STM32 嵌入式开发学习笔记六 :串口通信

本文转载自:https://www.cnblogs.com/isakovsky/p/11437355.htmlhttps://www.cnblogs.com/isakovsky/p/11444056.html,笔者将讲解STM32与外部设备通过串口通信的方式。

所谓串口通信,其实是一个类似于计算机网络的概念,它有物理层,比如规定用什么线通信,几伏特算高电平,几伏特算低电平。传输层,通信前要发RTS,CTS。每一层都有不同的协议所约束。在STM32中采用的USART就是其中之一。

USART模块由GPIO_InitTypeDef结构体控制,它的定义如下

typedef struct {
 u32 USART_BaudRate; // 波特率
 u16 USART_WordLength; // 字长
 u16 USART_StopBits; // 停止位
 u16 USART_Parity; // 校验位
 u16 USART_Mode; // USART 模式
 u16 USART_HardwareFlowControl; // 硬件流控制
 } USART_InitTypeDef;

外部设备的输入输出分别使用GPIOA的9号和10号管脚,因此我们要先把管脚输入输出模式配置好

GPIO_InitTypeDef GPIO_USART_INIT;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_9;
GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;  //最高输出速率 50MHz
GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
GPIO_Init(GPIOA,&GPIO_USART_INIT);
    
GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_10;
GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;  //最高输出速率 50MHz
GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入
GPIO_Init(GPIOA,&GPIO_USART_INIT);

然后我们设置USART,将波特率设置为9600,禁用硬件流控制模式,工作模式允许发送和接收,不设置校验位,数据位为8比特,在帧尾传输1个停止位。

USART_InitTypeDef USART_INIT;
    
USART_INIT.USART_BaudRate = 9600;
USART_INIT.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //硬件流控制失能
USART_INIT.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;  //接收/发送使能
USART_INIT.USART_Parity = USART_Parity_No;  //奇偶失能
USART_INIT.USART_StopBits = USART_StopBits_1;  //在帧结尾传输 1 个停止位
USART_INIT.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_INIT);
    
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

当然,处理器不可能时时刻刻检查串口有没有信息传来,因此我们刚刚学习的中断就派上了用场,如果串口传输了信息,那么则请求中断并进行处理。

NVIC_InitTypeDef NVIC_USART_INIT;
    
NVIC_USART_INIT.NVIC_IRQChannel = USART1_IRQn;
NVIC_USART_INIT.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_USART_INIT.NVIC_IRQChannelSubPriority = 1;
NVIC_USART_INIT.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_USART_INIT);
    
USART_Cmd(USART1,ENABLE);

中断回调函数,负责接收信息

u8 RXData;

void USART1_IRQHandler()
{
    if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
    {        
        RXData = USART_ReceiveData(USART1);
    }
    USART_ClearITPendingBit(USART1,USART_IT_RXNE|USART_IT_TXE);
}

依然采取防御式编程,只有确信是被中断调用时才进行消息接收,比较坑的一点在于,回调函数的返回值被写死成void类型了,所以必须定义一个外部变量,进行接收值的传输。

输出函数,注意需要等待,直到信息发送完成的flag被设置。

void USART1_SData(u8 Data)
{
    USART_SendData(USART1,Data);
    while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
    USART_ClearFlag(USART1,USART_FLAG_TC);
}
#ifndef _USART_H
#define _USART_H

#include <stm32f10x.h>

void usart_configer();
void USART1_SData(u8 Data);
void USART1_IRQHandler();

extern u8 RXData;

#endif
//usart.h
#include <usart.h>

void usart_configer()
{
    GPIO_InitTypeDef GPIO_USART_INIT;
    USART_InitTypeDef USART_INIT;
    NVIC_InitTypeDef NVIC_USART_INIT;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
    GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_9;
    GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA,&GPIO_USART_INIT);
    
    GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_10;
    GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&GPIO_USART_INIT);
    
    //有些参数和串口助手上设置的比较
    USART_INIT.USART_BaudRate = 9600;
    USART_INIT.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_INIT.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
    USART_INIT.USART_Parity = USART_Parity_No;//奇偶模式,不设置奇偶
    USART_INIT.USART_StopBits = USART_StopBits_1;//停止位
    USART_INIT.USART_WordLength = USART_WordLength_8b;//数据位
    USART_Init(USART1,&USART_INIT);
    
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断
    
    NVIC_USART_INIT.NVIC_IRQChannel = USART1_IRQn;
    NVIC_USART_INIT.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_USART_INIT.NVIC_IRQChannelSubPriority = 1;
    NVIC_USART_INIT.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_USART_INIT);
    
    USART_Cmd(USART1,ENABLE);  
}

