RS485通信应注意的几点细节

来源:互联网 发布:如何修改tomcat的端口 编辑:程序博客网 时间:2024/05/16 04:24

RS485通信应注意的几点细节

1.      关于控制位问题

#define TX_485GPIO_SetBits(GPIOF,GPIO_Pin_11)

#define RX_485GPIO_ResetBits(GPIOF,GPIO_Pin_11)

是给控制位高电平为发送模式还是给低电平为发送模式,看电路原理图的时候一定要看清楚。改变控制位时应该有一定的时间延迟。

2.      关于连续发送或接受一个字节或多个字节时问题

关于发送一个字节很简单:

void USART3_SendByte(unsigned char senddata)

{

TX_485;

Delay();

       USART_SendData(USART3,(uint8_t)senddata);

       while(USART_GetFlagStatus(USART3,USART_FLAG_TC)== RESET);

RX_485;

Delay();

}

开始我这么想的,连续发送多个字节和发送一个字节不都是一样的?就是多调用几次这个函数不就行那,可是,我调试了一个下午,连续调用这个函数发送一组命令过去,就是没收到接受设备的发聩,用485转232将命令发送到pc的串口助手上,没错误。后来我想到既然都是发送字节,干脆将TX_485和RX_485放到函数外面来,变成如下结构

TX_485;

Delay();

USART3_SendByte();

---

---

USART3_SendByte();

RX_485;

Delay();

 

然后将发送函数改成

void USART3_SendByte(unsigned charsenddata)

{

       USART_SendData(USART3,(uint8_t)senddata);

       while(USART_GetFlagStatus(USART3,USART_FLAG_TC)== RESET);

}

这样就收到了接受命令设备发回来的设备,通过这个现象是不是当发送大于一个字节的的数据时候,应该是不能多次改变485的控制位的,这样得到的将不会是一个整体的命令序列。接受数据也是一样的,当接受的数据大于一个字节的时候,只需要将485控制位设置为接受一次就行了。不然会出现没发送一组命令数据,却只会收到一个字节,因为在改变控制位的时候后面的数据还没来得及接受就丢弃了。调试了一天终于将485通信调试通了,唉,主要是第一次接触485,里面出现很多问题都不知道为什么,在网络上也很少说到这些应该注意的细节。因此将它记录下来。

附串口初始化函数:

void bsp_InitUart(void)

{

       GPIO_InitTypeDefGPIO_InitStructure;

       USART_InitTypeDefUSART_InitStructure;

       NVIC_InitTypeDefNVIC_InitStructure;

//     USART_ClockInitTypeDefUSART_ClockInitStructure;

       /*第1步:打开GPIO和USART部件的时钟 */

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOF| RCC_APB2Periph_AFIO, ENABLE);

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);

 

       /*第2步:将USART Tx的GPIO配置为推挽复用模式 */

       GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;

       GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

       GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

       GPIO_Init(GPIOB,&GPIO_InitStructure);

 

       /*第3步:将USART Rx的GPIO配置为浮空输入模式

              由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的

              但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数

       */

       GPIO_InitStructure.GPIO_Pin= GPIO_Pin_11;

       GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;

       GPIO_Init(GPIOB,&GPIO_InitStructure);

       /*  第3步已经做了,因此这步可以不做

              GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

       */

       //GPIO_Init(GPIOB,&GPIO_InitStructure);

       ////////////////////////////////////////////////////////

       GPIO_InitStructure.GPIO_Pin= GPIO_Pin_11;

       GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;

       GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

       GPIO_Init(GPIOF,&GPIO_InitStructure);

       /*第4步:配置USART参数

           - 波特率   = 9600 baud

           - 数据长度 = 8 Bits

           - 1个停止位

           - 无校验

           - 禁止硬件流控(即禁止RTS和CTS)

           - 使能接收和发送

       */

       USART_InitStructure.USART_BaudRate= 9600;

       USART_InitStructure.USART_WordLength= USART_WordLength_8b;

       USART_InitStructure.USART_StopBits= USART_StopBits_1;

       USART_InitStructure.USART_Parity= USART_Parity_No;

       USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None;

       USART_InitStructure.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;

       //////////////////////////////////////////////////////

       USART_Init(USART3,&USART_InitStructure);

       /*第5步:使能 USART, 配置完毕 */

       /*

              CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去

              如下语句解决第1个字节无法正确发送出去的问题:

             清发送完成标志,Transmission Complete flag*/

       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

       NVIC_InitStructure.NVIC_IRQChannel= USART3_IRQn;

       //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 1;

       NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;

       NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;

       NVIC_Init(&NVIC_InitStructure);

       //////////////////////////////////////////////////////

       USART_Cmd(USART3,ENABLE);

       USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);

       USART_ClearFlag(USART3,USART_FLAG_TC);     

}

原创粉丝点击