STM32F7xx —— 串口通信

                            STM32F7xx —— 串口通信

 

目录

STM32F7xx —— 串口通信

一、串口初始化过程

二、几个重要的串口函数

三、几个重要的结构

四、基本接口设计


一、串口初始化过程

1、时钟使能;

2、GPIO初始化;

3、串口波特率设置;

4、串口控制;

5、数据发送与接收

 

二、几个重要的串口函数

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); // 串口初始化HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); // 串口发送HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); // 串口接收__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)  // 串口中断使能void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority); // 设置中断优先级void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); // 使能中断

三、几个重要的结构

// 串口初始化结构体 包含了串口句柄 波特率配置 发送接收缓存 dma等
// 我们只描述前两个基本功能,对效率要求极高可以使用DMA。
typedef struct
{USART_TypeDef            *Instance;        /*!< UART registers base address        */UART_InitTypeDef         Init;             /*!< UART communication parameters      */UART_AdvFeatureInitTypeDef AdvancedInit;   /*!< UART Advanced Features initialization parameters */uint8_t                  *pTxBuffPtr;      /*!< Pointer to UART Tx transfer Buffer */uint16_t                 TxXferSize;       /*!< UART Tx Transfer size              */uint16_t                 TxXferCount;      /*!< UART Tx Transfer Counter           */uint8_t                  *pRxBuffPtr;      /*!< Pointer to UART Rx transfer Buffer */uint16_t                 RxXferSize;       /*!< UART Rx Transfer size              */uint16_t                 RxXferCount;      /*!< UART Rx Transfer Counter           */uint16_t                 Mask;             /*!< UART Rx RDR register mask          */DMA_HandleTypeDef        *hdmatx;          /*!< UART Tx DMA Handle parameters      */DMA_HandleTypeDef        *hdmarx;          /*!< UART Rx DMA Handle parameters      */HAL_LockTypeDef           Lock;            /*!< Locking object                     */__IO HAL_UART_StateTypeDef    gState;      /*!< UART state information related to global Handle management and also related to Tx operations.This parameter can be a value of @ref HAL_UART_StateTypeDef */__IO HAL_UART_StateTypeDef    RxState;     /*!< UART state information related to Rx operations.This parameter can be a value of @ref HAL_UART_StateTypeDef */__IO uint32_t             ErrorCode;   /*!< UART Error code                    */}UART_HandleTypeDef;
// 串口的操作句柄 如 USART1 USART2 USART3等
typedef struct
{__IO uint32_t CR1;    /*!< USART Control register 1,                 Address offset: 0x00 */ __IO uint32_t CR2;    /*!< USART Control register 2,                 Address offset: 0x04 */ __IO uint32_t CR3;    /*!< USART Control register 3,                 Address offset: 0x08 */__IO uint32_t BRR;    /*!< USART Baud rate register,                 Address offset: 0x0C */                                               __IO uint32_t GTPR;   /*!< USART Guard time and prescaler register,  Address offset: 0x10 */__IO uint32_t RTOR;   /*!< USART Receiver Time Out register,         Address offset: 0x14 */  __IO uint32_t RQR;    /*!< USART Request register,                   Address offset: 0x18 */__IO uint32_t ISR;    /*!< USART Interrupt and status register,      Address offset: 0x1C */__IO uint32_t ICR;    /*!< USART Interrupt flag Clear register,      Address offset: 0x20 */__IO uint32_t RDR;    /*!< USART Receive Data register,              Address offset: 0x24 */__IO uint32_t TDR;    /*!< USART Transmit Data register,             Address offset: 0x28 */
} USART_TypeDef;
// 设置串口的各个参数 波特率 字长 停止位 奇偶校验 收发模式 硬件流 过采样
// 字长:8位/9位
// 停止位:1位/2位
typedef struct
{uint32_t BaudRate;                  /*!< This member configures the UART communication baud rate.The baud rate register is computed using the following formula:- If oversampling is 16 or in LIN mode,Baud Rate Register = ((PCLKx) / ((huart->Init.BaudRate)))- If oversampling is 8,Baud Rate Register[15:4] = ((2 * PCLKx) / ((huart->Init.BaudRate)))[15:4]Baud Rate Register[3] =  0Baud Rate Register[2:0] =  (((2 * PCLKx) / ((huart->Init.BaudRate)))[3:0]) >> 1      */uint32_t WordLength;                /*!< Specifies the number of data bits transmitted or received in a frame.This parameter can be a value of @ref UARTEx_Word_Length */uint32_t StopBits;                  /*!< Specifies the number of stop bits transmitted.This parameter can be a value of @ref UART_Stop_Bits */uint32_t Parity;                    /*!< Specifies the parity mode.This parameter can be a value of @ref UART_Parity@note When parity is enabled, the computed parity is insertedat the MSB position of the transmitted data (9th bit whenthe word length is set to 9 data bits; 8th bit when theword length is set to 8 data bits). */uint32_t Mode;                      /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.This parameter can be a value of @ref UART_Mode */uint32_t HwFlowCtl;                 /*!< Specifies whether the hardware flow control mode is enabledor disabled.This parameter can be a value of @ref UART_Hardware_Flow_Control */uint32_t OverSampling;              /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).This parameter can be a value of @ref UART_Over_Sampling */uint32_t OneBitSampling;            /*!< Specifies whether a single sample or three samples' majority vote is selected.Selecting the single sample method increases the receiver tolerance to clockdeviations. This parameter can be a value of @ref UART_OneBit_Sampling */
}UART_InitTypeDef;

