STM32的USART注意

在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器,另一个是程序看不到的移位寄存器,对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送结束

XE--写寄存器DR清零

RXNE--读寄存器DR清零,也可软件手动清零

 TC--  读/写寄存器DR清零,也可软件手动清零

先说TC。即Transmission Complete。发送一个字节后才进入中断,这里称为“发送后中断”。

    再说判断TXE。即Tx DR Empty,发送寄存器空。当使能TXEIE后,只要Tx DR空了,就会产生中断,所以,发送完字符串后必须关掉,否则会导致重复进入中断。

    我的失败经历是在串口初始化是 USART_ITConfig(USART1, USART_IT_TXE, ENABLE);结果在串口中断中没有关闭txe,所以你上电后什么也不做,系统就会一直进中断,也就是发送为空,但是也进中断。所以串口初始化函数中就不用打开TXE的中断了。

1,用串口连续发送一串数字时, 第一个数总是发不出去

这个问题的根本原因是复位后,TC和TXE标志位默认都是1,很多人喜欢这样写: 
    USART_SendData(USART1, (u8) ch);  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  
    while在发送第一个字节时没有起到应有作用,直接跳出,接着写第二个字节,这时第一个字节还未发出,数据被破坏了.

看看datasheet,果然复位以后, SR=0x00c0;TC=TXE=1;

有人是在串口中断处理函数void USARTx_IRQHandler(void)最后加上下面的来解决第一个字节发布出去的问题。

if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)                   /
 { 
   USART_ITConfig(USART2, USART_IT_TXE, DISABLE);    
 }

其中TC判断的是一帧数据,而TXE是当TDR数据传到移位寄存器就被置位了,所以TC的时间比较长,很容易被下一次数据覆盖~~~所以一般喜欢判断TXE,数据写到DR就可以了 ,剩下的工作就交给硬件了,一般的用TXE就可以了, TC一般用于需要延时的场合,比如说是232/485转换器,需要得到TC后,才能将发送改变成接收,否则 最后一个字节发送不完全。

2.其实可以不用TC,也不用初始化使能USART_ITConfig(USART1, USART_IT_TXE, ENABLE);发送函数这样写:

发送函数可以这样写

 void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,uint16_t Len)

  uint16_t i;
  for(i=0; i<Len; i++)
  {
    USART_SendData(USARTx, Data[i]);
    //while(tx_flag==0)
    //{}
    //tx_flag=0;
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE)==RESET);                   //判断是否发送完成。 USART_FLAG_TC
  }

中断处理函数这样写:

void USARTx_IRQHandler(void)
{
  if(USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)  
  {
    uartx_recv(); //接受处理函数
  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值