赞
踩
串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。本文主要接收使用串口发送接收数据,波特率设置,串口的基本时序等。
在受到噪声影响后,采用2:1策略,选择更多的作为所接收到的数据,并使噪声标志位NE置1
使用USART1来作为例子,根据引脚定义,选择正确的接口
配置串口Serial.c
#include "stm32f10x.h" // Device header #include <stdio.h> #include <stdarg.h> void Serial_Init(void){ // 开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 初始化引脚,发送数据引脚 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // A9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Hz翻转速度 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化串口配置 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; // 串口波特率 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用流控 USART_InitStructure.USART_Mode = USART_Mode_Tx; // 串口模式,发送 USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 选择一位停止位 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 不需要校验位,八位字长 USART_Init(USART1,&USART_InitStructure); // USART1使能 USART_Cmd(USART1,ENABLE); } // 发送函数 void USART_SendByte(uint8_t Byte){ USART_SendData(USART1,Byte); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } // 发送数组函数 void USART_SendArray(uint8_t *Array,uint16_t Length){ uint8_t i = 0; for(i=0;i<Length;i++){ USART_SendData(USART1,Array[i]); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } // 发送字符串函数 void USART_SendString(uint8_t *String){ uint8_t i = 0; for(i=0;String[i]!='\0';i++){ USART_SendData(USART1,String[i]); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } // 返回X的Y次方 uint32_t Serial_Pow(uint32_t X,uint32_t Y){ uint32_t Result = 1; while(Y--){ Result *= X; } return Result; } // 发送数字函数 void USART_SendNum(uint32_t Num,uint16_t Length){ uint8_t i = 0; for(i=0;i<Length;i++){ USART_SendByte(Num / Serial_Pow(10,Length-i-1) % 10 + 0x30); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } //重定向fputc函数,fputc是printf函数的底层,printf通过不停的调用fputc来达到输出的效果 //重定向到串口 int fputc(int ch,FILE *f){ USART_SendByte(ch); return ch; } // 封装使用sprintf输出到串口 void Serial_Printf(char *format, ...) { char String[100]; va_list arg; // 可变参数列表 va_start(arg, format); // 从format开始接收可变参数 vsprintf(String, format, arg); va_end(arg); USART_SendString((uint8_t*)String); }
主函数main.c
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "Serial.h" int main(void) { OLED_Init(); Serial_Init(); //USART_SendByte(); // uint8_t Array[] = {0x41,0x42,0x43,0x44}; // USART_SendArray(Array,4); // uint8_t String[] = {"hello world"}; // USART_SendString(String); // USART_SendNum((uint32_t)12345,5); // printf("Num = %d\r\n",666); // char String[100]; // sprintf(String,"Num = %d\r\n",666); // USART_SendString((uint8_t*)String); Serial_Printf("一程山水"); while (1) { } }
串口配置Serial.c
#include "stm32f10x.h" // Device header #include <stdio.h> #include <stdarg.h> uint8_t RxData; uint8_t RxFlag; void Serial_Init(void){ // 开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 初始化引脚 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // A9 发送数据 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Hz翻转速度 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // A10 接收数据 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Hz翻转速度 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化串口配置 USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; // 串口波特率 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用流控 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 串口模式,发送+接收 USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 选择一位停止位 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 不需要校验位,八位字长 USART_Init(USART1,&USART_InitStructure); // 开启中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //初始化NVIC NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 分组 NVIC_InitTypeDef NVIC_InitStructure; // 中断通道 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 中断通道使能 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 抢占优先级 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 响应优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); // USART1使能 USART_Cmd(USART1,ENABLE); } // 发送函数 void USART_SendByte(uint8_t Byte){ USART_SendData(USART1,Byte); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } // 发送数组函数 void USART_SendArray(uint8_t *Array,uint16_t Length){ uint8_t i = 0; for(i=0;i<Length;i++){ USART_SendData(USART1,Array[i]); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } // 发送字符串函数 void USART_SendString(uint8_t *String){ uint8_t i = 0; for(i=0;String[i]!='\0';i++){ USART_SendData(USART1,String[i]); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } // 返回X的Y次方 uint32_t Serial_Pow(uint32_t X,uint32_t Y){ uint32_t Result = 1; while(Y--){ Result *= X; } return Result; } // 发送数字函数 void USART_SendNum(uint32_t Num,uint16_t Length){ uint8_t i = 0; for(i=0;i<Length;i++){ USART_SendByte(Num / Serial_Pow(10,Length-i-1) % 10 + 0x30); // 等待写入完成,写入完成之后会将标志位自动清0 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } } //重定向fputc函数,fputc是printf函数的底层,printf通过不停的调用fputc来达到输出的效果 //重定向到串口 int fputc(int ch,FILE *f){ USART_SendByte(ch); return ch; } // 封装使用sprintf输出到串口 void Serial_Printf(char *format, ...) { char String[100]; va_list arg; // 可变参数列表 va_start(arg, format); // 从format开始接收可变参数 vsprintf(String, format, arg); va_end(arg); USART_SendString((uint8_t*)String); } // 获取RxFlag uint8_t USART_GetRxFlag(void){ if(RxFlag == 1){ RxFlag = 0; return 1; } return 0; } // 获取RxData uint8_t USART_GetRxData(void){ return RxData; } //中断函数 void USART1_IRQHandler(void){ if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){ RxData = USART_ReceiveData(USART1); RxFlag = 1; USART_ClearITPendingBit(USART1,USART_IT_RXNE); } }
主函数main.c
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "Serial.h" uint8_t Serial_RxData; int main(void) { OLED_Init(); OLED_ShowString(1, 1, "RxData:"); Serial_Init(); while (1) { if (USART_GetRxFlag() == 1) { Serial_RxData = USART_GetRxData(); USART_SendByte(Serial_RxData); OLED_ShowHexNum(1, 8, Serial_RxData, 2); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。