历史上的今天
返回首页

历史上的今天

今天是:2024年12月14日(星期六)

2021年12月14日 | 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);

推荐阅读

史海拾趣

CUI公司的发展小趣事

在全球化的背景下,电子行业中的CUI技术也呈现出国际合作与竞争并存的局面。一些国内企业通过与国际知名企业的技术合作,引进先进的CUI生产线和工艺,提高了自身的技术水平和市场竞争力。同时,国际市场的竞争也促使国内企业不断创新,寻求差异化的发展道路。

FASTRAX公司的发展小趣事

随着公司业务的不断发展,FASTRAX开始积极拓展海外市场,并与多家国际知名企业建立了战略合作关系。通过与这些企业的合作,FASTRAX不仅获得了更多的市场份额,也学习到了先进的管理经验和技术知识。这些合作经验为FASTRAX的持续发展奠定了坚实的基础。

Chesivale Electronics公司的发展小趣事

Chesivale Electronics公司深知人才是企业发展的核心动力。因此,公司一直注重人才队伍建设。公司通过校园招聘、社会招聘等多种渠道吸引优秀人才加入,同时建立完善的培训机制和晋升机制,激发员工的积极性和创造力。这些措施使得公司的人才队伍不断壮大,为公司的发展提供了有力的人才保障。

台湾美丽微(FMS)公司的发展小趣事

2013年,FTDI推出了最新的嵌入式视频引擎(EVE)技术产品。这项技术将高度先进的图形控制器、显示器、音频和触摸功能集成到单一芯片中,为智能显示器的实施提供了高效、便捷的解决方案。这一创新不仅提升了FTDI在嵌入式系统领域的竞争力,也为公司在智能家居、工业自动化等多个领域的市场拓展提供了有力支持。

成都芯进(CrossChip)公司的发展小趣事

2013年,三位在半导体行业积累了近十年经验的成电校友,怀揣着对电子技术的热爱和对国产芯片事业的执着,在成都创办了成都芯进电子有限公司(CrossChip)。公司初期专注于模拟和混合信号芯片设计,并以磁传感器芯片作为切入点。一年后,他们的首款产品——开关型霍尔传感器成功实现量产销售,为公司的发展奠定了坚实的基础。

Bussmann (Eaton)公司的发展小趣事

1985年,Cooper工业(后更名为库柏工业)收购了Bussmann公司,并成立了新的事业部——“Cooper Bussmann熔断器”。这一收购为Bussmann带来了更多的资源和市场机会,使其能够进一步扩大生产规模,提升产品质量,并加强在全球市场的布局。同时,Cooper工业的支持也帮助Bussmann巩固了在电路保护领域的领先地位,并逐渐将其打造成为熔断器电路保护及相关配件的最知名品牌。

问答坊 | AI 解惑

如何学好电子技术-致初学者

学习电子技术是一个循序渐进的过程,我个人认为应该分五步来走:        第一步,培养兴趣。受家庭影响,我从小就对电子技术产生了浓厚兴趣,整天把一些电池、导线、小灯泡连来连去,为搞清楚收音机里为何能发出人说话唱歌的 ...…

查看全部问答>

用单片机如何检测另一大功率系统已发生短路?

请问下用单片机如何来检测另一大功率系统已经发生短路了(电源分开);我想用激励变压器来做不知是否可以,原理是当大 功率系统短路了电流就大,通过激励变压器在次级产生一电压,再通过比较器到单片机系统,请问是否可以?…

查看全部问答>

Windows CE下GPS与PDA串行通信的实现.pdf

Windows CE下GPS与PDA串行通信的实现.pdf…

查看全部问答>

问大家几个问题,也许对你们来说是比较简单的!谢谢,急急急急~~~~~~

1.VS1103这个MIDI音源我要是画在电路图中,应该怎么样在库里找到呢?是否Protel库里根本就没有这个元件呢?? 2.我需要用一个5芯的MIDI接口来外接MIDI音源,要在图里画出一个5芯接口的元件,要用哪个呢? 3.还要用到一个小功率的LM386,应该怎么 ...…

查看全部问答>

上海某国内知名产品公司诚聘3年以上嵌入式开发工程师,薪资10K以上

一、主管(高级嵌入式开发软件工程师)   本科5年以上 职位描述: 1、负责软件产品的系统分析和架构设计 2、指导工程师进行模块设计,解决工作中的技术问题 3、负责关键核心模块的编码以及质量控制 任职要求: 1、精通C&C++,5年以上嵌 ...…

查看全部问答>

CeFindAllFile问题

我在做Wince设备中某目录下的文件复制到PC时,用CeFindAllFiles函数返回为true, 但不能返回所有的文件名,有没有谁弄过的?能不能写一下CeFindAllFiles 的用法? 最好给个例子. …

查看全部问答>

51单片机中的通用寄存器属于ram还是属于cpu?比如一本书说cpu寄存器分通用寄存器和系统寄存器,然后框图里是包括通用寄存器的,

51单片机中的通用寄存器属于ram还是属于cpu?比如一本书说cpu寄存器分通用寄存器和系统寄存器,然后框图里是包括通用寄存器的, 但另外一本书上看到cpu通用寄存器又是存放在RAM里的。。 糊涂啊 …

查看全部问答>

帮忙看看F437用到LCD的P4、P5口应该怎样设置呢?谢谢!

高手帮忙看看,MSP430F437用到LCD的P4、P5口应该怎样设置呢? LCDCTL = LCDSG0_1 + LCD4MUX + LCDON; // 4-Mux LCD, segments S0-S15 BTCTL = BT_fLCD_DIV256; // LCD clock freq is ACLK/256=32768Hz P5SEL = 0xFC; ...…

查看全部问答>