四、基本接口设计

我们使用中断接收,普通发送。中断接收到的数据放入队列中,在外部可配置每路串口的功能。

// 抽象出一个串口设备结构体
typedef struct
{UART_HandleTypeDef handle; // 串口句柄uart_queue_t recv;         // 接收队列uart_queue_t send;         // 发送队列uint8_t ret;               // 接收的值
} uart_dev_t;static uart_dev_t uart1_dev;
static uart_dev_t uart2_dev;
// 对外只有通道 不再包含USART1...
typedef enum
{UART_CHANNEL_NONE,UART_CHANNEL_1,UART_CHANNEL_2,UART_CHANNEL_NUM
} uart_channel_t;// 宏定义串口的基本信息 之所以这样写,方便移植修改
#define UART1_CHANNEL             USART1
#define UART1_PREEMPT_PRIO        UART1_PRIORITY
#define UART1_IRQ                 USART1_IRQn
#define UART1_IRQ_FUNC            USART1_IRQHandler
#define UART1_CLK_ENABLE()        __HAL_RCC_USART1_CLK_ENABLE()
#define UART1_TX_PORT             GPIOA
#define UART1_TX_PIN              GPIO_PIN_10
#define UART1_TX_AF               GPIO_AF7_USART1
#define UART1_TX_CONFIG()         GPIOConfigExt(UART1_TX_PORT, UART1_TX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, UART1_TX_AF)
#define UART1_RX_PORT             GPIOA
#define UART1_RX_PIN              GPIO_PIN_9
#define UART1_RX_AF               GPIO_AF7_USART1
#define UART1_RX_CONFIG()         GPIOConfigExt(UART1_RX_PORT, UART1_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, UART1_RX_AF)#define UART2_CHANNEL             USART2
#define UART2_PREEMPT_PRIO        UART2_PRIORITY
#define UART2_IRQ                 USART2_IRQn
#define UART2_IRQ_FUNC            USART2_IRQHandler
#define UART2_CLK_ENABLE()        __HAL_RCC_USART2_CLK_ENABLE()
#define UART2_TX_PORT             GPIOA
#define UART2_TX_PIN              GPIO_PIN_2
#define UART2_TX_AF               GPIO_AF7_USART2
#define UART2_TX_CONFIG()         GPIOConfigExt(UART2_TX_PORT, UART2_TX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, UART2_TX_AF)
#define UART2_RX_PORT             GPIOA
#define UART2_RX_PIN              GPIO_PIN_3
#define UART2_RX_AF               GPIO_AF7_USART2
#define UART2_RX_CONFIG()         GPIOConfigExt(UART2_RX_PORT, UART2_RX_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, UART2_RX_AF)
// 串口的基本操作 
// 串口1
static void uart1_var_init(void)
{uart1_dev.recv = uart1_queue_recv;uart1_dev.send = uart1_queue_send;UartQueueInit(&uart1_dev.recv);UartQueueInit(&uart1_dev.send);
}static void uart1_gpio_init(void)
{UART1_RX_CONFIG();UART1_TX_CONFIG();
}static void uart1_mode_init(uint32_t bound)
{UART1_CLK_ENABLE();uart1_dev.handle.Instance = UART1_CHANNEL;uart1_dev.handle.Init.BaudRate = bound;                // 波特率uart1_dev.handle.Init.WordLength = UART_WORDLENGTH_8B; // 字长为8位数据格式uart1_dev.handle.Init.StopBits = UART_STOPBITS_1;      // 一个停止位uart1_dev.handle.Init.Parity = UART_PARITY_NONE;       // 无奇偶校验位uart1_dev.handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控uart1_dev.handle.Init.Mode = UART_MODE_TX_RX;          // 收发模式HAL_UART_Init(&uart1_dev.handle);                      // HAL_UART_Init()会使能UART1
}static void uart1_nvic_init(void)
{HAL_NVIC_SetPriority(UART1_IRQ, UART1_PREEMPT_PRIO, 3);HAL_NVIC_EnableIRQ(UART1_IRQ);__HAL_UART_ENABLE_IT(&uart1_dev.handle, UART_IT_RXNE);
}// 串口2
static void uart2_var_init(void)
{uart2_dev.recv = uart2_queue_recv;uart2_dev.send = uart2_queue_send;UartQueueInit(&uart2_dev.recv);UartQueueInit(&uart2_dev.send);
}static void uart2_gpio_init(void)
{UART2_RX_CONFIG();UART2_TX_CONFIG();
}static void uart2_mode_init(uint32_t bound)
{UART2_CLK_ENABLE();uart2_dev.handle.Instance = UART2_CHANNEL;uart2_dev.handle.Init.BaudRate = bound;uart2_dev.handle.Init.WordLength = UART_WORDLENGTH_8B;uart2_dev.handle.Init.StopBits = UART_STOPBITS_1;uart2_dev.handle.Init.Parity = UART_PARITY_NONE;uart2_dev.handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;uart2_dev.handle.Init.Mode = UART_MODE_TX_RX;HAL_UART_Init(&uart2_dev.handle);
}static void uart2_nvic_init(void)
{HAL_NVIC_EnableIRQ(UART2_IRQ);HAL_NVIC_SetPriority(UART2_IRQ, UART2_PREEMPT_PRIO, 1);__HAL_UART_ENABLE_IT(&uart2_dev.handle, UART_IT_RXNE);
}
// 抽象出一个初始化的结构体 每个串口都有的操作
// 定义一个串口的列表
// 下面的函数就是扫描列表 到这里为止,这些接口都是给内部使用的,外部文件用不到。
typedef struct
{uint8_t channel;uart_dev_t *dev;void (* var_init_cb)(void);void (* gpio_init_cb)(void);void (* mode_init_cb)(uint32_t bound);void (* nvic_init_cb)(void);
} uart_config_t;static const uart_config_t uart_configs[] =
{{UART_CHANNEL_1, &uart1_dev, uart1_var_init, uart1_gpio_init, uart1_mode_init, uart1_nvic_init},{UART_CHANNEL_2, &uart2_dev, uart2_var_init, uart2_gpio_init, uart2_mode_init, uart2_nvic_init},
};static uart_dev_t *uart_dev_get(uint8_t channel)
{uint8_t i;for(i = 0; i < ARRAY_SIZE(uart_configs); ++i){if(uart_configs[i].channel == channel){return uart_configs[i].dev;}}return 0;
}static void uart_var_init(uint8_t channel)
{uint8_t i;for(i = 0; i < ARRAY_SIZE(uart_configs); ++i){if(uart_configs[i].channel == channel){uart_configs[i].var_init_cb();break;}}
}static void uart_gpio_init(uint8_t channel)
{uint8_t i;for(i = 0; i < ARRAY_SIZE(uart_configs); ++i){if(uart_configs[i].channel == channel){uart_configs[i].gpio_init_cb();break;}}
}static void uart_mode_init(uint8_t channel, uint32_t bound)
{uint8_t i;for(i = 0; i < ARRAY_SIZE(uart_configs); ++i){if(uart_configs[i].channel == channel){uart_configs[i].mode_init_cb(bound);break;}}
}static void uart_nvic_init(uint8_t channel)
{uint8_t i;for(i = 0; i < ARRAY_SIZE(uart_configs); ++i){if(uart_configs[i].channel == channel){uart_configs[i].nvic_init_cb();break;}}
}
// 这里的函数就是非常重要的了,都是给外部使用的。
// 初始化函数,同步发送 异步发送 接收处理
void UartInit(uint8_t channel, uint32_t bound)
{uart_var_init(channel);uart_gpio_init(channel);uart_mode_init(channel, bound);uart_nvic_init(channel);
}void UartSendSync(uint8_t channel, uint8_t *buffer, uint16_t length)
{uart_dev_t *dev = uart_dev_get(channel);HAL_UART_Transmit(&dev->handle, buffer, length, 10);
}void UartSendWriteAsyn(uint8_t channel, uint8_t *buffer, uint16_t length)
{uint16_t i;uart_dev_t *dev = uart_dev_get(channel);if(0 == dev){return;}for(i = 0; i < length; ++i){UartQueuePush(&dev->send, buffer[i]);}
}uint8_t UartSendReadAsyn(uint8_t channel, uint8_t *c)
{uart_dev_t *dev = uart_dev_get(channel);if(0 == dev){return 0;}return UartQueuePop(&dev->send, c);
}uint8_t UartRecv(uint8_t channel, uint8_t *c)
{uart_dev_t *dev = uart_dev_get(channel);return UartQueuePop(&dev->recv, c);
}
// 这里我没有使用串口的回调函数。
// 中断服务函数 接收到数据就加入到队列中。在UartRecv读队列数据并处理。
void UART1_IRQ_FUNC(void)
{if(__HAL_UART_GET_IT(&uart1_dev.handle, UART_IT_RXNE) != RESET){HAL_UART_Receive(&uart1_dev.handle, (uint8_t *)&uart1_dev.ret, 1, 1000);UartQueuePush(&uart1_dev.recv, uart1_dev.ret);}HAL_UART_IRQHandler(&uart1_dev.handle);
}void UART2_IRQ_FUNC(void)
{if(__HAL_UART_GET_IT(&uart2_dev.handle, UART_IT_RXNE) != RESET){HAL_UART_Receive(&uart2_dev.handle, (uint8_t *)&uart2_dev.ret, 1, 1000);UartQueuePush(&uart2_dev.recv, uart2_dev.ret);}HAL_UART_IRQHandler(&uart2_dev.handle);
}

