嵌入式接口期末复习-(江苏海洋大学)---(第四部分 串行通信)

本文详细介绍了STM32的串口通信,包括通信接口、电平标准、串口参数及时序、USART简介以及波特率发生器的工作原理。通过代码示例展示了如何配置USART初始化、发送和接收数据,以及如何处理中断。同时,文中还涉及到数据帧的结构和校验位的概念,帮助理解串口通信的完整流程。
摘要由CSDN通过智能技术生成

 一: 通信接口

  1. 通信的目的: 将一个设备的数据传送到另一个设备,扩展硬件系统
  2. 通信协议: 制定通信规则,通信双方按照协议规则进行数据收发

     4. 硬件电路

 

  1. VCC 和 GND 是供电 , TX,RX 是通信的引脚  一个发送 一个接收(交叉连接)
  2. TX RX 是单端信号,它们的高低电平都是相对于GND的  ->  TX RX GND 必须要接
  3. 上面的VCC 如果两个设备都有独立供电,那可以不接
  4. 像这里直接从控制器出来的信号,一般都是TTL 电平,相同的电平才能互相通信,不同的电平信号,需要加一个电平转换芯片。
  5. 在硬件电路上,协议规定: 一个设备使用TX发送高低电平,另一个设备使用RX接收高低电平,在线路中,使用TTL电平,stm32是3.3V器件,所以如果线路对地是3.3V,就代表发送了逻辑 1,如果线路对地是0V,就代表发送了逻辑 0

  1. 常用的电平标准  电平标准是数据1和数据0的表达方式

|1| TTL电平: +3.3 或 +5 表示1   0V 表示0    

|2| RS232电平: -3 -> -15表示1 +3 -> +15 表示0

|3| RS485电平: 两线压差 +2 -> +6 表示1  -2 ->-6表示0  (差分信号)

 


 二:串口参数及时序

  1. 波特率 : 串口通信的速率   (异步通信 -> 需要双方约定一个通信速率)决定了每隔 多久发送一位
  2. 起始位 : 标志一个数据帧的开始,固定为 低电平  产生下降沿,告诉接收设备
  3. 数据位 : 数据帧的有效载荷,1为高电平 0为低电平 低位先行
  4. 校验位 : 用于数据验证,根据数据位计算得来
  5. 停止位 : 用于数据帧间隔,固定为高电平  把引脚恢复成高电平
  6. 时序图

  1. 串口中,每一个字节都装载在一个数据帧里面,每个数据帧都有起始位 数据位 停止位组成。这里数据位有8个,代表一个字节的8位
  2. 在右边的数据帧里面,还可以在数据位最后加一个奇偶校验位  -> 9 位

三: USART简介

  1. 可以根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可以自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
  2. 自带波特率发生器,最高达4.5Mbits/s
  3. 可配置数据位长度(8/9),停止位长度(0.5/1/1.5/2)
  4. 可选校验位
  5. 支持同步模式,硬件流,DMA等

 6.波特率发生器

[1]USART_BRR波特率寄存器

[2] 公式里面的16 因为 它内部还有一个16倍波特率的采样时钟

 以下代码供参考

uint8_t RxData;
uint8_t RxFlag;
void Init(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Perigh_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Perigh_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    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);

    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;//1位停止位
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8字长
    
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    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);

    USART_Cmd(USART1,ENABLE);

}

void USART1_IRQHandler(void){
    if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){
        RxData = USART_ReceiveData(USART1);
        RxFlag = 1;
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    }
}
void SendByte(uint8_t Byte){
    USART_SendDate(USART1,Byte);
    While(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );
}

 ps: 配置一致性

 封装

void SendArray(uint8_t *Array , uint18_t Length){
    uint16_t i ;
    for(i=0 ; i<Length ;i++){
        SendByte(Array[i]);
    }

}

void SendString (char *String){
    uint8_t i;
    for(i=0; String[i] !='\0';i++){
        SendByte(String[i]);
    }

}
uint32_t Pow(uint32_t X , uint32_t Y){
    uint32_t Result = 1;
    while(Y--){
        Result *=X;
    }
    return Result;
}
void SendNumber(uint32_t Number, uint32_t Length){
    uint8_t i;
    for(i=0;i<Length;i++){
        SendByte(Number / Pow(10,Length-i-1) % 10 +'0';
    }
}
#include<stdarg.h>
// 重点学习 C语言 可变参数
void Printf*(char *format,...){
    char String[100];
    va_list arg;
    va_start(arg,format);
    vsprintf(String,format,arg);
    va_end(arg);
    SendString(String);
}

uint8_t TxPacket[4];
uint8_t RxPacket[4];
uint8_t RxFlag;
void SendPacket(void){
    SendByte(0xFF);
    SendArray(TxPacket,4);
    SendAByte(0xEF);
}

// 在刚才的中断处理函数中实现以下代码
static uint8_t pRxPacket=0;
static uint8_t RxState = 0;
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){

    uint8_t RxData = USART_ReceiveData(USART1);
    if(RxState == 0 ){
        if(RxData ==0xFF){
            RxState = 1;
            pRxPacket=0;
        }
    }else if(RxState ==1 ){
        RxPacket[pRxPacket] = RxData;
        pRxPacket++;
        if(pRxPacket>=4){
            RxState =2;
        }
    }else if(RxState ==2 ){
        if(RxData ==0xFE){
            RxState = 0;
            RxFlag = 1;
        }    
    }
}


//用 RxFlag==1 来判断有没有结束哦

char RxPacket[100];

// 在刚才的中断处理函数中实现以下代码
static uint8_t pRxPacket=0;
static uint8_t RxState = 0;
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){

    uint8_t RxData = USART_ReceiveData(USART1);
    if(RxState == 0 ){
        if(RxData == '@'){
            RxState = 1;
            pRxPacket=0;
        }
    }else if(RxState ==1 ){
        if(RxData =='\r'){
            RxState=2; 
        }else{

            RxPacket[pRxPacket] = RxData;
            pRxPacket++;
        
        }


    }else if(RxState =='\n' ){
        if(RxData ==0xFE){
            RxState = 0;
            RxPacket[pRxPacket] = '\0';
            RxFlag = 1;
            
        }    
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值