最近灯光控制项目,通过485与墙板进行通信。此文记录调试这个485时掉过的坑
485端口初始化:
#define DEV_BUS_BAUD 1200
#define CTRL_LINKDIR GPIO_TO_PIN(PORTB, PIN4)
/** ****************************************************************************
* @brief 初始化串口
* @param[in] comm:串口号
* @param[in] baudrate:波特率
***************************************************************************** */
void UART_Init(BYTE uart_port, UINT baudrate, UINT rs485_flag, PCBRecv pFunc)
{
UART_CONFIG uart_config;
struct serial_rs485 config_of_485;
LINUX_UART *UARTx;
if (uart_port >= SYS_UART_DEV_NUM || pFunc == NULL)
{
PRINT_LOG("Uart initial para error.\n");
return;
}
g_pFunc[uart_port] = pFunc;
uart_config.Baud_rate = baudrate;
uart_config.Databits = UART_DATABIT_8;
uart_config.Parity = UART_PARITY_NONE;
uart_config.Stopbits = UART_STOPBIT_1;
uart_config.PCBRecv_Priority = 0;
UART_Config(uart_port, &uart_config);
if(rs485_flag == RS485_ON)
{
UARTx = GetUartHandle(uart_port);
config_of_485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
config_of_485.delay_rts_before_send = 0; //发送前延时0ms
config_of_485.delay_rts_after_send = 20; //发送后延时20ms
ioctl(UARTx->fd, TIOCSRS485, (unsigned long)&config_of_485);
}
}
void ExDev_Init(PCBExdevDataIn pfunc)
{
UINT BusBaudRate;
BusBaudRate = ExDev_Get_WallBorad_Baud(g_ConfigData.BusType);
if(BusBaudRate == 0)
{
BusBaudRate = DEV_BUS_BAUD;
}
PRINT_LOG("BusType =%d,BusBaudRate=%d\n",g_ConfigData.BusType,BusBaudRate);
UART_Init(DEV_BUS_PORT, BusBaudRate, RS485_ON, Exdev_Bus_RecvHandle);
Drv_GPIOSet(CTRL_LINKDIR, CTRL_DMXRX); //墙板使能接收
Sys_CreateTask(TASK_ID_VOD, Exdev_Bus_Thread, 0); //接收的数据处理线程
}
通过485发送数据:
UINT ExDev_WallBorad_SendCode(USHORT keyvalue)
{
BYTE BusCode[MAX_BUS_DATA_LEN];
BYTE BusCodeLen;
BYTE i;
memset(BusCode,0,sizeof(BusCode));
Drv_GPIOSet(CTRL_LINKDIR, CTRL_DMXTX);
BusCodeLen = Get_WallBorad_Code(BusCode,keyvalue);
if(BusCodeLen>0)
{
RS485_Bus_SendBuff(BusCode,BusCodeLen);
/********************/
PRINT_LOG("ExDev_WallBorad_SendCode:");
for(i=0;i<BusCodeLen;i++)
{
PRINT_LOG("%02x ",BusCode[i]);
}
PRINT_LOG("\n");
/********************/
}
else
{
PRINT_LOG("BusCode BusCodeLen =0 keyvalue = %d\n",keyvalue);
}
// DelayMs(20);
Drv_GPIOSet(CTRL_LINKDIR, CTRL_DMXRX); 墙板使能接收
return ERR_NULL;
}
遇到的坑:
1、调试过程中发现发送出去的数据总是不正确;摸索了很久,发现数据发送时,将要发送的数据传递给内核,然而内核还没有将数据发送完成,就立即将使能gpio置为接收状态,导致数据发送失败。发数据后延时20ms,在将gpio置为接收状态,发送数据就正常啦。
2、接收墙板发的数据是没问题,一切正常。但是接收串口助手发送的数据就不正常了,总是有丢数据:
调试把串口初始化时的485开关关闭就正常了
UART_Init(DEV_BUS_PORT, BusBaudRate, RS485_OFF, Exdev_Bus_RecvHandle);