到这里,串口的初始化,发送,接收的接口就封装好了。

裸机:裸机就在while(1)中调用UartRecv扫描数据;

系统:带系统就在任务中扫描并解析数据。(带系统可以使用信号量去同步数据 -- 这里只提出一种思路)

串口队列可参考:串口队列

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个跳楼博士生的遗书:这个世界是一沟绝望的死水

o(︶︿︶)o 唉北邮跳楼博士生给母亲堵塞遗书&#xff1a;这个世界是一沟绝望的死水 这个世界是一沟绝望的死水&#xff0c;我在这里再怎么折腾也激不起半点涟漪。所有的努力都会被既得利益集团踩在脚下&#xff0c;所有的奋斗都面临着举步维艰。冷漠的人&#xff0c;谢谢你…

jquery插件课程1 幻灯片、城市选择、日期时间选择、拖放、方向拖动插件

jquery插件课程1 幻灯片、城市选择、日期时间选择、拖放、方向拖动插件 一、总结 一句话总结&#xff1a;都是jquery插件&#xff0c;都还比较小&#xff0c;参数&#xff08;配置参数、数据&#xff09;一般都是通过json传递。 1、插件配置数据或者参数的时候用的是什么数据结…

由c语言转向c++,我们需要做什么?

点击上方蓝字添加关注在此送大家一份小礼物&#xff0c;公众号内回复linux0001即可获得一本Linux电子教程“c语言和c到底有什么不同和联系呢&#xff1f;”毫无疑问&#xff0c;c语言和c是两种不同的语言&#xff0c;但是又有着千丝万缕的联系。语法上c语言与c一脉相承&#xf…

