单片机
返回首页

STM32串口协议概念及结构体初始化详解+串口点灯+串口收发

2021-12-14 来源:eefocus

一、串口通信协议简介

物理层:规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。其实就是硬件部分。


协议层:协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。其实就是软件部分。


1.RS232标准

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.USB转串口

在这里插入图片描述

3.原生的串口到串口

在这里插入图片描述

二、初始化结构体解

1.USART初始化结构体

在这里插入图片描述

2.同步时钟初始化结构体

在这里插入图片描述

3.编程时需要用到的固件库函数

在这里插入图片描述
在这里插入图片描述

三、串口点灯代码实现

1.USART .C文件

#include 'bsp_usart.h'


void USART_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;


// 打开串口GPIO的时钟

DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

// 打开串口外设的时钟

DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);


// 将USART Tx的GPIO配置为推挽复用模式

GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);


  // 将USART Rx的GPIO配置为浮空输入模式

GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

// 配置串口的工作参数

// 配置波特率

USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;

// 配置 针数据字长

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

// 配置停止位

USART_InitStructure.USART_StopBits = USART_StopBits_1;

// 配置校验位

USART_InitStructure.USART_Parity = USART_Parity_No ;

// 配置硬件流控制

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

// 配置工作模式,收发一起

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

// 完成串口的初始化配置

USART_Init(DEBUG_USARTx, &USART_InitStructure);

// // 串口中断优先级配置

// NVIC_Configuration();

//

// // 使能串口接收中断

// USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);

// 使能串口

USART_Cmd(DEBUG_USARTx, ENABLE);     

}


/* 发送一个字节 */

void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)

{

USART_SendData(pUSARTx, data);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

}


/* 发送两个字节的数据 */

void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)

{

uint8_t temp_h,temp_l;

temp_h = (data&0xff00) >> 8 ;

temp_l = data&0xff;

USART_SendData(pUSARTx, temp_h);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

USART_SendData(pUSARTx, temp_l);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

}


/* 发送8位数据的数组 */

void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)

{

uint8_t i;

for( i=0; i  {

Usart_SendByte(pUSARTx, array[i]);

}

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );

}


/* 发送字符串 */

void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)

{

uint8_t i=0;

do

  {

Usart_SendByte(pUSARTx, *(str+i));

i++;

}while(*(str+i) != '');

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );

}


///重定向c库函数printf到串口,重定向后可使用printf函数

int fputc(int ch, FILE *f)

{

/* 发送一个字节数据到串口 */

USART_SendData(DEBUG_USARTx, (uint8_t) ch);

/* 等待发送完毕 */

while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

return (ch);

}


///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数

int fgetc(FILE *f)

{

/* 等待串口输入数据 */

while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);


return (int)USART_ReceiveData(DEBUG_USARTx);

}


2.USART.H文件

#ifndef __BSP_USART_H

#define __BSP_USART_H


#include 'stm32f10x.h'

#include


#define DEBUG_USART1     1

#define DEBUG_USART2     0

#define DEBUG_USART3     0

#define DEBUG_USART4     0

#define DEBUG_USART5     0


#if DEBUG_USART1

// 串口1-USART1

#define  DEBUG_USARTx                   USART1

#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1

#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_9

#define  DEBUG_USART_RX_GPIO_PORT       GPIOA

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10


#define  DEBUG_USART_IRQ                USART1_IRQn

#define  DEBUG_USART_IRQHandler         USART1_IRQHandler


#elif DEBUG_USART2

//串口2-USART2

#define  DEBUG_USARTx                   USART2

#define  DEBUG_USART_CLK                RCC_APB1Periph_USART2

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_2

#define  DEBUG_USART_RX_GPIO_PORT       GPIOA

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_3


#define  DEBUG_USART_IRQ                USART2_IRQn

#define  DEBUG_USART_IRQHandler         USART2_IRQHandler


#elif DEBUG_USART3

//串口3-USART3

#define  DEBUG_USARTx                   USART3

#define  DEBUG_USART_CLK                RCC_APB1Periph_USART3

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOB)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOB   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_RX_GPIO_PORT       GPIOB

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11


#define  DEBUG_USART_IRQ                USART3_IRQn

#define  DEBUG_USART_IRQHandler         USART3_IRQHandler


#elif DEBUG_USART4

//串口4-UART4

#define  DEBUG_USARTx                   UART4

#define  DEBUG_USART_CLK                RCC_APB1Periph_UART4

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_RX_GPIO_PORT       GPIOC

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11


#define  DEBUG_USART_IRQ                UART4_IRQn

#define  DEBUG_USART_IRQHandler         UART4_IRQHandler


#elif DEBUG_USART5

//串口5-UART5

#define  DEBUG_USARTx                   UART5

#define  DEBUG_USART_CLK                RCC_APB1Periph_UART5

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_12

#define  DEBUG_USART_RX_GPIO_PORT       GPIOD

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_2


#define  DEBUG_USART_IRQ                UART5_IRQn

#define  DEBUG_USART_IRQHandler         UART5_IRQHandler


#endif


void USART_Config(void);

void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);

void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data);

void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num);

void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str);

#endif  /* __BSP_USART_H */


3.MAIN.C


#include 'stm32f10x.h'

#include 'bsp_led.h'

#include 'bsp_usart.h'


int main(void)

{

uint8_t ch;

USART_Config();

LED_GPIO_Config();

printf( '这是一个串口控制RGB灯的程序n' );

 

while (1)

{

ch = getchar();

  printf( 'ch=%cn',ch );

switch(ch)

   {

case '1': LED_RED;

break;

 

case '2': LED_GREEN;

  break;

 

case '3': LED_BLUE;

  break;

 

default: LED_RGBOFF;

    break;

}

}

}

