【STM32 标准库】USART串口

 1.1 通信

    (1)分类:

        按照数据传输的方式:串行通信、并行通信;

        串行通信:

        并行通信:    

        按照通信的数据同步方式:异步通信、同步通信;

        异步通信:1.字符帧(8位数据位+1位校验位+1位起始位+1位停止位);2.校验方法:奇校验、偶校验、0校验、1校验、无校验;3.发、收设备的时钟要尽可能保持一致,但允许一定误差。

        同步通信:发送方时钟对接收方时钟进行直接控制。

        按照数据的传输方向:单工通信、半双工通信、全双工通信

        单工通信:数据传输只沿一个方向,不能实现反向传输。

        半双工通信:数据传输可以沿2个方向,但是需要分时进行(RS485)。

        全双工通信:数据传输可以同时双向进行(RS232)。

        (2)通信速率

           通信速率,常指比特率(Bitrate)是衡量通信性能的重要参数。比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。

        (3)RS232通信:

        接口:公头、母头

        接线:RXD、TXD、GND

        电平转换芯片:TTL电平(单片机)--> RS232电平

        通信协议:96-N-8-1(96:波特率9600,可以大于;N:不校验;8:数据传输位数;1:停止位)

1.2 STM32F1 USART

        (1)USART

        USART即通用同步异步收发器,它能够灵活地与外部设备进行全双工数据交 换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求。UART即通用异步收发器,它是在 USART 基础上裁剪掉了同步通信功能,同步和异步主要看其时钟 是否需要对外提供。

        (2)结构框图

p1:功能引脚。

p2:数据寄存器功能。

p3:控制器单元。

p4:波特率生成模块。

2.USART串口通信配置

    2.1通用定时器PWM输出配置步骤

    (1)添加库文件:stm32f10x_usart.c/stm32f10x_usart.h;

(2)使能串口时钟及 GPIO 端口时钟                 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    (3)GPIO 端口模式设置,设置串口对应的引脚为复用功能    

     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;     

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出引脚TXD               

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;     

GPIO_Init(GPIOA,&GPIO_InitStructure);     

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;     

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入引脚RXD              

GPIO_Init(GPIOA,&GPIO_InitStructure);

    (4)初始化串口参数,包含波特率、字长、奇偶校验等参数    

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);     

typedef struct 

   {     

        uint32_t USART_BaudRate; //波特率     

        uint16_t USART_WordLength; //字长     

        uint16_t USART_StopBits; //停止位     

        uint16_t USART_Parity; //校验位     

        uint16_t USART_Mode; //USART 模式     

        uint16_t USART_HardwareFlowControl; //硬件流控制 

    } USART_InitTypeDef;

    (5)使能串口    

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

    (6)设置串口中断类型并使能

 void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalStat e NewState); 

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断              

USART_ITConfig(USART1,USART_IT_TC, ENABLE);

    (7)设置串口中断优先级,使能串口中断通道

    (8)编写串口中断服务函数

   USART1_IRQHandler uint16_t 

USART_ReceiveData(USART_TypeDef* USARTx); 

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

    2.2 配置流程

    2.2.1 添加STM32驱动文件

2.2.2 初始化USART函数

2.2.3 USART中断服务函数

    2.3.4 主函数

3.硬件设计

3.1 USB转串口:程序下载,通过CH340C模块

   3.2 RS232

 3.3 RS485

4.软件设计

    4.1 功能描述

    本章所要实现的功能是:STM32F1 通过 USART1 实现与 PC 机对话,STM32F1 的 USART1 收到 PC 机发来的数据后原封不动的返回给 PC 机显示。同时使用 DS0指示灯不断闪烁提示系统正常运行。

    4.2 软件实现

    (1)初始化 USART1,并使能串口接收中断等

