0
点赞
收藏
分享

微信扫一扫

关于STM32串口实验的一些学习总结和思考

1、usart.c

在做串口实验时,我们在写void USART1_IRQHandler(void)函数时,会遇到一些问题,这里做一下总结,首先,先附上代码

oid USART1_IRQHandler(void)                 //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif


//回车:回到当前行行首,不会回到下一行,如果接着输入则会覆盖本行以前的内容。0x0d \r
//换行:换到当前位置的下一行,而不会回到首行。 0x0a \n
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
//USART_RX_STA&0x8000若为1表示bit15为1,USART_RX_STA的二进制首数字为1,则表明接收到了0x0a,可以结束,
//同理0x4000表示接收到了0x0d,可以结束
//正常的结束应该先接受到0x0a,再接收到0x0d,表示先换到下一行的当前位置,再回到这一行的行首
if((USART_RX_STA&0x8000)==0)//接收未完成,
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)
USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA=USART_RX_STA|0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)
USART_RX_STA=USART_RX_STA|0x4000;//结果
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//USART_RX_STA&0x3fff接收到的数据长度,一直在接收
USART_RX_STA++;//这边可以循环?
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}

在这段代码中,有几点值得注意:

1、在学习历程的过程中,如果遇到如0x8000、0x4000这些16进制表示的数时,我们尽量可以将其改成二进制,改成二进制之后再去查阅资料,会比较容易理解,因为寄存器存储的都是二进制。例如,在实验中我们需要去理解USART_RX_STA,如果转换成二进制,再结合下面的代码注释,就会容易理解很多。

#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
//u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
//u16 USART_RX_STA=0; //接收状态标记

2、注意在串口通讯中回车和换行的区别。

//回车:回到当前行行首,不会回到下一行,如果接着输入则会覆盖本行以前的内容。0x0d  \r

 //换行:换到当前位置的下一行,而不会回到首行。  0x0a  \n

3、整个函数的理解逻辑,函数要在接收到回车或者换行之后停止,USART_RX_STA&0x8000若为1表示bit15为1,USART_RX_STA的二进制首数字为1,则表明接收到了0x0a,可以结束,同理0x4000表示接收到了0x0d,可以结束。正常的结束应该先接受到0x0a,再接收到0x0d,表示先换到下一行的当前位置,再回到这一行的行首。我们分析代码,得到下图

关于STM32串口实验的一些学习总结和思考_串口

这个图是我对这个函数中很多的if循环语句的一个理解,也许会有理解不准确的地方,希望大家可以帮我指出来。


2、主函数main.c

int main(void)
{
int t=0;
int len=0;
int times=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为2
uart_init(9600);
LED_Init();
LED0=0;
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("您发送的消息为:");
for(t=0;t<len;t++)
{
USART1->DR=USART_RX_BUF[t];//USART1->DR 串口1的数据寄存器,这里是通过串口循环发送USART_RX_BUF数据
while((USART1->SR&0X40)==0);//等待发送结束
}
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}else //times%5000==0 times%200==0 这个会一直显示 times%30==0这个会一直显示
{
times++;

printf("快点输入\r\n");
// if(times%30==0)
// LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}

主函数相对简单,我在实验例程稍作更改,其中,例程中

 //times%5000==0      times%200==0 这个会一直显示     times%30==0这个会一直显示

这个表达时间间隔的方式很新颖,我第一次见




以上是对串口实验的一些总结,希望大家批评指正!



加油!!

举报

相关推荐

0 条评论