先看usart.h
#ifndef __USART_H #define __USART_H /* 头文件 */ #include "stm32f10x.h" #include "stdio.h" #include "led.h" #include "beep.h" /* 串口接收信息封装 */ typedef struct{ u8 rx_buff[16]; //保存接收到的数据 u8 count; //记录接收到数据的个数 u8 flag; //状态:0 -- 正在接收 , 1 -- 接收完成 }USART_RX_Message; extern USART_RX_Message usart1_rx; /* 函数接口 */ void Usart1_Config(u32 brr); //初始化 void USART1_Test(void); //串口通信(上位机控制下位机) void USART1_Echo(void); //串口回显 #endif
再看usart.c
#include "usart.h" USART_RX_Message usart1_rx; //USART1接收封装 /* 私有函数 */ void USART1_DataTest(u8 *pdata); /*********************************************************************************** 函数功能:USART1初始化 (USB转串口——USART1) 形参:brr -- 波特率 返回值:无 ***********************************************************************************/ /* 管脚: USART1_Tx PA9 复用推挽输出 USART1_Rx PA10 浮空输入 */
定义了变量 和函数
下面usart使能
void Usart1_Config(u32 brr) { /* 配置GPIO */ //1. 时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //2. 配置模式 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 配置USART模式 */ //1. 时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //2. 模式配置 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = brr; //波特率 (数据传输速度) USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //非硬件流 (如何决定收发的时机) USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 (全双工) USART_InitStructure.USART_WordLength = USART_WordLength_8b; //RS232协议(数据格式):数据位 8个 USART_InitStructure.USART_Parity = USART_Parity_No; //RS232协议(数据格式):奇偶校验位 0个 USART_InitStructure.USART_StopBits = USART_StopBits_1; //RS232协议(数据格式):停止位 1个 USART_Init(USART1, &USART_InitStructure); //3. 配置接收中断(串口回显时注释掉) USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //接收中断打开 NVIC_InitTypeDef NVIC_InitStruct = {0}; NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruct); //4. 初始状态 -- 使能 USART_Cmd(USART1, ENABLE); }
中断服务函数
/* * USART1中断服务函数 * 通信格式:0xFF(开始码)+ 数据+ 0x66(结束码) -- 最大16byte */ void USART1_IRQHandler(void) { u8 temp = 0; if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET) //接收中断触发 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志位 temp = USART1->DR; if(temp != 0xFF && usart1_rx.count == 0) return; //开始码错误或没有数据 -> 返回 else { usart1_rx.rx_buff[usart1_rx.count++] = temp; if(temp == 0x66) usart1_rx.flag = 1; //收到结束码 -> 接收完成标志位置1 } }
函数接口函数 定义flag buff[0]数据头
/*********************************************************************************** 函数功能: USART1 函数接口 ***********************************************************************************/ void USART1_Test(void) { if(usart1_rx.flag != 1) return; //没有接收完毕->返回 if(usart1_rx.rx_buff[0] != 0xFF) goto CLEAR_OVER; //接收到的数据帧头不是FF -> 数据错误 USART1_DataTest(&usart1_rx.rx_buff[1]); //串口通信数据解析 CLEAR_OVER: usart1_rx.count = 0; usart1_rx.flag = 0; }
/* *串口通信数据解析 */ void USART1_DataTest(u8* pdata) { switch(pdata[0]) { case 0: if(pdata[1] == 1) // 00 + 01 { BEEP(ON);LED1(ON); } else if(pdata[1] == 0) // 00 + 00 { BEEP(OFF);LED1(OFF); } break; case 1: if(pdata[1] == 1) LED1(ON); // 01 + 01 else if(pdata[1] == 0) LED1(OFF); // 01 + 00 break; case 2: if(pdata[1] == 1) BEEP(ON); // 02 + 01 else if(pdata[1] == 0) BEEP(OFF); // 02 + 00 break; } }
串口回显
/* * 串口回显 */ void USART1_Echo(void) { u8 data = 0; while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == RESET); data = USART1->DR; while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); USART1->DR = data; }
串口显示
/* * 串口打印 */ int fputc(int c, FILE * stream) { while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); // 发送完毕 -- SET USART1->DR = c; //把要打印的内容存到USART1的数据寄存器中 return c; }
main函数中添加
#include "main.h" void JTAG_SWD_Config(void); /*********************************************************************************** 函数功能:main函数 形参:无 返回值:无 ***********************************************************************************/ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); JTAG_SWD_Config(); LED_Config(ON); BEEP_Config(); KEY_Config(); EXTI0_Config(); Motor_Config(); RGB_Config(); Relay_Config(); //今日内容:串口通信 Usart1_Config(9600); while(1) { //上位机控制下位机 USART1_Test(); USART1_Echo(); Dht11_ReadData(); } } /*********************************************************************************** 函数功能:下载接口管脚重映射 形参:无 返回值:无 ***********************************************************************************/ void JTAG_SWD_Config(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO时钟使能 // GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); //完全禁用SWD及JTAG GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用JTAG }
主要是
//今日内容:串口通信
Usart1_Config(9600);
//上位机控制下位机
USART1_Test();
USART1_Echo();
源文件:
https://wwa.lanzoui.com/ivndmvh1uih