485通信例程串口的一个小问题

2019-07-20 04:02发布

在485的初始化函数RS485_Init(u32 bound)里面,清除了串口发送完成的标志位

USART_ClearFlag(USART2, USART_FLAG_TC);

然后在485发送数据的函数RS485_Send_Data(u8 *buf,u8 len)里面

while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); 这句读取串口发送标志位不应该为0吗?
满足while为真,那么程序不会停在这句吗?

下面是这两个函数,求大佬解释一下
void RS485_Init(u32 bound)
{      
   
  GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
   
  //串口2引脚复用映射
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2复用为USART2
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3复用为USART2
   
    //USART2   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //GPIOA2与GPIOA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
    GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA2,PA3
   
    //PG8推挽输出,485模式控制  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOG8
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
    GPIO_Init(GPIOG,&GPIO_InitStructure); //初始化PG8
   

   //USART2 初始化设置
    USART_InitStructure.USART_BaudRate = bound;//波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    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(USART2, &USART_InitStructure); //初始化串口2
   
  USART_Cmd(USART2, ENABLE);  //使能串口 2
   
    USART_ClearFlag(USART2, USART_FLAG_TC);
   
#if EN_USART2_RX   
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启接受中断

    //Usart2 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器、

#endif   
   
    RS485_TX_EN=0;                //默认为接收模式   
}

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
    u8 t;
    RS485_TX_EN=1;            //设置为发送模式
      for(t=0;t<len;t++)        //循环发送数据
    {
      while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //等待发送结束        
    USART_SendData(USART2,buf[t]); //发送数据
    }     
    while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //等待发送结束        
    RS485_RX_CNT=0;      
    RS485_TX_EN=0;                //设置为接收模式   
}




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
yklstudent
1楼-- · 2019-07-20 08:19
你沒理解這個標志位,回去好好看看手冊
黑色
2楼-- · 2019-07-20 09:20
 精彩回答 2  元偷偷看……
szczyb1314
3楼-- · 2019-07-20 13:45
黑 {MOD} 发表于 2019-1-22 11:07
初始化的时候没有数据发送,TC标志位就为0,清除的函数是
void USART_ClearFlag(USART_TypeDef* USARTx, ...

你的理解是对的,严格的说,在你初始化清除了TC标志位后,在发送时确实需要先往数据寄存器DR写入数据,然后才应该再等待TC置位滴。

一周热门 更多>