微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32串口中断的一些资料

STM32串口中断的一些资料

时间:11-19 来源:互联网 点击:
在研究STM32串口接收发送中断的时候找到不少不错的资料,现在备份在这里。以供自己查阅,以及方便其他人。

TC====TXE

顺便预告下最近会写个有关串口处理数据的帖子,从查询和中断方面以及数据处理的方式,从队列以及FIFO方面写起。

SECTION1

SECTION2

先说TC。即TransmissionComplete。发送一个字节后才进入中断,这里称为“发送后中断”。和原来8051的TI方式一样,都是发送后才进中断,需要在发送函数中先发送一个字节触发中断。发送函数如下

/*
功能:中断方式发送字符串.采用判断TC的方式.即判断发送后中断位.
输入:字符串的首地址
输出:无
*/
voidUSART_SendDataString(u8*pData)
{
pDataByte=pData;

USART_ClearFlag(USART1,USART_FLAG_TC);//清除传输完成标志位,否则可能会丢失第1个字节的数据.网友提供.

USART_SendData(USART1,*(pDataByte++));//必须要++,不然会把第一个字符t发送两次
}

中断处理函数如下
/
*FunctionName:USART1_IRQHandler
*Description:ThisfunctionhandlesUSART1globalinterruptrequest.
*Input:None
*Output:None
*Return:None
*/
voidUSART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_TC)==SET)
{
if(*pDataByte==\0)//TC需要读SR+写DR方可清0,当发送到最后,到\0的时候用个if判断关掉
USART_ClearFlag(USART1,USART_FLAG_TC);//不然TC一直是set,TCIE也是打开的,导致会不停进入中断.clear掉即可,不用关掉TCIE
else
USART_SendData(USART1,*pDataByte++);
}

}

其中u8*pDataByte;是一个外部指针变量

在中断处理程序中,发送完该字符串后,不用关闭TC的中断使能TCIE,只需要清掉标志位TC;这样就能避免TC==SET导致反复进入中断了。

串口初始化函数如下

/*
名称:USART_Config
功能:设置串口参数
输入:无
输出:无
返回:无
/
voidUSART_Config()
{
USART_InitTypeDefUSART_InitStructure;//定义一个包含串口参数的结构体

USART_InitStructure.USART_BaudRate=9600;//波特率9600
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//8位数据位
USART_InitStructure.USART_StopBits=USART_StopBits_1;//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_InitStructure.USART_Clock=USART_Clock_Disable;//时钟关闭
USART_InitStructure.USART_CPOL=USART_CPOL_Low;
USART_InitStructure.USART_CPHA=USART_CPHA_2Edge;
USART_InitStructure.USART_LastBit=USART_LastBit_Disable;
USART_Init(USART1,&USART_InitStructure);//设置到USART1

USART_ITConfig(USART1,USART_IT_TC,ENABLE);//TramsimssionComplete后,才产生中断.开TC中断必须放在这里,否则还是会丢失第一字节

USART_Cmd(USART1,ENABLE);//使能USART1
}
这里请问一个问题:开TC中断USART_ITConfig()如果放在我的USART_SendDataString()中再开,会丢失字符串的第一字节。必须放在串口初始化函数中才不会丢。不知道为什么??

这里笔者可以给出解释,你看下SECTION1就可以知道为什么呢,你这样做的原理和SECTION1讲解的差不多,就相当于延时,而你后面没有丢失数据的主要原因就是你代码中有这么一句USART_ClearFlag(USART1,USART_FLAG_TC);//清除传输完成标志位,否则可能会丢失第1个字节的数据.网友提供.

再说判断TXE。即TxDREmpty,发送寄存器空。当使能TXEIE后,只要TxDR空了,就会产生中断。所以,发送完字符串后必须关掉,否则会导致重复进入中断。这也是和TC不同之处。

发送函数如下:
/*
功能:中断方式发送字符串.采用判断TC的方式.即判断发送后中断位.
输入:字符串的首地址
输出:无
*/
voidUSART_SendDataString(u8*pData)
{
pDataByte=pData;
USART_ITConfig(USART1,USART_IT_TXE,ENABLE);//只要发送寄存器为空,就会一直有中断,因此,要是不发送数据时,把发送中断关闭,只在开始发送时,才打开。

}

中断处理函数如下:

/
*FunctionName:USART1_IRQHandler
*Description:ThisfunctionhandlesUSART1globalinterruptrequest.
*Input:None
*Output:None
*Return:None
/
voidUSART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_TXE)==SET)
{
if(*pDataByte==\0)//待发送的字节发到末尾NULL了
USART_ITConfig(USART1,USART_IT_TXE,DISABLE);//因为是发送寄存器空的中断,所以发完字符串后必须关掉,否则只要空了,就会进中断
else
USART_SendData(USART1,*pDataByte++);
}

}

在串口初始化函数中就不用打开TXE的中断了(是在发送函数中打开的)如下:
/
名称:USART_Config
功能:设置串口参数
输入:无
输出:无
返回:无
/
voidUSART_Config()
{
USART_InitTypeDefUSART_InitStructure;//定义一个包含串口参数的结构体

USART_InitStructure.USART_BaudRate=9600;//波特率9600
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//8位数据位
USART_InitStructure.USART_StopBits=USART_StopBits_1;//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_InitStructure.USART_Clock=USART_Clock_Disable;//时钟关闭
USART_InitStructure.USART_CPOL=USART_CPOL_Low;
USART_InitStructure.USART_CPHA=USART_CPHA_2Edge;
USART_InitStructure.USART_LastBit=USART_LastBit_Disable;

USART_Init(USART1,&USART_InitStructure);//设置到USART1

USART_Cmd(USART1,ENABLE);//使能USART1

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top