STM32串口学习总结(经典)
主函数代码如下:
#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "arduino.h" //ALIENTEK Mini STM32¿ª·¢°å·¶Àý´úÂë3 //´®¿ÚʵÑé //¼¼ÊõÖ§³Ö£ºwww.openedv.com //¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾int main(void){ u8 t;u8 len; u16 times=0; u8 ax;//u8 bx='*'; //*µÄʵ¼ÊÖµÆäʵ´ú±í0x42Ò²¾ÍÊÇASCIIµÄÖµÊÇ42delay_init(); //ÑÓʱº¯Êý³õʼ»¯ NVIC_Configuration();// ÉèÖÃÖжÏÓÅÏȼ¶·Ö×éuart_init(9600); //´®¿Ú³õʼ»¯Îª9600LED_Init(); //³õʼ»¯ÓëLEDÁ¬½ÓµÄÓ²¼þ½Ó¿Ú USART3_Config(115200);while(1){delay_ms(100);LED0=1;LED1=1;//GPIO_ResetBits(GPIOA,GPIO_Pin_8);ax=arduino_Analysis();//printf("sudo=%d \r\n",sudu);//printf("ax=%d \r\n",ax);//printf("cx=%d \r\n",cx);//printf("%d \r\n",bx);//delay_ms(1000);//////////////////////////////////Ôº¯Êý // LED0=!LED0; // if(USART_RX_STA&0x8000) // { // len=USART_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶È // printf("\r\nÄú·¢Ë͵ÄÏûϢΪ:\r\n"); // for(t=0;t<len;t++) // { // USART1->DR=USART_RX_BUF[t]; // while((USART1->SR&0X40)==0);//µÈ´ý·¢ËͽáÊø // } // printf("\r\n\r\n");//²åÈë»»ÐÐ // USART_RX_STA=0; // }else // { // times++; // if(times%5000==0) // { // printf("\r\nALIENTEK MiniSTM32¿ª·¢°å ´®¿ÚʵÑé\r\n"); // printf("ÕýµãÔ×Ó@ALIENTEK\r\n\r\n\r\n"); // } // if(times%200==0)printf("ÇëÊäÈëÊý¾Ý,ÒԻسµ¼ü½áÊø\r\n"); // //ÉÁ˸LED,ÌáʾϵͳÕýÔÚÔËÐÐ. // delay_ms(10); // //} // } } }需要串口服务工程
建立与Arduino板子的通讯
.c程序如下:
总结以及函数的说明,今天系统的学习了单片机的串口通讯,简单的建立基于两个单片机的通讯使用单片机型号是stm32f103 rct6
1.在MDK中建立工程的过程中,在函数dianC中定义的相关函数,都在点h中进行相应的声明,但是除了void USART3_IRQHandler(void)以及void TIM4_Init(u16 arr,u16 psc)和void TIM4_IRQHandler(void) void TIM4_Init(u16 arr,u16 psc)。像串口中断服务函数这样的函数,在进行编程的时候它是在库函数中已经定义好的函数,只要串口发生中中断,就会进入串口中断函数,执行相应的操作。除此之外所有的自己定义的函数都要在.h中进行相应的声明。
2.要想在.h中进行引用自己编写工程中的全局变量,例如使用Arduino.c中的变量sudo,要在Aduino.h中像如下:extern u8 sudu;外部一下才能够使用
3.如果想在main.c中使用某个.c文件中相应的函数处理的某个数据,当遇到需要一个以上的数据的时候,使用return语句就显得不合时宜,return处理这样的数据也有点吃力,这时候可以考虑使用全局变量并在Arduino.h中进行extern一下就行了,使用的实例如下所示:
像sudu=Arduino_receive_temp[7];这时候在主函数想要引用只需要在Arduino.h中extern一下sudu就行了。全局变量可以直接相当于函数的返回在主函数中使用
4.串口中断函数void USART3_IRQHandler(void)只要串口3进入中断,就会跳到串口中断函数void USART3_IRQHandler(void)处理串口中断函数中的相应的命令。
5.关于串口调试助手相关的说明,在进行这个实验的时候,由于串口3使用的bound是115200,但是串口1使用的bound是9600。当你使用串口打印函数:printf的时候,其实库函数中是默认使用串口1进行打印的,因此配置串口的使用9600,而不是115200.因为虽然你使用的是串口3进行通讯,但是单片机与电脑的串口助手进行通讯使用的是串口1,因此无论在任何地方使用串口的打印函数都要使用串口1的配置环境。
6.ASCII问题说明:在进形多机通讯的时候,以Arduino板子为例。当Arduino板子发来数字1的时候,32的板子接收过来就是一个数字1,但是当Arduino的板子发来的是一串字符串的时候比如:‘,6,-,11,’,这个时候其实32的板子接收的是一串数字(补充:串口中所定义的8bit(11111111)0-255,字节(byte)这是计算机中数据类型最基本的单位了,8bit 组成1byte,因此串口在进行数据的传输的过程中是每次传输八个比特,一个字节也就是数据被拆分成一个一个字符的 进行数据传送因此,数据,6,-,11,被拆分为(42 44 54 44 45 44 49 49)ASCII的形式)
如下形式
与
if((Arduino_receive_counter==0)&&(Arduino_receive_temp[0]!=0x2a)) return;所实现的功能是一样的,进行通讯的时候,其它的单片机传过来的数据都是一个一个的数字(0-255)形式进行解析的,因此开头的“”*“”的ASCII码就是42=0x2a写成十六进制的还是十进制的都行,进行编译之后单片机所接受的二进制的数是一样的。
6.函数怎样处理的说明,尽量不要在中断服务函数中进行数据的处理,加上一个标志位再在中断函数的外部进行函数的处理如下:
void USART3_IRQHandler(void) //´®¿Ú3ÖжϷþÎñ³ÌÐò{if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏÓÐЧ,Èô½ÓÊÕÊý¾Ý¼Ä´æÆ÷Âú{Arduino_receive_temp[Arduino_receive_counter]=USART_ReceiveData(USART3);// Res=USART_ReceiveData(USART3);// printf("res=%d",Res);// USART_SendData(USART3,Res);// LED1=!LED1;if((Arduino_receive_counter==0)&&(Arduino_receive_temp[0]!=42)) return;/87=W Ê×Ö¡//if((Arduino_receive_counter==0)&&(Arduino_receive_temp[0]!=0x2a)) return; //˵Ã÷£¬0x2a=42LED0=0; // if( Arduino_Receive_Data[0]!=0x42) // { // Arduino_receive_counter++; // }elseArduino_receive_counter++;if(Arduino_receive_counter==9){Arduino_receive_counter=0;Arduino_receive_flag=1;}}}u8 arduino_Analysis() {if(Arduino_receive_flag==1){Arduino_receive_flag=0;memcpy(Arduino_Receive_Data,Arduino_receive_temp,8);//memcpy(Arduino_receive_temp,Arduino_Receive_Data,8);LED1=0;printf("sudu=%d \r\n",Arduino_Receive_Data[2]-48);jiaodu=(Arduino_Receive_Data[6]-48)*10+(Arduino_Receive_Data[7]-48);if(Arduino_Receive_Data[4]==45){printf("jiaodu=-%d \r\n",jiaodu);}else{printf("jiaodu=%d \r\n",jiaodu);}sudu=Arduino_receive_temp[7];} }就像上面的函数一样定义一个全局的变量u8 Arduino_receive_flag=0;,当进入到中断函数的时候就会是标志位置1,当标志位置1的时候函数u8 arduino_Analysis()中的if语句就开始执行`if(Arduino_receive_flag==1)
{
jiaodu=(Arduino_Receive_Data[6]-48)*10+(Arduino_Receive_Data[7]-48);
if(Arduino_Receive_Data[4]==45)
{
printf(“jiaodu=-%d \r\n”,jiaodu);
}else
{
printf(“jiaodu=%d \r\n”,jiaodu);
}
}`
到此处一个STM32的中断函数学习基本的就可以自己进一步做了
总结
以上是生活随笔为你收集整理的STM32串口学习总结(经典)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 作者:刘新海(1976-),男,博士,
- 下一篇: stm32中断优先级分组