/*********************************************END OF FILE**********************/


四、串口收发程序代码实现

1.USART .C文件

#include 'bsp_usart.h'


static void NVIC_Configuration(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  

  /* 嵌套向量中断控制器组选择 */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  

  /* 配置USART为中断源 */

  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;

  /* 抢断优先级*/

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  /* 子优先级 */

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  /* 使能中断 */

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  /* 初始化配置NVIC */

  NVIC_Init(&NVIC_InitStructure);

}


void USART_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;


// 打开串口GPIO的时钟

DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

// 打开串口外设的时钟

DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);


// 将USART Tx的GPIO配置为推挽复用模式

GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);


  // 将USART Rx的GPIO配置为浮空输入模式

GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

// 配置串口的工作参数

// 配置波特率

USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;

// 配置 针数据字长

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

// 配置停止位

USART_InitStructure.USART_StopBits = USART_StopBits_1;

// 配置校验位

USART_InitStructure.USART_Parity = USART_Parity_No ;

// 配置硬件流控制

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

// 配置工作模式,收发一起

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

// 完成串口的初始化配置

USART_Init(DEBUG_USARTx, &USART_InitStructure);

// 串口中断优先级配置

NVIC_Configuration();

// 使能串口接收中断

USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);

// 使能串口

USART_Cmd(DEBUG_USARTx, ENABLE);     

}


/* 发送一个字节 */

void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)

{

USART_SendData(pUSARTx, data);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

}


/* 发送两个字节的数据 */

void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)

{

uint8_t temp_h,temp_l;

temp_h = (data&0xff00) >> 8 ;

temp_l = data&0xff;

USART_SendData(pUSARTx, temp_h);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

USART_SendData(pUSARTx, temp_l);

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

}


/* 发送8位数据的数组 */

void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)

{

uint8_t i;

for( i=0; i  {

Usart_SendByte(pUSARTx, array[i]);

}

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );

}


/* 发送字符串 */

void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)

{

uint8_t i=0;

do

  {

Usart_SendByte(pUSARTx, *(str+i));

i++;

}while(*(str+i) != '');

while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );

}


///重定向c库函数printf到串口,重定向后可使用printf函数

int fputc(int ch, FILE *f)

{

/* 发送一个字节数据到串口 */

USART_SendData(DEBUG_USARTx, (uint8_t) ch);

/* 等待发送完毕 */

while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);

return (ch);

}


///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数

int fgetc(FILE *f)

{

/* 等待串口输入数据 */

while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);


return (int)USART_ReceiveData(DEBUG_USARTx);

}


2.USART.H文件

#ifndef __BSP_USART_H

#define __BSP_USART_H


#include 'stm32f10x.h'

#include


#define DEBUG_USART1     1

#define DEBUG_USART2     0

#define DEBUG_USART3     0

#define DEBUG_USART4     0

#define DEBUG_USART5     0


#if DEBUG_USART1

// 串口1-USART1

#define  DEBUG_USARTx                   USART1

#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1

#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_9

#define  DEBUG_USART_RX_GPIO_PORT       GPIOA

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10


#define  DEBUG_USART_IRQ                USART1_IRQn

#define  DEBUG_USART_IRQHandler         USART1_IRQHandler


#elif DEBUG_USART2

//串口2-USART2

#define  DEBUG_USARTx                   USART2

#define  DEBUG_USART_CLK                RCC_APB1Periph_USART2

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_2

#define  DEBUG_USART_RX_GPIO_PORT       GPIOA

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_3


#define  DEBUG_USART_IRQ                USART2_IRQn

#define  DEBUG_USART_IRQHandler         USART2_IRQHandler


#elif DEBUG_USART3

//串口3-USART3

#define  DEBUG_USARTx                   USART3

#define  DEBUG_USART_CLK                RCC_APB1Periph_USART3

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOB)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOB   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_RX_GPIO_PORT       GPIOB

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11


#define  DEBUG_USART_IRQ                USART3_IRQn

#define  DEBUG_USART_IRQHandler         USART3_IRQHandler


#elif DEBUG_USART4

//串口4-UART4

#define  DEBUG_USARTx                   UART4

#define  DEBUG_USART_CLK                RCC_APB1Periph_UART4

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_RX_GPIO_PORT       GPIOC

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11


#define  DEBUG_USART_IRQ                UART4_IRQn

#define  DEBUG_USART_IRQHandler         UART4_IRQHandler


#elif DEBUG_USART5

//串口5-UART5

#define  DEBUG_USARTx                   UART5

#define  DEBUG_USART_CLK                RCC_APB1Periph_UART5

#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd

#define  DEBUG_USART_BAUDRATE           115200


// USART GPIO 引脚宏定义

#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD)

#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

    

#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   

#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_12

#define  DEBUG_USART_RX_GPIO_PORT       GPIOD

#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_2


#define  DEBUG_USART_IRQ                UART5_IRQn

#define  DEBUG_USART_IRQHandler         UART5_IRQHandler


#endif


void USART_Config(void);

void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);

void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data);

void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num);

void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str);

#endif  /* __BSP_USART_H */


3.MAIN.C


#include 'stm32f10x.h'

#include 'bsp_led.h'

#include 'bsp_usart.h'


int main(void)

{

  uint8_t a[10]={100,2,3,4,5,6,7,8,9,10};

USART_Config();


printf( '串口printf函数测试n' );

while (1)

{

}

}

/*********************************************END OF FILE**********************/

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章