串口查詢法
其實我在網上找了許多串口查詢法的例程,可是無一例外,都特別繁瑣,我對這個串口查詢法有趣的是其實現的過程,因為在實際工程應用中基本用不到查詢法,因此我在此拋磚引玉,假若有所遺漏,請各位不膩賜教!覺得不錯的,可以點個贊。
我主要都是在keil MDK5開發平台上基於stm32f103開發板進行開發。主要函數及其定義都在usart這個函數中
首先出現的這個是usart.c對應的.h文件,主要是對各個函數和定義進行申明
#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define USART_REC_LEN 200 //定義最大接收字節數 200 //主要函數,這些函數具體作用在usart.c中有說明 void uart_init(u32 bound); void USART1_SendOneByte(u8 SendData); void USART1_SendString(u8 * SendData); u8 USART1_ReceiveOneByte(void); u8 USART1_ReceiveString(void); #endif
接下來的就是usart.c文件
#include "stm32f10x.h" #include "usart.h" //加入以下代碼,支持printf函數,而不需要選擇use MicroLIB #if 1 #pragma import(__use_no_semihosting) //標准庫需要的支持函數 struct __FILE { int handle; }; FILE __stdout; //定義_sys_exit()以避免使用半主機模式 void _sys_exit(int x) { x = x; } //重定義fputc函數 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0); //循環發送,直到發送完畢 USART1->DR = (u8) ch; return ch; } #endif //用於接收電腦端虛擬串口發送過來的數據 //定義了一個接收數組USART_RX_BUF[USART_REC_LEN]; //#define USART_REC_LEN 200 //定義最大接收字節數 200 (在usart.h中) //定義了一個計算字符串長度的全局變量USART_RX_LEN u8 USART_RX_BUF[USART_REC_LEN]; u8 USART_RX_LEN=0; /* 函數名: uart_init 功能: 對串口1進行初始化 帶入參數: 波特率(9600) 返回: void */ void uart_init(u32 bound) { GPIO_InitTypeDef GPIO_InitStrue; USART_InitTypeDef USART_InitStrue; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); //使能串口1對應GPIO口和串口1的時鍾 GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9; //PA9 串口1TX 復用推挽輸出 GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10; GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING; //PA10 串口1RX 浮空輸入 GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); USART_InitStrue.USART_BaudRate=bound; //串口波特率 USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //串口是否由硬件控制 USART_InitStrue.USART_Parity=USART_Parity_No; //奇偶校驗位 USART_InitStrue.USART_StopBits=USART_StopBits_1; //停止位的位數 USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //串口的模式,這里即可接收又可發送 USART_InitStrue.USART_WordLength=USART_WordLength_8b; //串口的字長 USART_Init(USART1,&USART_InitStrue); //對所有的串口參數形成初始化 USART_Cmd(USART1,ENABLE); //串口使能 } /* 函數名: USART1_SendOneByte 功能: 對單個字節進行發送 帶入參數: u8 SendData 返回: void */ void USART1_SendOneByte(u8 SendData) { u32 cnt=0; USART_SendData(USART1,(u16)SendData); //調用stm32f10x_usart.c中的發送函數USART_SendData while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET) //等待發送完畢,這個等待函數也可在stm32f10x_usart.c找到 { cnt++; if(cnt>100000) break; //超過100ms,不管數據是否發送完畢,都不再等待 } } /* 函數名: USART1_SendString 功能: 對多個字節進行發送 帶入參數: u8 * SendData 返回: void */ void USART1_SendString(u8 * SendData) { while(*SendData!='\0') //當發送的字符串還沒結束(即遇到結束字符‘\0’)時 { USART1_SendOneByte(*SendData++); //一直一個字節一個字節的發送數據 } } /* 函數名: USART1_ReceiveOneByte 功能: 對單個字節進行接收 帶入參數: void 返回: u8 */ u8 USART1_ReceiveOneByte(void) { while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET){} //等待接收寄存器接收完畢,USART_FLAG_RXNE將置1,就會跳出這個while循環 return USART_ReceiveData(USART1); //返回接收寄存器中的接收數據 } /* 函數名: USART1_ReceiveString 功能: 對多個字節進行接收 帶入參數: void 返回: u8 */ u8 USART1_ReceiveString(void) { u8 i=0; u32 cnt=0; while(1) { USART_RX_BUF[USART_RX_LEN++]=USART1_ReceiveOneByte();//把接收的字節依次賦給數據緩沖區(USART_RX_BUF數組) for(i=0;i<USART_RX_LEN-1;i++) //對接收數據的數據進行判斷 { if(USART_RX_BUF[i]==0x0d) //0x0d回車,就是把光標定位到該行起始位置 { if(USART_RX_BUF[i+1]==0x0a) //0x0a換行符,就是把換行到下一行的起始位置 { USART_RX_LEN=0; //USART_RX_LEN必須置0,不然你下一次發送時,接收的數據將在USART_RX_BUF[USART_RX_LEN] return 1; //而接收的數據要從USART_RX_BUF[0]才行 //當接連遇到0x0d、0x0a表示字符串已經結束了 //這是因為電腦虛擬串口在發送數據時會自動給數據添加0x0d、0x0a結尾 }else { i=0; break; //假如不是接連遇到0x0d、0x0a,則重新尋找 } } } cnt++; if(cnt>100000) return 0; //超過100ms,不管數據是否接收完畢,都不再等待 } }
接下來將是main函數,main 函數就是開發板將從電腦虛擬串口助手發送過來的數據接收之后,開發板發送這些接收的數據給電腦的電腦虛擬串口助手。
#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "string.h" //這些數組以及數據長度變量已經在usart.c中定義,這里用extern直接申明在外部尋找即可 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節.末字節為換行符 extern u8 USART_RX_LEN; int main(void) { u16 t; u16 len; u16 times=0; delay_init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級 uart_init(9600); //串口初始化為115200 LED_Init(); while(1) { if(USART1_ReceiveString()==1) //開發板一接收到數據 USART1_SendString(USART_RX_BUF); //就執行發送數據給電腦的操作 // printf("%s\r\n",USART_RX_BUF); //對接收的數據打印出來,調試用 memset(USART_RX_BUF,0,100); //發送完數據之后,要對這個接收數據的數組進行清零,防止串口一直返回1,讓開發板一直發送數據 } }
串口中斷法
大家要是想了解一下STM32中串口的中斷法如何使用的話,可以直接搜索下邊這個地址,這是筆者借鑒正點原子的開發例程,其中搭配上筆者的一些見解,請大家感興趣的話,可以了解一下。
https://www.cnblogs.com/18689400042qaz/p/13378636.html
最后,覺得筆者寫的還可以的,可以給個推薦,謝謝大家!!!