首页 > 其他分享 >STM32-基于标准库的中断串口通信

STM32-基于标准库的中断串口通信

时间:2023-10-28 17:12:26浏览次数:43  
标签:USART 中断 void STM32 InitStructure 串口 GPIO Serial USART1

目录

STM32-标准库实现中断方式的串口通信

实验任务

使用标准库方式,设置USART1 波特率为115200,1位停止位,无校验位,采用中断方式完成下列任务:

  • STM32系统给上位机(win10)连续发送“hello windows!”;
  • 当上位机给stm32发送字符串“stop”后,stm32暂停发送“hello windows!”;
  • 发送一个字符串“start”后,stm32继续发送。

实验过程

  1. 创建好工程后,在Hardware文件夹下新建两个文件:Serial.h 和 Serial.c,用来编写串口收发数据的相关代码。

  2. 串口通信相关变量和函数介绍:

    • char Serial_RxPacket[]:缓存数组,当单片机接收到的上位机的数据后,存放在这个数组里。
    • uint8_t Serial_RxFlag:判断数据是否全部接收完成,如果上位机发送过来的数据,单片机全部接收完毕,就把这个变量置为1,否则为0。
    • void Serial_Init(void):串口初始化函数,进行一些串口、引脚和模式的配置。
    • void Serial_SendByte(uint8_t Byte):单片机给上位机发送一个字节。
    • void Serial_SendString(char *String):单片机给上位机发送一个字符串。
  3. Serial.h中编写如下代码:

    #ifndef __SERIAL_H
    #define __SERIAL_H
    
    #include <stdio.h>
    
    extern char Serial_RxPacket[]; // 单片机接收到的上位机的数据,存放在这里
    extern uint8_t Serial_RxFlag; // 判断数据是否全部接收完成
    
    void Serial_Init(void); // 串口初始化函数
    void Serial_SendByte(uint8_t Byte); // 单片机给上位机发送一个字节
    void Serial_SendString(char *String); // 单片机给上位机发送一个字符串
    
    #endif
    

    Serial.c中对相应变量进行初始化,对相应函数进行实现,代码如下:

    #include "stm32f10x.h"                  // Device header
    #include <stdio.h>
    #include <stdarg.h>
    
    char Serial_RxPacket[100];
    uint8_t Serial_RxFlag;
    
    void Serial_Init(void)
    {
        // 使能USART1和GPIOA的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
        // 配置USART1的引脚
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     // 复用推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           // USART1的TX引脚
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // GPIO速度
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        // 配置USART1的引脚
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       // 输入上拉
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;          // USART1的RX引脚
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // GPIO速度
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        // 配置USART1
        USART_InitTypeDef USART_InitStructure;
        USART_InitStructure.USART_BaudRate = 115200;                          // 波特率
        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_Init(USART1, &USART_InitStructure);
    
        // 使能USART1的接收中断
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    
        // 配置中断分组为第2组
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
        // 配置USART1接收中断的中断处理函数的优先级
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;        // USART1的中断通道
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          // 使能中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       // 子优先级为1
        NVIC_Init(&NVIC_InitStructure);
    
        // 使能USART1
        USART_Cmd(USART1, ENABLE);
    }
    
    void Serial_SendByte(uint8_t Byte)
    {
    	USART_SendData(USART1, Byte);
    	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    }
    
    void Serial_SendString(char *String)
    {
    	uint8_t i;
    	for (i = 0; String[i] != '\0'; i ++)
    	{
    		Serial_SendByte(String[i]);
    	}
    }
    
  4. 中断函数实现:

    本实验选择在中断函数内去接收上位机的数据,并且规定:上位机发送的数据,必须以@为开头,并且结尾要带有换行。

    Serial.c中继续添加中断函数代码:

    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 == '@' && Serial_RxFlag == 0)
    			{
    				RxState = 1;
    				pRxPacket = 0;
    			}
    		}
    		else if (RxState == 1)
    		{
    			if (RxData == '\r')
    			{
    				RxState = 2;
    			}
    			else
    			{
    				Serial_RxPacket[pRxPacket] = RxData;
    				pRxPacket ++;
    			}
    		}
    		else if (RxState == 2)
    		{
    			if (RxData == '\n')
    			{
    				RxState = 0;
    				Serial_RxPacket[pRxPacket] = '\0';
    				Serial_RxFlag = 1;
    			}
    		}
    		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    	}
    }
    

    至此,串口部分的代码就完成了。

  5. main.c中输入以下代码:

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    #include "Serial.h"
    #include "string.h"
    
    // 如果为0,就持续发送“Hello Windows!”,为1,就停止发送
    static uint8_t sendFlag = 0;
    
    int main(void)
    {
    	Serial_Init();
    	
    	while (1)
    	{
    		if (sendFlag == 0) { 
    			Serial_SendString("Hello Windows!\r\n"); // 给上位机发送信息
    			Delay_ms(1000); // 延时1秒
    		}
    		if (Serial_RxFlag == 1) // 单片机接收完毕
    		{
    			if (strcmp(Serial_RxPacket, "start") == 0) // 上位机发送的数据为“start”
    			{
    				sendFlag = 0;
    			}
    			else if (strcmp(Serial_RxPacket, "stop") == 0) // 上位机发送的数据为“stop”
    			{
    				sendFlag = 1;
    			}
    			Serial_RxFlag = 0;  // 重新等待接收
    		}
    	}
    }
    
  6. 实验效果