黄聪:【强烈推荐】搜索引擎排名决定一切吗!

在点石看到一篇《搜索引擎排名决定一切么》&#xff0c;作者cqqc626。写的太赞的&#xff0c;Kyw看后都有点激动&#xff0c;希望天下所有要需要SEO服务的客户们&#xff0c;都能明白其中道理&#xff0c;明白排名不是一切。正文如下&#xff1a; 前段时间经常看到很多和自己差…

STM32F7xx —— CAN通信

STM32F7xx —— CAN通信 目录 STM32F7xx —— CAN通信 一、CAN基础 二、几个重要的CAN函数 三、几个重要的结构 四、接口设计 一、CAN基础 差分信号&#xff1a;显性电平对应逻辑0&#xff0c;CAN_H和CAN_L差为2.5V&#xff1b;隐形电平对应逻辑1&#xff0c;CAN_H和CAN_…

[leetcode] 14. 最长公共前缀

14. 最长公共前缀 超级简单。。。 class Solution { public:string longestCommonPrefix(vector<string> &strs) {if (strs.size() 0) {return "";}string common strs[0];for (int i 1; i < strs.size(); i) {common findCommon(strs[i], common);…

Cmake确实应该用到的时候再学

最近在做项目用到Cmake相关的知识&#xff0c;之前做的是BSP驱动开发&#xff0c;基本用不到Cmake&#xff0c;唯一和Cmake有交集的应该是我们移植网关项目&#xff0c;不过也只是修修改改&#xff0c;直到最近用到Cmake开发项目&#xff0c;才真正是接触了这个东西。前天加载一…

手机吞吃蛇游戏的设计与开发

为什么80%的码农都做不了架构师&#xff1f;>>> J2ME(Java 2 Micro Edition) 是近年来随着各种不同设备&#xff0c;尤其是移动通信设备的飞速发展而诞生的一项新的开发技术。它定位在消费性电子产品的应用上&#xff0c;对设备的智能化、www.21cnlunwen.com Write…

STM32F7xx —— 内部flash

STM32F7xx —— 内部flash 这个就没什么好说的了&#xff0c;直接上代码了&#xff0c;主要封装了三个函数&#xff0c;擦除&#xff0c;写flash&#xff0c;读flash。 // STM32F767IGT6: 1M flash // STM32F767ZIT6: 2M flash #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x…

深入理解 Vue Computed 计算属性

Computed 计算属性是 Vue 中常用的一个功能&#xff0c;我们今天来说一下他的执行过长 拿官网简单的例子来看一下&#xff1a; <div id"example"><p>Original message: "{{ message }}"</p><p>Computed reversed message: "{…

vscode 使用 ssh 登录

// 执行 // 使用你自己的服务器IP与登录账户 export USER_AT_HOST"服务器账户名服务器IP" // PUBKEYPATH是你公钥的路径 export PUBKEYPATH"$HOME/.ssh/id_rsa.pub"ssh-copy-id -i "$PUBKEYPATH" "$USER_AT_HOST"

SNMP4J的一点缺陷

最近在使用SNMP4J的过程中发现一个缺陷&#xff0c;不知道应不应该算是个bug&#xff0c;但我想终究算是一个不完善的地方。 问题描述如下&#xff1a; 在通过SNMP4J去获取某些交换机上的MAC地址转发表(dot1dTpFdbTable, OID为1.3.6.1.2.1.17.4.3&#xff09;时&#xff0c;发现…

3-3 数数字

算法入门经典 P57 把前n&#xff08;n<100000&#xff09;个整数顺序写在一起&#xff0c;123456789...数一数0-9各出现多少次。 #include<stdio.h>#include<string.h>#include "stdafx.h"#include "iostream" #include <string&…

如何用示波器测量串口波特率

这是前段时间遇到的问题&#xff0c;刚好这里找到了答案&#xff0c;记录下分享给大家。如何确定时基假如要测量的波特率为9600, 则每一比特位的时间为&#xff1a;1/9600 ≈ 104 μs&#xff0c;一般示波器横向上每个大格子里5个小格子&#xff0c;要想看清一比特位一般需要一…

STM32F7xx —— ADC

STM32F7xx —— ADC 基础知识参考&#xff1a;ADC /***************************************************************************** * ADC1 ADC2 ADC3 * 通道0 PA0 PA0 PA0 * 通道1 PA1 PA1 PA1 * 通道2 PA2 PA2 …

一键了结CUP100%问题

1、dllhost进程造成CPU使用率占用100%<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />服务器正常CPU消耗应该在75%以下&#xff0c;而且CPU消耗应该是上下起伏的&#xff0c;出现这种问题的服务器&#xff0c;CPU会突然一直处10…

Linux内核工程师是怎么步入内核殿堂的?

上图是公众号冠名参加的篮球赛对我来说&#xff0c;要搞好Linux内核&#xff0c;首先要做的就是买一块Linux开发板&#xff0c;然后就使劲捣鼓。下面是一位大神对于入门Linux内核的看法。以下的「我」不是公众号作者作者&#xff1a;Coly Lihttps://www.zhihu.com/question/304…

Newtonsoft.Json 获取匿名类数据

很简单。 1 using System;2 using System.Collections.Generic;3 4 namespace Test5 {6 class Program7 {8 9 static string Message "{\"Result\":0,\"ErrMsg\":\"执行失败。索引超出范围。必须为非负值并小于集合大小。\r\n参…

STM32F7xx —— Timer

STM32F7xx —— Timer 目录 STM32F7xx —— Timer 一、基础定时器配置 二、带回调定时器 作用&#xff1a;输出PWM&#xff0c;测量脉冲长度&#xff0c;定时等。 一、基础定时器配置 // 基本定时器 #define TIMER_CHANNEL TIM3 #define TIMER_PREEMPT_PRIO…

jquery-autocomplete学习(转)

jquery-autocomplete学习 一、用前必备官方网站&#xff1a;http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/当前版本&#xff1a;1.0.2需要JQuery版本&#xff1a;1.2.6 二、使用<script src"./jquery-1.3.2.js" type"text/javascript&q…