STM32串口中断的方式发送

2023-05-16

我将其改为真正的中断发送。

步骤一:初始化GPIO

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;         //LED1-PC10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          //USART1 TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);          //A端口
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;             //USART1 RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //复用开漏输入
GPIO_Init(GPIOA, &GPIO_InitStructure);               //A端口

步骤二:开时钟

/* Enable USART1, GPIOA, GPIOD and AFIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC
                         | RCC_APB2Periph_AFIO, ENABLE);

在此说明,不用设置RCC_APB2Periph_AFIO也是可以的,也就是在此没有使用复用功能。这两个步骤与查询方式是一样的。

步骤三:初始化USART1

USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_2;
USART_InitStructure.USART_Parity = USART_Parity_No;      //设置奇校验时,通信出现错误
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 /* Configure the USART1 */
USART_Init(USART1, &USART_InitStructure);
 /* Enable the USART Transmoit interrupt: this interrupt is generated when the
USART1 transmit data register is empty */ 
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
 /* Enable the USART Receive interrupt: this interrupt is generated when the
  USART1 receive data register is not empty */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
 /* Enable USART1 */
USART_Cmd(USART1, ENABLE);

在这里要使能USART1的外设中断,如USART_ITConfig(USART1, USART_IT_TXE, ENABLE);这就是使能发送中断,但发送寄存器空时能产生中断。

步骤四:编写中断函数

#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define RxBufferSize1   (countof(TxBuffer1) - 1)
#define countof(a)   (sizeof(a) / sizeof(*(a)))      //表示数组a中元素的个数 
 
uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
uint8_t RxBuffer1[RxBufferSize1],rec_f;
__IO uint8_t TxCounter1 = 0x00;
__IO uint8_t RxCounter1 = 0x00;
uint8_t NbrOfDataToTransfer1 = TxBufferSize1;
uint8_t NbrOfDataToRead1 = RxBufferSize1;
 
/*串口中断服务程序*/
void USART1_IRQHandler(void)
{
  unsigned int i;
  /*接收中断*/
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {   
    /* Read one byte from the receive data register */
    RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);
    if(RxCounter1 == NbrOfDataToRead1)  //接收数据达到需要长度,则将数据复制到发送数组中,并置标志
    {                     
      /* Disable the USART1 Receive interrupt */
      //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
        for(i=0; i< RxCounter1; i++) TxBuffer1[i]  = RxBuffer1[i];
        rec_f=1;
        RxCounter1=0;
        TxCounter1=0;
        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  //打开发送中断,这句是关键
    }
  }
  /*发送中断*/
  if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  {  
  
    USART_SendData(USART1, TxBuffer1[TxCounter1++]);
 
    if(TxCounter1 == NbrOfDataToTransfer1)//发送数据完成
    {   
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //关闭发送中断
    }   
  }   

至此程序就结束了。

我们就会有个疑问,main()只包括前三个步骤的初始化和一个死循环,那么中断又是如何触发的呢,main()的结构如下:

int main(void)
{
 /* System Clocks Configuration */
 RCC_Configuration();
 /* NVIC configuration */
 NVIC_Configuration();
 /* Configure the GPIO ports */
 GPIO_Configuration();
 USART_Configuration();
 
 while (1)
 {
 }
}
原来是这样的:状态寄存器USART_SR的复位值为0x00C0H, 也就是第七位TXE和第六位TC复位值为1,而TXE=1,表明发送数据寄存器为空, TC=1表明发送已完成。而在USART的设置中有

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

这两句使能中断,也就是说当TXE=1就会进入中断,所以程序初始化后就能进入中断,执行

if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
 {  
    /* Write one byte to the transmit data register */
      USART_SendData(USART1, TxBuffer[TxCounter++]);
    if(TxCounter == NbrOfDataToTransfer)
    {
      /* Disable the USART1 Transmit interrupt */
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    }
 }

因此建议的是在初始化时不好启用TXE中断,只在要发送数据(尤其是字符串、数组这样的系列数据)时才启用TXE。在发送完成后立即将其关闭,以免引起不必要的麻烦。
对于发送,需要注意TXE和TC的差别——这里简单描述一下,假设串口数据寄存器是DR、串口移位寄存器是SR以及TXD引脚TXDpin,其关系是DR->SR->TXDpin。当DR中的数据转移到SR中时TXE置1,如果有数据写入DR时就能将TXE置0;如果SR中的数据全部通过TXDpin移出并且没有数据进入DR,则TC置1。并且需要注意TXE只能通过写DR来置0,不能直接将其清零,而TC可以直接将其写1清零。
对于发送单个字符可以考虑不用中断,直接以查询方式完成。
对于发送字符串/数组类的数据,唯一要考虑的是只在最后一个字符发送后关闭发送中断,这里可以分为两种情况:对于发送可显示的字符串,其用0x00作为结尾的,因此在ISR中就用0x00作为关闭发送中断(TXE或者TC)的条件;第二种情况就是发送二进制数据,那就是0x00~0xFF中间的任意数据,就不能用0x00来判断结束了,这时必须知道数据的具体长度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32串口中断的方式发送 的相关文章

  • 如何在 Cortex-M3 (STM32) 上从 RAM 执行函数?

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • 135-基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真+源程序

    资料编号 135 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 电机 超声波传感器 制作一个基于stm32单片机超声波非接触式感应水龙头控制系统Proteus仿真 2 通过DHT11传感器检测当前
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后

