STM32-串口通信发送+接收信息(标准库+代码)
目录
一、串口简介
二、串口配置流程
三、代码实现
四、实现效果
一、串口简介
通用异步收发器 UART(Universal Asynchronous Receiver/Transmitter),是一种串行、异步、全双工的通信协议。通过发送线(TX)、接收线(RX)、GND就可以进行全双工通信。需要确定好通信双方的波特率(bps指每秒传输的码元数量)
串口通信是一位一位地传输,每传输一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有一位起始位(低电平),后面由7位数据位组成,接着是1位校验位,最后是1位停止位。停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。
一般的数据格式:(1bit)起始位+(7bit) 数据位 + (None)校验位 + (1bit)停止位
起始位:通信线路上空闲时为“1”,当检测到“0”即下降沿时,认为数据传输开始
有效数据位:传输开始后传递的需要接收和发送的数据值,可以表示指令或数据
奇偶校验位:奇偶校验,通过来校验传输数据中“1”的个数为奇数个(奇校验)或偶数个(偶校验)来指示传输数据是否正确
停止位:数据传输结束,传输线恢复常“1”状态
此外,还需关注数据传输波特率,波特率表示一秒内传输了多少个码元数量,一般波特率为300,1200,2400,9600,19200,38400,115200等。例如9600 Baud表示一秒内传输了9600个码元信息,当一个码元只含1 bit信息时,波特率=比特率
二、串口配置流程
一般我们使用串口,都需要有以下几个步骤:
1.开启GPIO时钟和串口时钟
2.配置GPIO模式并初始化
3.配置串口参数
4.使能串口
三、代码实现
Usart.c (这里的重定义函数需要勾选Use MicroLIB)
#include "stm32f10x.h" // Device header
#include "Usart.h"
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
//重定义fputc函数
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成
return ch;
}
void Usart1_Init(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//USART1_TX PA9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//USART1_RX PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//USART1 NVIC 配置
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_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | 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); //初始化串口 1
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开启串口接收中断
USART_Cmd(USART1,ENABLE); //使能串口 1
}
void USART1_IRQHandler( void ) /* 串口1中断服务程序 */
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
Usart.h
#ifndef __USART_H_
#define __USART_H_
#include "stm32f10x.h" // Device header
#include
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
void Usart1_Init(uint32_t bound);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Usart.h"
//硬件部分
#include "LED.h"
#include "KEY.h"
int main(void)
{
Usart1_Init(9600); //串口1 初始化
LED_Init();
while(1)
{
LED_ON;
Delay_ms(500);
LED_OFF;
Delay_ms(500);
printf("hello word\r
");
if(USART_RX_STA & 0x8000) //接收完成
{
printf("Received data: %s
", USART_RX_BUF);
USART_RX_STA = 0; //清除接收状态标记
}
}
}