使用C6748的UART1作为收发串口,输入的ttl电平信号通过ttl转485电平转换电路转为485信号,再送到485通信设备,ttl转485电平转换电路如图:
主函数如下:
int main(void)
{
// 外设使能配置
PSCInit();
// GPIO 管脚复用配置
GPIOBankPinMuxSet();
// UART 初始化
UARTInit();
// 发送字符串
// 使能发送
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH);
unsigned char i;
for(i = 0; i < 34; i++)
UARTCharPut(SOC_UART_1_REGS, Send[i]);
// 禁用发送
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW);
// 主循环
for(;;)
{
Receive=UARTCharGet(SOC_UART_1_REGS);
// 使能发送
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH);
UARTCharPut(SOC_UART_1_REGS, Receive);
// 等待数据发送完成
for(i=0;i<200;i++);
// 禁用发送
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW);
}
}
先是对DSP的复用管脚进行配置,GPIOBankPinMuxSet();函数如下:
void GPIOBankPinMuxSet(void)
{
// 使能 UART1 禁用流控
UARTPinMuxSetup(1, FALSE);
// RS485 Enable 管脚
RS485PinMuxSetup();
}
UARTPinMuxSetup(1, FALSE);函数设置PINMUX4寄存器的PINMUX4_31_28字段为2h,PINMUX4_27_24字段为2h,使能UART1所在引脚的UART1_TX和UART1_RX功能。UARTPinMuxSetup函数如下:
void UARTPinMuxSetup(unsigned int instanceNum, unsigned int modemCtrlChoice)
{
unsigned int svPinMuxRtsCts = 0;
unsigned int svPinMuxTxdRxd = 0;
if(0 == instanceNum)
{
if(TRUE == modemCtrlChoice)
{
svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \
~(SYSCFG_PINMUX3_PINMUX3_27_24 | \
SYSCFG_PINMUX3_PINMUX3_31_28));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \
(PINMUX3_UART0_CTS_ENABLE | \
PINMUX3_UART0_RTS_ENABLE | \
svPinMuxRtsCts);
}
svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) & \
~(SYSCFG_PINMUX3_PINMUX3_23_20 | \
SYSCFG_PINMUX3_PINMUX3_19_16));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(3)) = \
(PINMUX3_UART0_TXD_ENABLE | \
PINMUX3_UART0_RXD_ENABLE | \
svPinMuxTxdRxd);
}
else if(1 == instanceNum)
{
if(TRUE == modemCtrlChoice)
{
svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \
~(SYSCFG_PINMUX0_PINMUX0_23_20 | \
SYSCFG_PINMUX0_PINMUX0_19_16));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \
(PINMUX0_UART1_CTS_ENABLE | \
PINMUX0_UART1_RTS_ENABLE | \
svPinMuxRtsCts);
}
svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \
~(SYSCFG_PINMUX4_PINMUX4_31_28 | \
SYSCFG_PINMUX4_PINMUX4_27_24));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \
(PINMUX4_UART1_TXD_ENABLE | \
PINMUX4_UART1_RXD_ENABLE | \
svPinMuxTxdRxd);
}
else if(2 == instanceNum)
{
if(TRUE == modemCtrlChoice)
{
svPinMuxRtsCts = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \
~(SYSCFG_PINMUX0_PINMUX0_31_28 | \
SYSCFG_PINMUX0_PINMUX0_27_24));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = \
(PINMUX0_UART2_CTS_ENABLE | \
PINMUX0_UART2_RTS_ENABLE | \
svPinMuxRtsCts);
}
svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \
~(SYSCFG_PINMUX4_PINMUX4_23_20 | \
SYSCFG_PINMUX4_PINMUX4_19_16));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \
(PINMUX4_UART2_TXD_ENABLE | \
PINMUX4_UART2_RXD_ENABLE | \
svPinMuxTxdRxd);
}
else
{
}
}
(指南P204)
(指南P225)
(指南P225)
RS485PinMuxSetup();函数使能RS485管脚,函数如下:
void RS485PinMuxSetup(void)
{
unsigned int savePinMux = 0;
savePinMux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & \
~(SYSCFG_PINMUX0_PINMUX0_19_16 | \
SYSCFG_PINMUX0_PINMUX0_19_16));
HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = (PINMUX0_RS485_ENABLE | savePinMux);
}
该函数设置PINMUX0寄存器的PINMUX0_19_16字段为8,将GP0[11]功能所在复用引脚的功能设为GP0[11],GP0[11]外接到ttl转485芯片(ISO3082DW)的使能引脚REn和DE,控制485芯片功能的使能和禁止。该485芯片电路的工作方式为半双工,发送时,要使能DE脚(Data Enable),GP0[11]为高;接收时,要使能REn脚(Receive enable),GP0[11]为低。
(指南P204)
(指南P218)
GPIO管脚复用配置好后,对UART初始化,初始化函数UARTInit();函数如下:
void UARTInit(void)
{
// 配置 UART1 参数
// 波特率 115200 数据位 8 停止位 1 无校验位
UARTConfigSetExpClk(SOC_UART_1_REGS, UART_1_FREQ, BAUD_115200, UART_WORDL_8BITS,
UART_OVER_SAMP_RATE_16);
// 使能 UART1
UARTEnable(SOC_UART_1_REGS);
// 设置使能管脚为输出状态 GPIO0[11]
GPIODirModeSet(SOC_GPIO_0_REGS, 12, GPIO_DIR_OUTPUT);
}
函数配置UART1的参数,并使能UART1,函数没有使能UART1的接收和发送FIFO,所以每次收发都是一个字节。然后,设置485芯片使能引脚GP0[11]为输出状态。GPIODirModeSet函数如下:
void GPIODirModeSet(unsigned int baseAdd, unsigned int pinNumber,
unsigned int pinDir)
{
unsigned int regNumber = 0;
unsigned int pinOffset = 0;
/*
** Each register contains settings for each pin of two banks. The 32 bits
** represent 16 pins each from the banks. Thus the register number must be
** calculated based on 32 pins boundary.
*/
regNumber = (pinNumber - 1)/32;
/*
** In every register the least significant bits starts with a GPIO number on
** a boundary of 32. Thus the pin offset must be calculated based on 32
** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in
** 'register_name01'.
*/
pinOffset = (pinNumber - 1) % 32;
if(GPIO_DIR_OUTPUT == pinDir)
{
HWREG(baseAdd + GPIO_DIR(regNumber)) &= ~(1 << pinOffset);
}
else
{
HWREG(baseAdd + GPIO_DIR(regNumber)) |= (1 << pinOffset);
}
}
(手册P254)
(指南P846)
(指南P849)
完成UART1的初始化之后,就完成了所有的初始化工作了。这时,要发送数据到上位机的话,需要先使能485芯片,所以主函数先设置GP0[11]的输出电平为高,
GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_HIGH);。函数如下:
void GPIOPinWrite(unsigned int baseAdd, unsigned int pinNumber,
unsigned int bitValue)
{
unsigned int regNumber = 0;
unsigned int pinOffset = 0;
/*
** Each register contains settings for each pin of two banks. The 32 bits
** represent 16 pins each from the banks. Thus the register number must be
** calculated based on 32 pins boundary.
*/
regNumber = (pinNumber - 1)/32;
/*
** In every register the least significant bits starts with a GPIO number on
** a boundary of 32. Thus the pin offset must be calculated based on 32
** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in
** 'register_name01'.
*/
pinOffset = (pinNumber - 1) % 32;
if(GPIO_PIN_LOW == bitValue)
{
HWREG(baseAdd + GPIO_CLR_DATA(regNumber)) = (1 << pinOffset);
}
else if(GPIO_PIN_HIGH == bitValue)
{
HWREG(baseAdd + GPIO_SET_DATA(regNumber)) = (1 << pinOffset);
}
}
设置GP0[11]脚的输出为高,需要设置SET_DATA01寄存器的11位为1.
(指南P846)
(指南P853)
使能了485芯片的数据发送功能后,就可以往UART1写数据了。UARTCharPut(SOC_UART_1_REGS, Send[i]);将定义好的数据写往UART1的THR(transmitter holding register,THR)。然后禁用485芯片的发送功能,将GP0[11]清0,GPIOPinWrite(SOC_GPIO_0_REGS, 12, GPIO_PIN_LOW);。这时,485芯片处于接收状态,UART1等待上位机发送数据过来,Receive=UARTCharGet(SOC_UART_1_REGS);。收到数据后,再次启用发送功能,将收到的数据原封不动地发回去。