您的位置 首页 元件

STM32的串口中止

整个工程下载:http://www.rayfile.com/files/66369fee-d80c-11df-ac1d-0015c55db73d/关键代码:UART.h:/********串口收发环形

总的来说,STM32单片机的串口仍是很好了解的,编程也不算杂乱。当然我更乐意期望其中止体系51单片机相同的简略。

关于接纳终端,便是RXNE了,这只在接纳完结后才发生,在履行USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)代码时不会进入ISR。但费事的便是发送有关的中止了:TXE或许TC,依据材料和测验的成果,TXE在复位后便是置1的,即在履行USART_ITConfig(USART1, USART_IT_TXE, ENABLE)后会当即发生中止请求。因而这形成一个费事的问题:假如没有真实的发送数据,TXE中止都会发生,而且没有休止,这将占用很大部分的CPU时刻,乃至影响其他程序的运转!

因而主张的是在初始化时欠好启用TXE中止,只在要发送数据(尤其是字符串、数组这样的系列数据)时才启用TXE。在发送完结后当即将其封闭,避免引起不必要的费事。

关于发送,需求留意TXE和TC的不同——这儿简略描绘一下,假定串口数据寄存器是DR、串口移位寄存器是SR以及TXD引脚TXDpin,其联系是DR->SR->TXDpin。当DR中的数据转移到SR中时TXE置1,假如有数据写入DR时就能将TXE置0;假如SR中的数据悉数经过TXDpin移出而且没有数据进入DR,则TC置1。而且需求留意TXE只能经过写DR来置0,不能直接将其清零,而TC能够直接将其写1清零。

关于发送单个字符能够考虑不必中止,直接以查询方法完结。

关于发送字符串/数组类的数据,唯一要考虑的是只在终究一个字符发送后封闭发送中止,这儿能够分为两种状况:关于发送可显现的字符串,其用0x00作为完毕的,因而在ISR中就用0x00作为封闭发送中止(TXE或许TC)的条件;第二种状况便是发送二进制数据,那便是0x00~0xFF中心的恣意数据,就不能用0x00来判别完毕了,这时有必要知道数据的详细长度。

这儿简略剖析上面代码的履行进程:TXE中止发生于前一个字符从DR送入SR,履行作用是后一个字符送入DR。关于第一种状况,假如是可显现字符,就履行USART_SendData来写DR(也就清零了TXE),当终究一个可显现的字符从DR送入SR之后,发生的TXE中止发现要送入DR的是字符是0x00——这当然不可——此刻就封闭TXE中止,字符串发送进程就算完毕了。当然这时不能疏忽一个隐含的成果:那便是终究一个可显现字符从DR转入SR后TXE是置1的,但封闭了TXE中止,因而只需下次再敞开TXE中止就会当即进入ISR。关于第二种状况,其成果和第一种的相同。

关于第一种状况,其程序能够这么写:其间TXS是保存了要发送数据的字符串,TxCounter1是索引值:

extern __IO uint8_t TxCounter1;
extern uint8_t *TXS;
extern __IO uint8_t TxLen;

void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
if(TXS[TxCounter1]) //假如是可显现字符
{ USART_SendData(USART1,TXS[TxCounter1++]);}
else //发送完结后封闭TXE中止,
{ USART_ITConfig(USART1,USART_IT_TXE,DISABLE);}
}
}

关于第二种状况,和上面的迥然不同,其间TXLen表明要发送的二进制数据长度:

void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) //对USART_DR的写操作,将该位清零。
{
if(TxCounter1 { USART_SendData(USART1,TXS[TxCounter1++]);}
else //发送完结后封闭TXE中止
{ USART_ITConfig(USART1,USART_IT_TXE,DISABLE);}
}
}

事实上第一种状况是第二种的特别方法,便是说能够用第二种状况去发送可显现的字符——当然没人有闲心去数一句话里有多少个字母空格和标点符号!

在使用时,只需将TXS指向要发送的字符串或许数组,设置TxLen为要发送的数据长度,然后履行USART_ITConfig(USART1, USART_IT_TXE,ENABLE)就当即开端发送进程。用户能够查看TxCounter1来确认发送了多少字节。比如以第二种状况为例:

uint32_t *TXS;
uint8_t TxBuffer1[]=”0123456789ABCDEF”;
uint8_t DST2[]=”ASDFGHJKL”;
__IO uint8_t TxLen = 0x00;

TxLen=8; //发送8个字符,终究发送的是01234567
TXS=(uint32_t *)TxBuffer1; //将TXS指向字符串TxBuffer1
TxCounter1=0; //复位索引值
USART_ITConfig(USART1, USART_IT_TXE,ENABLE); //启用TXE中止,即开端发送进程
while(TxCounter1!=TxLen); //等候发送完结
TXS=(uint32_t *)TxBuffer2; //同上,终究发送的是ASDFGHJK
TxCounter1=0;
USART_ITConfig(USART1, USART_IT_TXE,ENABLE);
while(TxCounter1!=TxLen);

以上便是我以为的最佳计划,但串口中止方法数据有多长就中止多少次,我以为仍是占用不少CPU时刻,相比之下DMA方法就好多了,由于DMA发送字符串时最多中止两次(半传输完结,全传输完结),而且将串口变成相似16C550的器材。关于DMA方法的这儿就不介绍了,有空再说。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/254885.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部