串口查询法
其实我在网上找了许多串口查询法的例程,可是无一例外,都特别繁琐,我对这个串口查询法有趣的是其实现的过程,因为在实际工程应用中基本用不到查询法,因此我在此抛砖引玉,假若有所遗漏,请各位不腻赐教!觉得不错的,可以点个赞。
我主要都是在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
最后,觉得笔者写的还可以的,可以给个推荐,谢谢大家!!!