STM32学习--USART

2023-05-16

串口工作方式;
1.查询:串口程序不断循环查询,看看有没有数据需要它发送。
2.中断:平时串口只要打开中断即可。如果有中断来即需要传输数据,它就马上进行数据的传输。


STM32编程:
1.RCC设置
处常规时钟设置外,需要打开USART对应的IO口时钟,USART时钟,还有管脚功能复用时钟


2.GPIO设置
GPIO管脚配置为推挽输出,将接收管脚配置为浮空输入


3.USART配置
通过USART_InitTypeDef结构体对USART进行初始化操作,采用中断接收数据的方式,需要在USART配置中,
打开中断,同时还要打开串口。


4.NVIC配置
NVIC配置中主要是USART1_IRQChannel的配置,


5.发送/接收数据
发送数据用USART_SendData()函数,接收数据用USART_ReceiveData()函数。参考固件函数库。
发送数据时先开辟一个缓存区,将需要发送的数据送入缓存区,然后再将数据发送出去,接收数据同样也
是先将数据接收到缓存区,然后再进行相应的操作。
  注意在对数据进行发送和接收的时候,要检查USART的状态,只有等到数据发送或接收完成后才能进行
  下一帧  数据的发送或接收
。采用USART_GetFlagStatus()函数。
          同时还要注意的是,在发送数据的最开始,需要清除一下USART的标志位,否则第一帧数据会丢失。因为在
  硬件复位后,USART的状态位TC是置位的,当包含有数据的一帧发送完成后,由硬件将该位置位。只要当USART
  的状态位TC是置位的时候,就可以进行数据的发送。然后TC位的置零是通过软件序列来清除的,具体步骤为:
  先读USART_SR,然后写入USART_DR,只有这样才能清除标志位TC,但在发送第一帧数据的时候,并没有进行读
  USART_SR的操作,而是直接进行写操作,因此TC标志位并没有清空,那么,当发送第一帧数据,然后用
  USART_GetFlagStatus()检测状态时返回的是已经发送完毕(TC位是置1的),所以程序会马上发送下一帧数据,

  这样第一帧的数据就被第二帧数据覆盖了,所以看不到第一帧数据的发送。


源代码:

#incldue"stm32f10x_lib.h"
  
  FlagStatus RX_status;
  void RCC_cfg();
  void GPIO_cfg();
  void USART_cfg();
  void NVIC_cfg();
  
  int main()
  {
int i;
unsigned char TxBuf1[]="Welcome to www.peix365.com!"
RCC_cfg();
GPIO_cfg();
USART_cfg();
NVIC_cfg();
  //清除标志位,否则第1位数据会丢失
USART_ClearFlag(USART1,USART_FLAG_TC);

//发送数据PD2(LED1)显示正在发送的数据,当有数据发送时,LED1会亮
for(i=0;TxBuf1[i]!='\0';i++)
{
USART_SendData(USART1,TxBuf1[i]);
GPIO_SetBits(GPIOD,GPIO_pin_2)
//等待数据发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
GPIO_ResetBits(GPIOD,GPIO_Pin_2)
}
while(1);
  }
  
  
  //RCC时钟配置
  void RCC_cfg()
  {
//定义错误状态变量
ErrorStatus HSEStartUpStatus;
//将RCC寄存器重新设置为缺省值
RCC_DeInit();
//打开外部高速时钟晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟晶振工作
HSEStartUpStatus=RCC_WaitForHSEStartUp();
if(HSEStartUpStatus==SUCCESS)
{
//设置PLL时钟,为HSE的2倍频
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_2);

//使能PLL
RCC_PLLCmd(ENABLE);

//等待PLL准备就绪
if(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)!=RESET);

//设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判断PLL是否是系统时钟
if(RCC_GetSYSCLKSource()==0x08);
//设置AHB时钟(HCLK)为系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);

//设置高速AHB时钟(APB2)为HCLK时钟
RCC_PCLK2Config(RCC_HCLK_Div1);

