曲曲折折的找了很多方法,这种最简单有效了
,利用STM8L151的串口空闲中断标志,实现串口不定长数据接收。
主函数:
int main( void )
{
CLK_PeripheralClockConfig (CLK_Peripheral_USART1,ENABLE);//开启USART时钟
USART_Init(USART1,9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_Mode_Tx|USART_Mode_Rx);//设置USART参数9600,8N1, 接收/发送
USART_ITConfig (USART1,USART_IT_IDLE,ENABLE);//使能空闲中断
USART_ITConfig (USART1,USART_IT_RXNE,ENABLE);//使能接收中断
USART_Cmd (USART1,ENABLE);//使能USART
enableInterrupts();
while(1)
{
if(rce_idle_flag==1)
{
for(int i=0;i<rcep;i++)
{
USART_SendData8 (USART1,rcebufer[i]);
while(!USART_GetFlagStatus (USART1,USART_FLAG_TXE)); //等待发送完成
}
rce_idle_flag=0;
memset(rcebufer,0,rcep);
rcep=0;
}
}
}
清除数据:
void memset(u8 * p,u8 val,u32 length)
{
u8 i;
for(i=0;i<length;i++)
{
p[i]=val;
}
}
中断:
INTERRUPT_HANDLER(USART1_RX_TIM5_CC_IRQHandler,28)
{
u8 clear=clear;
if(USART_GetITStatus (USART1,USART_IT_RXNE)==SET)//j接收到一字节数据
{
USART_ClearITPendingBit (USART1,USART_IT_RXNE);//清中断标志
urtdate=USART_ReceiveData8 (USART1);
rcebufer[rcep]=urtdate;
rcep++;
}
if(SET==USART_GetITStatus (USART1,USART_IT_IDLE))//接收到一帧数据
{
clear=USART1->SR;//读SR寄存器
clear=USART1->DR;//读DR寄存器
rce_idle_flag=1;
return;
}
}
注意点:
1、rcebufer[]这个数据缓存数组长度要定的合适,否则容易产生溢出错误。
2、先读SR寄存器再读DR寄存器就是为了清除IDLE中断,USART_ClearITPendingBit()这个清串口中断标志的函数中是没有USART_IT_IDLE的