打印
[STM32F0]

stm32f030串口使用的一点心得

[复制链接]
12094|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
changmiao|  楼主 | 2015-10-21 08:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
       这几天在做一个案子,使用到了F0 USART收发功能。有些小伙伴们说F0不能像F1那样长期开放TC中断,否则将会卡死在中断里,应该在需要的时候开启,用完再关闭。事实真的这样吗?其实不然,那下面我来说说我是如何实现一次性初始化设置的。先来一段初始化代码:
void initUart(void)
{
        USART_InitTypeDef  USART_InitStructure;
        GPIO_InitTypeDef    GPIO_InitStructure;
        NVIC_InitTypeDef    NVIC_InitStructure;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

        /* USART2 Pins configuration ******/  
        /* Connect pin to Periph */
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);  

        /* Configure pins as AF pushpull */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        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(USART1,&USART_InitStructure);       


       USART_ClearFlag(USART1,USART_FLAG_TC);
        USART_ITConfig(USART1,USART_IT_TC,ENABLE);
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        USART_Cmd(USART1,ENABLE);      //使能串口


        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);     //使能串口中断
}

       在初始化代码中,使能串口和使能串口中断这两个的顺序不要搞反了,否则如果你已允许了TC中断,程序将会一直进入中断,既然在中断中调用USART_ClearFlag(USART1,USART_FLAG_TC)也无济于事。经过分析发现,数据手册中提到Set the TE bit in USARTx_CR1 to send an idle frame as first transmission。也就是说一旦使能了TE,芯片会自动地发出了一次数据,并会引起TC_FLAG置位,而想要清除该flag的先决条件是使能了串口。因此,假如在使能串口钱已经使能了串口中断,那程序就一直进入中断了。这也是小伙伴们疑惑的地方,误以为TC是无法清除的。
       完成了初始化,那么只要把需要发送的数据填写到发送缓冲区,并且调用一次USART_SendData()把第一个字节发送出去之后,剩下的就交给中断处理啦!So easy!
void USART1_IRQHandler(void)         
{

    if (USART_GetFlagStatus(USART1, USART_FLAG_TC) == SET)    {
        USART_ClearFlag(USART1,USART_FLAG_TC);   //清除TC_FLAG
        if(gbyteUartTxIndex < gbyteUartTxLenght)
        {
            USART_SendData(USART1,gbyteSendBuf[gbyteUartTxIndex++]);
        }
    }
}


沙发
mmuuss586| | 2015-10-21 09:10 | 只看该作者

谢谢分享;

使用特权

评论回复
板凳
迪卡| | 2015-10-21 10:18 | 只看该作者
也就是说一旦使能了TE,芯片会自动地发出了一次数据,并会引起TC_FLAG置位,而想要清除该flag的先决条件是使能了串口。因此,假如在使能串口钱已经使能了串口中断,那程序就一直进入中断了。这也是小伙伴们疑惑的地方,误以为TC是无法清除的。

受教了,学习了

使用特权

评论回复
地板
捉虫天师| | 2015-10-25 00:50 | 只看该作者
原来这么多学问,受益匪浅

使用特权

评论回复
5
可可球| | 2015-10-26 22:15 | 只看该作者
想要清除flag的先决条件是使能了串口

使用特权

评论回复
6
309030106| | 2015-10-26 22:24 | 只看该作者
谢谢分享

使用特权

评论回复
7
冰河w| | 2015-10-26 22:43 | 只看该作者
USART_ClearFlag(USART1,USART_FLAG_TC);   //清除TC_FLAG

使用特权

评论回复
8
FireRiver9| | 2015-10-26 22:50 | 只看该作者
在初始化代码中,使能串口和使能串口中断这两个的顺序不要搞反了

使用特权

评论回复
9
lefeng| | 2015-10-29 10:32 | 只看该作者
串口被占用了怎么办,能重映射吗

使用特权

评论回复
10
lwsn| | 2015-10-29 10:55 | 只看该作者
楼主这个串口中断响应后会不会自己关闭

使用特权

评论回复
11
changmiao|  楼主 | 2015-10-29 13:42 | 只看该作者
lwsn 发表于 2015-10-29 10:55
楼主这个串口中断响应后会不会自己关闭

不会,每次进中断清掉标志位就可以了

使用特权

评论回复
12
huangcunxiake| | 2015-10-29 16:42 | 只看该作者
想要清除flag的先决条件是使能了串口?这不对吧

使用特权

评论回复
13
changmiao|  楼主 | 2015-10-30 08:06 | 只看该作者
huangcunxiake 发表于 2015-10-29 16:42
想要清除flag的先决条件是使能了串口?这不对吧

我仿真验证过,如果不使能串口,会一直不断进入中断,清除flag也不管用,然后调出寄存器,手工勾上UE就一切正常了。然后代码初始化的时候顺序做了调整,也没问题了。

使用特权

评论回复
14
huangcunxiake| | 2015-11-12 22:18 | 只看该作者
勾上UE就一切正常了,这个UE是指的什么内容,哪个选项?

使用特权

评论回复
15
changmiao|  楼主 | 2015-11-16 14:09 | 只看该作者
本帖最后由 changmiao 于 2015-11-16 14:11 编辑
huangcunxiake 发表于 2015-11-12 22:18
勾上UE就一切正常了,这个UE是指的什么内容,哪个选项?

UE是USARTx_CR1寄存器中的最低位——UE: USART enable,USART_Cmd(USART1,ENABLE)的效果就是把它置位, 请仔细看手册,谢谢~~

使用特权

评论回复
16
huangcunxiake| | 2015-11-16 20:31 | 只看该作者
非常感谢楼主的悉心教诲,终于知道了UE是USARTx_CR1寄存器中的最低位——UE: USART enable,USART_Cmd(USART1,ENABLE)的效果就是把它置位

使用特权

评论回复
17
android2| | 2015-11-16 21:07 | 只看该作者
请教一下,在看资料时,发现有的说中断产生时会使中断标志位置1,但又说清除中断标志位是向寄存器里写1,怎么回事啊

使用特权

评论回复
18
changmiao|  楼主 | 2015-11-17 14:05 | 只看该作者
android2 发表于 2015-11-16 21:07
请教一下,在看资料时,发现有的说中断产生时会使中断标志位置1,但又说清除中断标志位是向寄存器里写1,怎 ...

置一是由硬件完成,而写1清除中断标志位是由用户软件清除,不清除的后果就是硬件检测到标志位置一不断地进入中断。至于是写1还是写0甚至只要读某个特定寄存器(例如有些芯片串口接收中断发生时读一次接收寄存器即可清除)达到清除的目的,要看数据手册,不同的厂商可能不一样。

使用特权

评论回复
19
android2| | 2015-11-24 20:12 | 只看该作者
置一是由硬件完成,而写1清除中断标志位是由用户软件清除,不清除的后果就是硬件检测到标志位置一不断地进入中断。

那如果硬件置1,进入中断,清中断是不是要再写入1

使用特权

评论回复
20
玛尼玛尼哄| | 2015-11-24 22:46 | 只看该作者
  在初始化代码中,使能串口和使能串口中断这两个的顺序不要搞反了,否则如果你已允许了TC中断,程序将会一直进入中断,既然在中断中调用USART_ClearFlag(USART1,USART_FLAG_TC)也无济于事。。很赞同楼主的话。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

170

帖子

1

粉丝