linux串口命令UART,STM32串口通信UART使用

2023-05-16

STM32串口通信UART使用

uart使用的过程为:

1. 使能GPIO口和UART对应的总线时钟

2. 配置GPIO口的输出模式

3. 配置uart口相关的基本信息

4. 使能uart口的相关的中断,如接收中断、空闲中断等

5. 编写中断接收函数

配置对应的GPIO口

对于STM32F4_Discovery开发板而言共有五个,选择UART5作为实验串口,其对应的IO口为PC12、PD2。

UART5_TX: PC12

UART5_RX: PD2

首先需要将对应的GPIO口配置为复用功能,如下所示:

GPIO_InitTypeDef gpioInitStructure;

//

// 使能对应的GPIO口时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);

//

// UART5 TX:PC12 RX:PD2

//

GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);

GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);

//

// PC12

gpioInitStructure.GPIO_Pin = GPIO_Pin_12;

gpioInitStructure.GPIO_Mode = GPIO_Mode_AF;

gpioInitStructure.GPIO_OType = GPIO_OType_PP;

gpioInitStructure.GPIO_PuPd = GPIO_PuPd_UP;

gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOC, &gpioInitStructure);

// PD2

gpioInitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_Init(GPIOD, &gpioInitStructure);

对于GPIO口的配置,实际上是对GPIO各个寄存器的配置。GPIO_PinAFConfig()函数作用是配置GPIOx_AFR寄存器,每个口的复用功能选择由四个位来配置(具体参考STM32F4XX参考手册),因此16个GPIO空需要两个32位寄存器,在STM32F4处理器中,分别是GPIOx_AFRL、GPIOx_AFRH。而在库函数中,将寄存器的地址对应到相应的结构体上,与这两个寄存器放在一个AFR[2]数组中,如下所示。

typedef struct

{

__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */

__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */

__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */

__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */

__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */

__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */

__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */

__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */

__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */

__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */

} GPIO_TypeDef;

GPIO_Init()函数作用是配置GPIO口的输出输入功能,将GPIO_TypeDef结构体中的寄存器依次配置为相应的模式。

GPIO口配置完成之后,需要配置UART口。

UART口配置

配置UART口的同时,需要配置对应的接收中断,对应代码如下:

NVIC_InitTypeDef nvicInitStructure;

USART_InitTypeDef uartInitStructure;

//使能uart5时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5 , ENABLE);

//

// 配置UART5

uartInitStructure.USART_BaudRate = 9600;

uartInitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

uartInitStructure.USART_WordLength = USART_WordLength_8b;

uartInitStructure.USART_StopBits = USART_StopBits_1;

uartInitStructure.USART_Parity = USART_Parity_No;

uartInitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_Init(UART5, &uartInitStructure);

//

// 配置外设接受中断

nvicInitStructure.NVIC_IRQChannel = UART5_IRQn;

nvicInitStructure.NVIC_IRQChannelPreemptionPriority = 0;

nvicInitStructure.NVIC_IRQChannelSubPriority = 0;

nvicInitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&nvicInitStructure);

//

USART_Cmd(UART5, ENABLE);

配置UART5的过程主要由USART_Init()函数实现,该函数完成对UART寄存器的配置。在库函数中,UART寄存器如下所示:

typedef struct

{

__IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */

uint16_t RESERVED0; /*!< Reserved, 0x02 */

__IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */

uint16_t RESERVED1; /*!< Reserved, 0x06 */

__IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */

uint16_t RESERVED2; /*!< Reserved, 0x0A */

__IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */

uint16_t RESERVED3; /*!< Reserved, 0x0E */

__IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */

uint16_t RESERVED4; /*!< Reserved, 0x12 */

__IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */

uint16_t RESERVED5; /*!< Reserved, 0x16 */

__IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */

uint16_t RESERVED6; /*!< Reserved, 0x1A */

} USART_TypeDef;

UART寄存器详细内容可以参考STM32F4中文手册,这里简单介绍下以下几个寄存器:

SR寄存器:状态寄存器,包含了一些标志位,如TXE(发送数据寄存器为空)、TC(发送完成)、RXNE(读取数据寄存器不为空)

DR寄存器: 数据寄存器,只用其低9位(DR[8:0])。当发送数据时,将数据写入该寄存器,该寄存器将数据发送到TDR或者移位寄存器发送,当数据写到移位寄存器时,TXE标志置1(数据写入时置0)。TXE为1时可以继续写入数据,否则新写入的数据会把原有数据覆盖。读取数据时,也是从该寄存器读取数据。

BRR波特率寄存器:波特率寄存器,用来设置波特率的值。

CR1寄存器:包含使能位UE、字长M、过采样倍率、奇偶校验、接收使能、发送使能等控制信息。

数据收发

单字符发送

//发送一个字符,USART_SendData函数实际就是将字符写入USART_DR寄存器

USART_SendData(pUSARTx,ch);

//

