STM32串口发送中断
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
STM32串口发送中 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)