对于STM32串口的发送和接收,以及数据类型的任意转换和识别字符命令,进行相应的赋值。
1 关于STM32串口发送和接收,以及任意转换数据类型和识别字符命令进行响应赋值。对于STM32来说,串口的外设非常重要。 如果你彻底了解了这个外设,无疑对我们的STM32有很大的帮助。 由于可以修改代码功能来实现任何功能,因此将代码分为主要模块。 一、功能模块两部分 1.实现代码的主模块
首先,关于初始化,其余代码是一样的,只是多了一个
USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE);
我们可以查一下这个中断对应的手册,知道这个中断对应的是接收一帧数据的中断。 通俗地说,当我们互相交谈时,我们要一个字一个字地说、听,但大脑真正处理一个完整的句子时,帧中断的含义可以理解为,我们已经发送完一个完整的“ word”,然后让CPU产生中断来处理我们完整的句子
2.中断串口处理函数
char rece_buffer[128];
int RxCounter;
void USART1_IRQHandler(void )
{
u8 clear=clear;//这个变量用于清除IDLE中断,下面会做解释
USART_ClearFlag(USART1,USART_FLAG_TC);
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET)
{
rece_buffer[RxCounter++]=USART1->DR;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
//通过接受中断,将发送的数据一个一个得存放在数组里
}
else if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=Bit_RESET)
{//当我们发完了一帧数据后,该中断就会产生
clear=USART1->SR;
clear=USART1->DR;//这两行代码在作用上完全类似于 USART_ClearITPendingBit(USART1, USART_IT_RXNE);
//查看手册,对应寄存器可以知道,当我们依次读SR,DR寄存器之后,这个标志位就会自动清除。
RxCounter=0;//这个为接收数据数组的计数数据,这里清零后,方便下一次接收数据
//如果没有这个清零,下次接收就会出问题,
//比如第一次我们接收了5个数据,分别对 rece_buffer的0 1 2 3 4 放了数据,当我们第二次接收数据,因为RxCounter
//并未清零,会继续给RxCounter的 5 6 7 .........赋值,如此会对我们的数据处理造成很大影响
}
}
这段代码是我们函数代码的主体
3.数据类型转换
我们都知道串口发送时,如果不选择十六进制发送,发送的是字符类型,如何将字符转换成数据类型供我们使用呢?
在此之前,我相信函数的重定向对于每个人来说都不是问题。
#include //因为我们用到了sscanf以及print函数,所以要加入该头文件
char rece_buffer[128];
int RxCounter;
void USART1_IRQHandler(void )
{
u8 clear=clear;
double num;
USART_ClearFlag(USART1,USART_FLAG_TC);
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET)
{
rece_buffer[RxCounter++]=USART1->DR;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
else if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=Bit_RESET)
{
clear=USART1->SR;
clear=USART1->DR;
RxCounter=0;
printf ("%s\r\n",rece_buffer);//此代码只是为了验证与转换后的结果相同
sscanf (rece_buffer,"%lf",&num );//这两行代码可以把字符串变成浮点,整型等等!
//该函数的公式为sscanf( 数组,"渴望转换成为类型",转换数据赋值处 ),通俗地说就是把我们数组里的数据,转换成%lf,然后赋值到num;
//如果想赋值为int ,把%lf 改成 %n即可
printf ("%f\r\n",num);
}
}
识别命令字符及其字符串
我们在学习stm32的时候,常常会想,是不是可以从串口发送一个命令,比如“open led”,我们就打开led,输入“m”,我们就关闭
,是的,当然可以实现,仍然是同一个模块,只是稍有改变
char rece_buffer[128];
int RxCounter;
void USART1_IRQHandler(void )
{
u8 clear=clear;
USART_ClearFlag(USART1,USART_FLAG_TC);
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET)
{
rece_buffer[RxCounter++]=USART1->DR;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
else if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=Bit_RESET)
{
clear=USART1->SR;
clear=USART1->DR;
if(rece_buffer[0]=='p')//这个k就是命令字符
{//字母区分大小写的
RxCounter=0;//这个清零很重要,切记!!!
}
if(rece_buffer[0]=='k'&& rece_buffer[1]=='d'&&rece_buffer[2] =='a'&&rece_buffer[3]=='w' )
//这个kdaw就是命令字符串。*****************************,如果想改变命令字符串,依葫芦画瓢,照着增加或者减少即可,
//如果要增加特殊符号,如空格等等,请查阅对于的字符表示形式
{//字母区分大小写的
RxCounter=0;
}
}
}
识别字符串命令及其分配
例如,如果我们要输入k7854\r\n,我们会将7854赋给k变量,如果我们输入其他,例如m7854\r\n,我们会将7854赋给m
char rece_buffer[128];
char rece_buffer1[128];//两个数组,,用于数据的移位
int RxCounter;
void USART1_IRQHandler(void )
{
u8 clear=clear;
float num;
USART_ClearFlag(USART1,USART_FLAG_TC);
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET)
{
rece_buffer[RxCounter++]=USART1->DR;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
else if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=Bit_RESET)
{ u8 i;
clear=USART1->SR;
clear=USART1->DR;
if(rece_buffer[0]=='k')
{ RxCounter=0;
for(i=0;i<=(sizeof(rece_buffer)/sizeof(rece_buffer[0]));i++)
{
rece_buffer1[i]=rece_buffer[i+1];
//比如我们输入 k 854 ,rece_buffer里面的数据为 k 8 5 4,然后把后面的三个数据赋给cece_buffer1为 8 5 4
}
printf ("%s\r\n",rece_buffer1);
sscanf (rece_buffer1,"%f",&num );//将字符转变为浮点
printf ("%f\r\n",num);
printf ("rece_buffer[0]=%c\r\n",rece_buffer[0]) ;
printf ("rece_buffer[1]=%c\r\n",rece_buffer[1]) ;
//printf只是为了验证,无实际意义
}
else {printf ("你输入了错误命令");
RxCounter=0;
printf ("rece_buffer[0]=%c\r\n",rece_buffer[0]) ;
printf ("rece_buffer[1]=%c\r\n",rece_buffer[1]) ;}
}
}
**
这样就实现了串口常用的几个功能。