//等待发送寄存器为空,只有当USART_FLAG_TXE == 1 时才可以继续想DR寄存器写入数据,否则会将上一个数据覆盖掉。

while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET)

字符串发送

/***************** 发送字符串 **********************/

// 发送字符串是每个字符依次发送,相当于循环执行单字符发送函数。

//

void uart_send_str( USART_TypeDef * pUSARTx, char *str){

unsigned int k=0;

//

do {

uart_send_byte( pUSARTx, *(str + k) );

k++;

} while (*(str + k)!='\0');

//

/* 等待发送完成 */

while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) ;

}

//

// USART_FLAG_TC为1的条件是,DR寄存器为空并且以为寄存器也为空。相当于所有数据都发送完毕

字符接收

uint8_t ucTemp;

if (USART_GetITStatus(UART5, USART_IT_RXNE)!=RESET){

ucTemp = USART_ReceiveData( UART5 );

// USART_SendData(UART5,ucTemp);

}

// USART_ReceiveData()函数是将DR寄存器读取并返回

// USART_IT_RXNE不为0表示数据寄存器中有数据,需要将其读出。

// 每次收一个字符,USART_IT_RXNE会被设置为1,直至数据被读出,USART_IT_RXNE再次被设置为0.

// 同时,USART_IT_RXNE也被设置为中断的标志,即接收到数据时,进入中断。

0b1331709591d260c1c78e86d0c51c18.png

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

linux串口命令UART,STM32串口通信UART使用 的相关文章

  • Linux 中的无缓冲 I/O

    我正在写入大量的数据 这些数据数周内都不会再次读取 由于我的程序运行 机器上的可用内存量 显示为 空闲 或 顶部 很快下降 我的内存量应用程序使用量不会增加 其他进程使用的内存量也不会增加 这让我相信内存正在被文件系统缓存消耗 因为我不打算
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • 如何在数组中存储包含双引号的命令参数?

    我有一个 Bash 脚本 它生成 存储和修改数组中的值 这些值稍后用作命令的参数 对于 MCVE 我想到了任意命令bash c echo 0 0 echo 1 1 这解释了我的问题 我将用两个参数调用我的命令 option1 without
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • 如何将目录及其子目录中的所有 PDF 文件复制到一个位置?

    如何全部复制PDF文件从目录及其子目录到单个目录 实际上还有更多的文件 并且深度有些任意 假设四个目录的最大深度是公平的 我想这些文件需要重命名 如果a pdf例如 位于多个目录中 因为我会adding https ebooks stack
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • C语言中如何通过内存地址映射函数名和行号?

    如何用 GCC 中的内存地址映射回函数名称和行号 即假设一个 C 语言原型 void func Get the address of caller maybe this could be avoided MemoryAddress get
  • 为什么我可以直接从 bash 执行 JAR?

    我是一个长期从事 Java 工作的人 并且知道运行带有主类的 JAR 的方法MANIFEST MFJar 中的文件很简单 java jar theJar jar 我用它来启动 Fabric3 服务器 包含在bin server jar在其标
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 查找哪个程序运行另一个程序

    我有一个 NAS 运行在 Redhat Linux 的有限版本上 我按照指示破解了它 这样我就可以访问 shell 这很有帮助 我还做了一些修改 其他人也做过修改 除了一个问题之外 它们似乎都工作得很好 不知何故 每隔 22 天 系统就会关
  • 如何确保应用程序在 Linux 上持续运行

    我试图确保脚本在开发服务器上保持运行 它会整理统计数据并提供网络服务 因此它应该会持续存在 但一天中有几次 它会因未知原因而消失 当我们注意到时 我们只需再次启动它 但这很麻烦 并且某些用户没有权限 或专有技术 来启动它 作为一名程序员 我
  • 如何更改 Apache 服务器的根目录? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何更改 Apache 服务器的文档根目录 我基本上想要localhost从 来 users spencer projects目录而不是