//设置低速AHB时钟(APB1)为HCLK的2分频时钟
RCC_PCLK1Config(RCC_HCLK_Div2);

//设置FLASH代码延时
FLASH_SetLatency(FLASH_Latency_2);

//使能预取值缓存
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

}
//打开GPIO时钟,复用功能,使能串口1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE);
  }
  
  
  //IO口配置
  void GPIO_cfg()
  {
GPIO_InitTypeDef GPIO_InitStructure;

//PA9作为USART1的TX端,打开复用,负责发送数据
//初始化GPIO口部分成员
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
//初始化GPIO口
GPIO_Init(GPIOA,&GPIO_InitStructure);

//PA10作为USART1的RX端,负责接收数据
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
  }
  
//LED显示串口正在发送/接收的数据
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT_PP;
GPIO_Init(GPIOD,&GPIO_InitStructure);

  //串口初始化
  void USART_cfg()
  {
USART_InitTypeDef USART_InitStructure;
//将结构体设置为缺省状态
USART_StructInit(&USART_InitStructure);
//波特率设置为9600
USART_InitStructure.USART_BandRate=9600;
//帧数据宽度设置为8bits
USART_InitStructure.WordLength=USART_WordLength_8b;
//帧结尾1个停止位
USART_InitStructure.USART_StopBits=USART_StopBits_1;
//无奇偶校验位
USART_InitStructure.USART_Parity=USART_Parity_No;
//发送/接收使能
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
//硬件流控制失能
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
//初始化串口1
USART_Init(USART1,&USART_InitStructure);
//打开串口1中断响应函数
USART_ITConfig(USART1,USART_IT_RXNE|USART_IT_TXE,ENABLE);
//打开(使能)串口1
USART_Cmd(USART1,ENABLE);
  }
  
  //配置中断
  void NVIC_cfg();
  {
NVIC_InitTypeDef NVIC_InitTypeDef;

//选择中断分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//选择串口1中断
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQChannel;

//抢占式中断优先级为0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

//响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

//IRQ 通道使能
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//中断优先级初始化
NVIC_Init(&NVIC_InitStructure);
  }
  
  //然后在stm32f10x_it.c文件中找到相应的中断处理函数,并填入以下内容。
  //注意在stm32f10x_it.c中,要声明一下外部变量RX_status
  extern FlagStatus RX_status;
  
  void USART1_IRQHandler(void)
  {
GPIO_SetBits(GPIOD,GPIO_Pin_2);
//确认是否接收到数据
RX_status=USART_GetFlagStatus(USART1,USART_FLAG_RXNE);
//接收到数据
if(RX_status==SET)
{
//将数据回送
USART_SendData(USART1,USART_ReceiveData(USART1));
//等待数据发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
GPIO_ResetBits(GPIOD,GPIO_Pin_2)
}
  }

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

STM32学习--USART 的相关文章

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

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • c项目makefile多重定义错误

    这个问题是一个对应于创建的repexthis问题 在我的嵌入式 C 项目中 我有两个独立的板 我想为每个板创建两个 c 文件 master c 和 Slave c 其中包含自己的特定main 功能 我使用 stm32cumbemx 生成带有
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • STM32 GPIO工作原理详解

    STM32 GPIO介绍 1 STM32引脚说明 GPIO是通用输入 输出端口的简称 是STM32可控制的引脚 GPIO的引脚与外部硬件设备连接 可实现与外部通讯 控制外部硬件或者采集外部硬件数据的功能 以STM32F103ZET6芯片为例
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 无法使用 OpenOCD 找到脚本文件

    我正在尝试按照本教程将 OpenOCD 与我的 ST 发现板一起使用 https japaric github io discovery README html https japaric github io discovery READM
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • 使用 STM32 USB 设备库将闪存作为大容量存储设备

    我的板上有这个闪存IC 它连接到我的STM32F04 ARM处理器 处理器的USB端口可供用户使用 我希望我的闪存在通过 USB 连接到 PC 时被检测为存储设备 作为第一步 我在程序中将 USB 类定义为 MSC 效果很好 因为当我将主板
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re

随机推荐