#include "USART.h"
u8 USATR1_RX_BUF[USART1_RECIEVE_DATA_LEN];  //定义接收数据数组
u16  USART1_RX_STA=0;           //识别接收数据长度,是否接收到0x0D、0x0;15:接收完成标志,14:接收到0x0D,0-13:接收到的有效数据
// ------------------------------1.USART初始化-----------------------------------
/* ---------------------------------函数声明-------------------------------------
*函数名称:USART1_Iint(u32 baud_rate)
*输入参数:u32 baud_rate:波特率
*返回参数:无
*功    能:初始化usart1
*作    者:lph
*日    期:2024/03/28
------------------------------------------------------------------------------ */
void USART1_Iint(u32 baud_rate)
{
    //1.使能串口时钟及 GPIO 端口时钟                  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    //2.GPIO 端口模式设置,设置串口对应的引脚为复用功能
    GPIO_InitTypeDef GPIO_InitStructure;
    //2.1 TXD端口初始化
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;     
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出引脚TXD
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;     
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //2.2 RXD端口初始化
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;     
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入引脚RXD
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //3.初始化串口参数,包含波特率、字长、奇偶校验等参数
    USART_InitTypeDef USART_InitStructure;
    
    USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
    USART_InitStructure.USART_BaudRate=baud_rate;
    USART_InitStructure.USART_WordLength=USART_WordLength_8b;
    USART_InitStructure.USART_Parity=USART_Parity_No;
    USART_InitStructure.USART_StopBits=USART_StopBits_1;
    USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    
    USART_Init(USART1, &USART_InitStructure);
    
    //4.使能串口
    USART_Cmd(USART1, ENABLE);
    
    //5.设置串口中断类型并使能
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    
    
    //6.设置串口中断优先级,使能串口中断通道
    NVIC_InitTypeDef NVIC_InitStructure;
    
    NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
}

(2)编写 USART1 中断服务函数

// -----------------------------2.USART中断服务函数------------------------------
/* ---------------------------------函数声明-------------------------------------
*函数名称:USART1_IRQHandler(void)
*输入参数:无
*返回参数:无
*功    能:usart1中断服务函数
*作    者:lph
*日    期:2024/03/28
------------------------------------------------------------------------------ */
void USART1_IRQHandler(void)
{
    u8 ReceiveDate=0;
    if(USART_GetITStatus(USART1, USART_IT_RXNE)==SET)  //判断是否为要发送的串口
    {
        ReceiveDate = USART_ReceiveData(USART1);
        if((USART1_RX_STA&0x8000)==0)  //是否接收完成
        {
            if(USART1_RX_STA&0x4000)  //接收到0x0d
            {
                if(ReceiveDate!=0x0a)
                {
                    USART1_RX_STA=0;
                }
                else
                {
                    USART1_RX_STA |= 0x8000;  //接收完成
                }
            }
            else  //未接收到0x0D
            {
                if(ReceiveDate == 0x0d)  //接收到0x0d
                {
                    USART1_RX_STA |= 0x4000;
                }
                else
                {
                    USATR1_RX_BUF[USART1_RX_STA&0x3fff]=ReceiveDate;
                    USART1_RX_STA++;
                    if(USART1_RX_STA>(USART1_RECIEVE_DATA_LEN-1))  //当接收到数据长度大于设定的数据长度时,认为接收错误
                    {
                        USART1_RX_STA=0;
                    }
                }
            }
        }
        USART_SendData(USART1, ReceiveDate);
        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != SET); //判断数据是否发送完成
    }
}

    (3)编写主函数

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "system.h"
#include "LED.h"
#include "SysTick.h"
#include "USART.h"
/* 主函数main() --------------------------------------------------------------*/
int main()
{   
    // 自定义变量
    u8 i=0;
    u16 len=0;
    u16 t=0;
    // 初始化
    SysTick_Iint(72);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
    LED_Init();
    USART1_Iint(115200);
    
    while(1)
    {
        i++;
        if(i%20==0)
        {
            if((USART1_RX_STA&0x8000)==1)
            {
                len = USART1_RX_STA&0x3ffff;
                for(t=0;t<len;t++)
                {
                    USART_SendData(USART1, USATR1_RX_BUF[t]);
                    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
                }
                USART1_RX_STA=0;
            }
            
            LED1 = !LED1;
            delay_ms(100);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值