总结体会

通过本次实验,能够实现STM32的串口通信,并能够通过上位机来简单控制单片机的行为。

遇到的困难:起初尝试用HAL库来写,但折腾了一个晚上,改不出来,所以无奈选择了标准库实现。

参考

江科大-USART串口数据包

标签:USART,中断,void,STM32,InitStructure,串口,GPIO,Serial,USART1
From: https://www.cnblogs.com/cqjtu-linzd/p/17794296.html

相关文章

  • 基于高性能Cortex®-M7内核STM32F765VGT7、STM32F745IET6嵌入式微控制器
    STM32F732位MCU+FPU基于高性能的ARM®Cortex-M732位RISC内核®,工作频率高达216MHz。Cortex®-M7内核具有单浮点单元(SFPU)精度,支持所有ARM®单精度数据处理指令与数据类型。同时执行全套DSP指令和存储保护单元(MPU),增强应用安全性。1、STM32F765VGT7ICMCU32BIT1MB......
  • 微机原理与接口技术中断实验
    ;*******************************;;*中断实验IRQ3*;;*******************************;includeio.inc.modelsmall;定义程序的存储模式.stack;定义堆栈段(默认是1KB空间).datamsgbyte'TPCAinterruptNo.3!',0dh,0ah,0c......
  • 串口占用检测工具
    串口占用检测工具平时需要检测哪个程序占用了串口,下面介绍一款非常方便的工具,它的工具箱里包含一个串口占用检测工具,可以非常方便的检测出来哪个程序占用了串口,并给出程序名和PID。官网下载地址:http://www.redisant.cn/mse......
  • 32-TIM定时中断
    一16位计数器,功能:定时中断、内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发 ......
  • STM32基于HAL库流水灯实验
    一、搭建STM32的开发环境(一)安装jdk由于STM32CubeMX是Java实现的,需要安装jdk环境。jdk官网下载链接:https://www.oracle.com/java/technologies/javase-downloads.html(二)安装STM32CubeMX1.下载地址:https://www.st.com/en/development-tools/stm32cubemx.html2.安装过程1.以管理员身......
  • stm32cubeide+bootloader跳转的方法和坑点
    网上介绍方法很多,跳转原理可以看这一篇  基于STM32的简易Bootloader实现-JiuLiBlog-博客园(cnblogs.com)大概步骤为:先判断栈顶地址是否合法,再关闭总中断和systick中断,再设置跳转地址、再加载栈顶地址,然后就可以跳转了,跳转后的应用程序需要先设置栈顶地址、再开启之前关闭......
  • esp32笔记[9]-rust的串口收发及GCODE解析
    摘要使用rust在no-std环境下实现esp32-c3串口收发及gcode解析.平台信息esp32c3rust超链接esp32笔记[7]-使用rust+zig开发入门使用rust实现串口中断示例代码:serial_interrupts.rs//!ThisshowssomeoftheinterruptsthatcanbegeneratedbyUART/Serial.//!Us......
  • stm32性能评估(程序执行效率,中断最大速率)
    自从研究stm32以来,对mcu的运行速度一直没有一个明确的概念,困惑一直卡在这,很烦,最近有了一点心得,记录一下。stm32的官方数据为1.25MIPS/MHZ,即每秒执行的汇编指令数应该是主频的1.25倍。stm32f103 72M主频,所以一秒执行90M汇编指令,stm32H743480M主频,一秒的指令只会大于600M指令......
  • 安信可小安派【IO中断】基于AI-M6X MCU
    最近在研究小安派的中断。昨晚写了一个Demo来进行测试。关于什么是中断这里已经讲的很清楚了。首先贴上引用参考。第一个是泽哥写的中断:http://ai-thinker.com/forum.php?mod=viewthread&tid=562&highlight=%E4%B8%AD%E6%96%AD&_dsign=fe47e0a0复制代码这个是我自己写......
  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能
    开发板:STM32F407ZGT6;目标:想使用软件“串口调试助手”情况:开发板上的USB_UART口所在器件损坏或者直接没有;解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作:1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,将串口1的TX接USB转TTL模块的R......