随机推荐

  • 技术系统进化法则是_技术系统进化论,模式七、系统由宏观向微观进化

    阿奇舒勒TRIZ理论三个核心思想 xff1a 1 无论是一个简单产品还是复杂的技术系统 xff0c 其核心技术的发展都是遵循着客观的规律发展演变的 xff0c 即具有客观的进化规律和模式 xff1b 2 各种技术难题和矛盾的不断解决是推动这
  • 吉他谱

    其实我是个诗人 01 得不到你 02 多想在平庸的生活拥抱你 03 往后余生 04 成都 转载于 https www cnblogs com zhangmingyan p 11603872 html
  • Openssl配置CA证书及https访问

    一 创建根秘钥对 1 创建目录 cd mkdir root ca cd root ca mkdir certs crl newcerts private chmod 700 private touch index txt echo 1000
  • Thread.currentThread().setContextClassLoader为什么不生效与java.lang.NoClassDefFoundError之Java类加载的Parent fir...

    众所周知 xff0c Java的类加载机制采用了双亲委派模型 xff0c 导致在进行类加载的时候会有多个加载器 xff0c 这种复杂的机制 xff0c 有时候会导致 Exception in thread main java lang No
  • C#编写的通过汉字得到拼音和五笔码

    public static class SpellAndWbConfig region 变量声明 XML文件读取实例 lt summary gt XML文件读取实例 lt summary gt private static XmlReade
  • 设置HTML5的video播放速度

    var speed 61 1 5 设置速度 var vdo 61 document getElementById 34 视频的id 34 获取id vdo playbackRate 61 speed 改变速度 合并一句 document g
  • uni-app 做路由拦截器

    插件市场 xff08 https ext dcloud net cn plugin id 61 159 xff09 吐槽 好多小伙伴跑来问我有没有Uni app视频教程 xff0c 收费的也行 各位uni app 你根本不需要买市面上几百块
  • 华为S5700交换机初始化和配置SSH和TELNET远程登录方法

    华为S5700交换机初始化和配置TELNET远程登录方法 xff1a 1 交换机开启Telnet服务 lt Huawei gt system view 进入系统视图 Huawei telnet server xff1f 查看有enable还
  • 方差的无偏估计如何计算?

    我们常常被问到 34 方差的无偏估计如何计算 xff1f 和有偏估计的区别是什么 xff1f 34 xff0c 心想 34 哎呀 xff0c 又忘了 34 本篇回归问题本质 xff0c 带你理解这些名词背后解决的实际问题 xff08 通过总
  • C++ for无限循环~

    无限循环 如果条件永远不为假 xff0c 则循环将变成无限循环 for 循环在传统意义上可用于实现无限循环 由于构成循环的三个表达式中任何一个都不是必需的 xff0c 您可以将某些条件表达式留空来构成一个无限循环 include lt io
  • VINS-Fuison调试笔记

    最近一直在断断续续的调试vins fuison xff0c odometry总是各种飘 xff0c 令人头大 记录一下调试过程 xff0c 供以后学习参考 首先选用一组可靠的视觉惯导传感器 xff0c 如Realsense D435i xf
  • 《C和指针》阅读笔记

    第9章 字符串 字符和字节 9 1 字符串基础 字符串就是一串 零个或多个字符 xff0c 并且以一个位模式为全0的NUL字节结尾 因此 xff0c 字符串所包含的字符内部不能出现NUL字节 NUL字节是字符串的终止符 xff0c 但它本身
  • 【蓝牙数据采集模块】-02-Sensor Controller 编写CC2650STK外设驱动

    上次说到把所有的传感器模块在Sensor Controller中实现读写 xff0c 并封装驱动 先来看一下CC2650STK的原理图 用红色方框标记的DIO 0 DIO 7 DIO 23 DIO 30是可以通过Sensor Control
  • ->:间接引用运算符

    gt 是一个整体 xff0c 它是用于指向结构体 C 43 43 中的class等含有子数据的指针用来取子数据 换种说法 xff0c 如果我们在C语言中定义了一个结构体 xff0c 然后申明一个指针指向这个结构体 xff0c 那么我们要用指
  • linux音频服务器,Linux声音系统

    TAG linux alsa oss pulseaudio esd aRts DATE 2013 08 13 Linux声音系统有些混乱 xff0c 它有三套音频驱动 OSS Open Sound System 商业版的OSS xff0c
  • android 网络调试工具,安卓网络调试助手

    安卓网络调试助手apk是一款内容比体积精彩得多的网络设置软件 安卓网络调试助手支持多种端口和协议 xff0c 而且安卓网络调试助手apk虽然功能很专业但是操作起来也不是很难 xff0c 很容易学会 xff01 软件介绍 安卓网络调试助手ap
  • 计算机非全日制硕士 选校,非全日制硕士研究生,到底值不值得报考?看完这篇就懂了!...

    网友一 xff1a 如果不是已经工作的 xff0c 不推荐报考 因为非全日制的待遇不如全日制 xff0c 同时公务员等体制很多要求全日制学历 同时学费也比全日制贵好几倍 加上本身作为新生事物 xff0c 就业市场的认可与否还很难讲 如果你已
  • android进入后台被杀死,Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制...

    新Activity启动及旧Activity保存流程 App在后台久置后 xff0c 再次从桌面或最近的任务列表唤醒时经常会发生崩溃 xff0c 这往往是App在后台被系统杀死 xff0c 再次恢复的时候遇到了问题 xff0c 而在使用Fra
  • V4L2框架

    前言 在分析v4l2之前最好具有的知识 xff1a 1 字符设备 因为v4l2是被枚举为字符设备 2 内存分配和映射 比如相关数据结构的分配和buffer 3 DMA xff0c 因为v4l2的数据传输用到了DMA 4 I2C xff0c
  • linux串口命令UART,STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为 xff1a 1 使能GPIO口和UART对应的总线时钟 2 配置GPIO口的输出模式 3 配置uart口相关的基本信息 4 使能uart口的相关的中断 xff0c 如接收中断 空闲中断等