问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32-串口通信发送+接收信息(标准库+代码)

创作时间:
作者:
@小白创作中心

STM32-串口通信发送+接收信息(标准库+代码)

引用
CSDN
1.
https://blog.csdn.net/m0_74785680/article/details/137650198

目录
一、串口简介
二、串口配置流程
三、代码实现
四、实现效果

一、串口简介

通用异步收发器 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 <stdio.h>
#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\n");
        if(USART_RX_STA & 0x8000) //接收完成
        {
            printf("Received data: %s\n", USART_RX_BUF);
            USART_RX_STA = 0; //清除接收状态标记
        }
    }
}
  

四、实现效果

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号