随机推荐

  • 关于mysql自增id的获取和重置

    转载请注明出处 xff1a 帘卷西风的专栏 http blog csdn net ljxfblog mysql获取自增id的几种方法 使用max函数 xff1a select max id from tablename 优点 xff1a 使
  • LXC的安装与配置使用

    1 简介 在云端技术的领域 xff0c 虚拟系统扮演了重要的角色 xff0c 但不管虚拟系统怎样演进 xff0c 效能如何的提升 xff0c 不可否认的虚拟系统 xff08 Guest OS xff09 对实体系统 xff08 Host O
  • 关于SQL中Union和Join的用法

    转载请注明出处 xff1a 帘卷西风的专栏 http blog csdn net ljxfblog 一直以来 xff0c 对于数据库SQL方面都是半吊子水平 xff0c 能写一些基本的增删改查的语句 xff0c 大部分时间都是用下Where
  • 使用Cmake生成跨平台项目编译解决方案

    项目最近有需求在windows下面运行 xff0c 我花了几周时间将linux的服务器移植到windows下面 xff0c 目前已经能够正常运行服务器 xff0c 目前又有了新需求 xff0c 两边的代码结构和组织是分开的 xff0c 因此
  • linux下shell技巧

    经常看到一些大牛操作linux的时候 xff0c 双手运指如飞 xff0c 指令如流水般输出 xff0c 会不会感到羡慕呢 xff1f 本文就整理了一些linux下shell的技巧 xff0c 保管你学会之后 xff0c shell输出ap
  • Cmake在windows支持预编译头文件(stdafx.h)

    最近一直在研究cmake构建项目 xff0c 之前接触cmake的时候就感觉不太喜欢cmake xff0c 觉得它太乱了 xff0c 产生了太多的中间文件 xff0c 产生的项目文件也不是特别友好 xff0c 在windows下 xff0c
  • 位置控制代码

    Copyright c 2013 2016 PX4 Development Team All rights reserved Redistribution and use in source and binary forms with or
  • 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。

    最近公司开发网站针对微信公众号的支付功能 由于公司目前的这个项目网站是使用asp代码开发的 xff0c 但是微信官方给出的demo中是没有asp版本的 xff0c 所以楼主只有下载demo的php版本作为参考写了一个asp版本的代码 阅读官
  • Nacos实战一:架构及部署

    2018年 xff0c 阿里巴巴开源 Nacos xff0c 由此成为继 Eureka Consul Apollo 等服务注册发现 amp 配置的又一开源框架 xff0c 到如今2021年 xff0c Nacos 已经历了 0 01 gt
  • Windows Server搭建Tomcat服务器及Java项目应用

    Windows Server搭建Tomcat服务器及Java项目应用 本文主要介绍使用阿里云Windows Server搭建Tomcat服务器及Java项目应用 xff0c 将文章写下来以后自己也可以及时看看 工具和软件 服务器 xff1a
  • 【Node.js】安装使用nvm管理nodejs版本

    Node js 安装使用nvm管理nodejs版本 本文主要介绍mac linux下如何安装nvm来管理nodejs版本 一 下载nvm安装 方式一 xff1a brew方式 1 xff1a brew list nvm 命令检测是否安装nv
  • Redis设置Key/value的规则定义和注意事项(附工具类)

    Redis设置Key value的规则定义和注意事项 xff08 附工具类 xff09 对于redis的存储key value键值对 xff0c 经过多次踩坑之后 xff0c 我们总结了一套规则 xff1b 这篇文章主要讲解定义key va
  • Linux命令之mkdir

    mkdir命令用于创建目录 xff0c 全拼 xff1a make directory 具体参数 xff1a m 选项自定义目录权限 p 递归建立目录 v 创建文件夹时显示信息
  • 浅析微信支付:支付结果通知

    本文是 浅析微信支付 系列文章的第六篇 xff0c 主要讲解支付成功后 xff0c 微信回调商户支付结果通知的处理 浅析微信支付系列已经更新五篇了哟 xff5e xff0c 没有看过的朋友们可以看一下哦 浅析微信支付 xff1a 统一下单接
  • 浅析微信支付:查询订单和关闭订单

    本文是 浅析微信支付 系列文章的第七篇 xff0c 主要讲解微信商户平台的订单查询和关闭接口的使用 浅析微信支付系列已经更新六篇了哟 xff5e xff0c 没有看过的朋友们可以看一下哦 浅析微信支付 xff1a 支付结果通知 浅析微信支付
  • 超实用!!!使用IDEA插件Alibaba Cloud Toolkit工具一键部署本地应用到ECS服务器

    最近看到阿里云发布了一款名为 Alibaba Cloud Toolkit 的插件 xff0c 可以帮助开发者高效开发并部署适合在云端运行的应用 xff0c 瞬间击中了我的小心脏 xff0c 这个对于个人开发者来说超级棒啊 xff0c 终于不
  • 浅析微信支付:开通社交立减金活动、创建立减金及领取使用的相关文档和源码

    本文是 浅析微信支付 系列文章的第十七篇 xff0c 主要讲解在在微信平台中 xff0c 如何创建优惠券 xff0c 开通社交立减金 xff0c 并为用户配置发送立减金 上篇文章已经为大家讲解了如何在微信公众平台创建优惠券并为用户发券 xf
  • vnc远程屏幕大小设置

    安装软件tigervnc server yum install vnc y 注释 etc sysconfig vncservers VNCSERVERS 61 34 1 root 34 VNCSERVERARGS 1 61 34 geome
  • tx2系统备份与恢复

    tx2系统备份与恢复 tx2系统备份与恢复对我们以后长期开发与产品批量生产是非常有帮助的 xff0c 能快速的对已经开发好的系统进行备份 xff0c 复制 xff0c 节约大量的安装时间 在操作过程在需要手动操作 xff0c 执行命令也不多
  • STM32串口中断的方式发送

    我将其改为真正的中断发送 步骤一 xff1a 初始化GPIO GPIO InitTypeDef GPIO InitStructure GPIO InitStructure GPIO Pin 61 GPIO Pin 10 LED1 PC10