void USART1_SData(u8 Data)
{
    USART_SendData(USART1,Data);
    //USART_SendData(USART1,(u8)USART_GetFlagStatus(USART1,USART_IT_TC));
    while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));//等待发送完毕
    USART_ClearFlag(USART1,USART_FLAG_TC);//清除标志位
}

u8 RXData;

void USART1_IRQHandler()//接收
{
    if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判断是否真的是接收中断  每次接收1byte
    {        
        RXData = USART_ReceiveData(USART1);
    }
    USART_ClearITPendingBit(USART1,USART_IT_RXNE|USART_IT_TXE);//清空中断源(接收中断和发送中断)
}
//usart.c

下面我们进行几个串口通信的实际应用。

实验一:发信实验,让开发板通过串口向电脑发送信息:

#include <stdio.h>
#include <stm32f10x.h>
#include <led.h>
#include <button.h>
#include <systick.h>
#include <time.h>
#include <usart.h>
int main()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    led_configer();
    button_configer();
    usart_configer(); 
    while(1)
    {
        USART1_SData(0x66);
    }
}
//main.c

实验二:电脑向串口发送0x55时,开灯,电脑向串口发送0x66时,关灯。

#include <stdio.h>
#include <stm32f10x.h>
#include <led.h>
#include <button.h>
#include <systick.h>
#include <time.h>
#include <usart.h>
int main()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    led_configer();
    button_configer();
    usart_configer(); 
    while(1)
    {
        if(RXData==0x55)
            lightup(GPIO_Pin_1);
        else if(RXData==0x66)
            shutdown(GPIO_Pin_1);
    }
}
//main.c

附:《STM32固件库使用手册》和《STM32参考手册》下载地址:
https://blog.csdn.net/weixin_41561640/article/details/107124800

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习使用 STM32 开发板可以按照以下步骤进行: 1. 了解 STM32 系列:首先,了解 STM32 系列微控制器的概述、特性和不同型号之间的区别。掌握 STM32 的基本架构、处理器核心、外设等信息,以便后续的开发工作。 2. 准备开发环境:下载并安装 STM32CubeIDE(集成开发环境),这是 STMicroelectronics 官方提供的开发工具。确保开发环境的正确安装和配置,包括驱动程序、编译链以及与目标硬件的连接。 3. 学习基本知识:了解嵌入式系统和 ARM Cortex-M 架构的基本概念,熟悉 C 语言编程和基本的电子知识。学习有关 STM32 的参考手册、用户手册和应用笔记,以便理解 STM32 的功能和使用方法。 4. 掌握 STM32CubeMX:学习使用 STM32CubeMX 工具来生成项目代码框架。了解如何选择 MCU 型号、配置时钟、外设和中断,以及生成初始化代码。这个工具可以帮助简化初始化过程。 5. 开始编程:使用 C 语言编写应用程序代码。可以通过 STM32CubeIDE 创建项目,并在其中编写代码。熟悉 STM32 的 HAL 库(硬件抽象层),它提供了一组 API 来操作 STM32 的外设。 6. 调试和测试:使用 STM32CubeIDE 提供的调试工具进行代码调试和硬件性能测试。学习使用调试器来断点调试、单步执行、查看寄存器和变量的值等。 7. 开发应用程序:根据具体的应用需求,开发相应的功能和应用程序,如控制外设、读取传感器数据、通信等。可以参考官方文档、示例代码和开发板的用户手册。 8. 扩展功能:学习如何使用外部模块或传感器与 STM32 开发板进行连接和通信。了解串行通信接口(如 UART、SPI、I2C)和其他常用接口的使用方法。 9. 学习资源和社区:利用 STMicroelectronics 官方提供的文档、示例代码、技术支持和社区资源。参加培训课程、研讨会或参与在线论坛,与其他开发者交流经验和解决问题。 10. 实践项目:通过完成一些简单的项目来巩固所学知识,并逐步挑战更复杂的项目。可以从 LED 控制、按键输入、显示屏驱动等简单示例开始,逐步扩展到更复杂的应用领域。 以上步骤提供了一个基本的学习路径,但具体的学习过程可能因个人需求和项目要求而有所不同。重要的是持续学习和实践,不断提升自己在 STM32 开发方面的技能和经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值