STM32:串口发送/接收HEX数据包代码篇(内含:实物图接线图+代码部分+个人笔记)

简介: STM32:串口发送/接收HEX数据包代码篇(内含:实物图接线图+代码部分+个人笔记)

接线图:


05c6ec7bd4364ee1b2e9e9ec2029b0d2.png


实物图:


c023994093a6415c9f172b5bace954af.png


RXD接PA9,TXD接PA10,PB1接按键,PA1口接LED,长脚接正,短脚接GND。

代码部分:

main.c代码部分:


f306ec90ee5945bcb7f323e59d54ff31.png

3488e1162b504efcafaadbf0718e0eb3.png


098920dd48bf47a581f0f6d2aab15a63.png

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "Key.h"
uint8_t KeyNum;
int main(void)
{
    OLED_Init();
    Serial_Init();
    OLED_ShowString(1,1,"RxData");
    OLED_ShowString(3,1,"TxData");
    //赋初值
    Serial_TxPacket[0]=0x01;
    Serial_TxPacket[1]=0x02;
    Serial_TxPacket[2]=0x03;
    Serial_TxPacket[3]=0x04;
    while (1)
    {
        KeyNum = Key_GetNum();
        if(KeyNum==1)
        {
            Serial_SendPacket();//发送数据包
            Serial_TxPacket[0]++;
            Serial_TxPacket[1]++;
            Serial_TxPacket[2]++;
          Serial_TxPacket[3]++;
            OLED_ShowHexNum(2,1,Serial_TxPacket[0],2);
            OLED_ShowHexNum(2,4,Serial_TxPacket[1],2);
            OLED_ShowHexNum(2,7,Serial_TxPacket[2],2);
            OLED_ShowHexNum(2,10,Serial_TxPacket[3],2);
        }
        if(Serial_GetRxFlag() == 1)//标志位结束判断
        {
            OLED_ShowHexNum(4,1,Serial_TxPacket[0],2);
            OLED_ShowHexNum(4,4,Serial_TxPacket[1],2);
            OLED_ShowHexNum(4,7,Serial_TxPacket[2],2);
            OLED_ShowHexNum(4,10,Serial_TxPacket[3],2);
        }
    }
}

Serial.c代码部分:


d9f45ad5d76b4755bc5b8ff260434f48.png

bf2ea9b271724458b69c50d395a90b43.png

60c9af3c17ee4b2f92795ea76d6029b4.png

818ec9167cc94d8dbf9262185905b8a4.png

95b322cb931a4606ba258dd8fc525c3e.png

0a001908d62940168339b8da1e54ec89.png

#include "stm32f10x.h"                  // Device header
uint8_t Serial_RxFlag;
uint8_t Serial_TxPacket[4];
uint8_t Serial_RxPacket[4];//接收库函数USART_Serial_ReceiveData(USART1)的值,
void Serial_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    USART_InitTypeDef USART_InitStruct;
    USART_InitStruct.USART_BaudRate=9600;
    USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode=USART_Mode_Tx;
    USART_InitStruct.USART_Parity=USART_Parity_No;
    USART_InitStruct.USART_StopBits=1;
    USART_InitStruct.USART_WordLength=0;
    USART_Init(USART1,&USART_InitStruct);
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStruct);
    USART_Cmd(USART1,ENABLE);
}
void Serial_SendByte(uint8_t Byte)
{
    USART_SendData(USART1,Byte);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
void Serial_SendArray(uint8_t *Array,uint16_t Lenth)
{
    uint8_t i;
    for(i=0;i<Lenth;i++)
    {
        USART_SendData(USART1,Array[i]);
    }
}
void Serial_SendString(char*String)
{
    uint8_t i;
    for(i=0;String[i]!= '\0';i++)
    {
        Serial_SendByte(String[i]);
    }
}
uint32_t  Serial_Pow(uint16_t x,uint16_t y)
{
    uint32_t Return;
    while(y--)
    {
        Return*=x;
    }
        return Return;
}
void Serial_SendNumber(uint32_t Number,uint8_t Lenth)
{
    uint8_t i;
    for(i=0;i<Number;i++)
    {
        USART_SendData(USART1,Number/Serial_Pow(10,Lenth-1-i)%10+0x40);
    }
}
uint8_t Serial_GetRxFlag(void)
{
    if(Serial_RxFlag==1)
    {
        Serial_RxFlag=0;
        return 1;
    }
    else
        return 0;
}
//调用该函数,TxPacket的四个数据会自动发送出去
void Serial_SendPacket(void)
{
    Serial_SendByte(0xFF);//发送包头(数据用Byte)
    Serial_SendArray(Serial_TxPacket,4);//发送载荷数据(数组用Array)
    Serial_SendByte(0xFE);
}
//接收数据
void USART1_IRQHandler(void)
{
    static uint8_t RxState=0;//分情况判断
    static uint8_t pRxPacket=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)
        {
            Serial_RxPacket[pRxPacket]=RxData;//将RxData放在数组里,pRxPacket表示存的位置
            pRxPacket++;
            if(pRxPacket>=4)
            {
                RxState=2;
            }
        }
        else if(RxState==2)
        {
            if(RxData==0xFE)
            {
                RxState=0;
                Serial_RxFlag=1;//置标志位,告诉已结束
            }
        }
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
    }
}

Serial.h代码部分:


e2279982e67f4c52b3579f64c5cb9bf7.png

#ifndef  __SERIAL_H
#define  __SERIAL_H
extern uint8_t Serial_TxPacket[];
extern uint8_t Serial_RxPacket[];
void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array,uint16_t Lenth);
void Serial_SendString(char* String);
uint32_t  Serial_Pow(uint16_t x,uint16_t y);
void Serial_SendNumber(uint32_t Number,uint8_t Lenth);
void USART1_IRQHandler(void);
uint8_t Serial_GetRxFlag(void);
void Serial_SendPacket(void);
#endif


个人笔记:


33b3f0a89f3f430a9c8a8207f08589e4.jpg

相关文章
|
2月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
236 0
|
2月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
35 9
|
2月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
27 2
|
2月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
|
3月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
182 2
|
4月前
|
传感器
|
3月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
333 4
|
3月前
|
存储 数据采集 数据安全/隐私保护
使用STM32F103读取TF卡并模拟U盘:使用标准库实现
通过以上步骤,你可以实现用STM32F103将TF卡内容变成U盘进行读取。这种功能在数据采集、便携式存储设备等应用中非常有用。如果你有更多的需求,可以进一步扩展此项目,例如添加文件管理功能、加密存储等。希望这篇博客能帮到你,如果有任何问题,欢迎在评论区留言讨论!
84 1
|
3月前
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
266 2
|
2月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。