STM32串口学习总结(经典)
主函數代碼如下:
#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "arduino.h" //ALIENTEK Mini STM32?a·¢°?·?ày′ú??3 //′??úêμ?é //??ê??§3?£owww.openedv.com //1??YêDD?òíμ?×ó????óD?T1???int main(void){ u8 t;u8 len; u16 times=0; u8 ax;//u8 bx='*'; //*μ?êμ?ê?μ??êμ′ú±í0x42ò2?íê?ASCIIμ??μê?42delay_init(); //?óê±oˉêy3?ê??ˉ NVIC_Configuration();// éè???D??ó??è??·?×éuart_init(9600); //′??ú3?ê??ˉ?a9600LED_Init(); //3?ê??ˉó?LEDá??óμ?ó2?t?ó?ú 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);//////////////////////////////////?-oˉêy // LED0=!LED0; // if(USART_RX_STA&0x8000) // { // len=USART_RX_STA&0x3fff;//μ?μ?′?′??óê?μ?μ?êy?Y3¤?è // printf("\r\n?ú·¢?íμ????¢?a:\r\n"); // for(t=0;t<len;t++) // { // USART1->DR=USART_RX_BUF[t]; // while((USART1->SR&0X40)==0);//μè′y·¢?í?áê? // } // printf("\r\n\r\n");//2?è???DD // USART_RX_STA=0; // }else // { // times++; // if(times%5000==0) // { // printf("\r\nALIENTEK MiniSTM32?a·¢°? ′??úêμ?é\r\n"); // printf("?yμ??-×ó@ALIENTEK\r\n\r\n\r\n"); // } // if(times%200==0)printf("??ê?è?êy?Y,ò???3μ?ü?áê?\r\n"); // //éá??LED,ìáê??μí3?y?ú??DD. // 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?D??·t??3ìDò{if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //?óê??D??óDD§,è??óê?êy?Y??′??÷?ú{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中断优先级分组