7.1 ARM cortex-A7 UART4

cpp 复制代码
#include "include/uart4.h"

void delay_ms(int ms) {
	for (int i = 0; i < ms; i++)
		for (int j = 0; j < 1000; j++);
}



int main() {
	hal_uart4_init();
	while (1)
		hal_string_put(hal_string_get());
	return 0;
}
cpp 复制代码
#ifndef __UART4_H__
#define __UART4_H__

#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit)
#define GET_BYTE(x, byte) (x & (0xFF << (8 * byte)) >> (8 * byte))


// RCC / GPIO / UART4 初始化
void hal_uart4_init();
// 发送一个字符
void hal_char_put(const char ch);
// 发送一个字符串
void hal_string_put(const char* str);
// 接收一个字符
char hal_char_get();
// 接收一个字符串
char* hal_string_get();


#endif
cpp 复制代码
#include "../include/uart4.h"
#include "../include/stm32mp1xx_gpio.h"
#include "../include/stm32mp1xx_rcc.h"
#include "../include/stm32mp1xx_uart.h"
// UART4_RX => PB2
// UART4_TX => PG11

extern void delay_ms(int ms);

/**
 * @brief RCC && GPIO && UART4 初始化
 *
 */
void hal_uart4_init() {
	/*********** RCC初始化 ***********/
	// 1. 使能GPIOB、G组时钟 RCC_MP_AHB4ENSETR[6,1] = 1
	RCC->MP_AHB4ENSETR |= 0x21 << 1;
	// 2. 使能UART4组时钟 RCC_MP_APB1ENSETR[16] = 1
	RCC->MP_APB1ENSETR |= 0x1 << 16;

	/*********** GPIO初始化 ***********/
	// 1. 设置PG11为复用功能模式
	GPIOG->MODER &= ~(0x3 << 22);
	GPIOG->MODER |= 0x2 << 22;
	// 2. 设置PB2为复用功能模式
	GPIOB->MODER &= ~(0x3 << 4);
	GPIOB->MODER |= 0x2 << 4;
	// 3. 设置PG11的复用功能为UART4_TX
	GPIOG->AFRH &= ~(0xF << 12);
	GPIOG->AFRH |= 0x6 << 12;
	// 4. 设置PB2的复用功能为UART4_RX
	GPIOB->AFRL &= ~(0xF << 8);
	GPIOB->AFRL |= 0x8 << 8;

	/*********** UART4初始化 ***********/
	// 1. 使UE、RE、TE失能,以便于初始化:
	if (USART4->CR1 & 0x1) {
		delay_ms(500);
		USART4->CR1 &= ~(0x1);
	}
	// 2. CR1寄存器的M、OVER8、PCE;
	// 1) M[1:0] = 00,1位起始位,8位数据位
	USART4->CR1 &= ~(0x1 << 28);
	USART4->CR1 &= ~(0x1 << 12);
	// 2) OVER8 = 0,16倍超采样
	USART4->CR1 &= ~(0x1 << 15);
	// 3) PCE = 0,无校验位
	USART4->CR1 &= ~(0x1 << 10);

	// 2. BRR寄存器的BRR;
	  // 1) BRR[15:0] = 0x160A,串口波特率115200Bps
	USART4->BRR &= ~(0xFFFF);
	USART4->BRR |= 0x22B;

	// 3. CR2寄存器的STOP;
	// 1) STOP[1:0] = 00,1位停止位
	USART4->CR2 &= ~(0x3 << 12);

	// 4. PRESC寄存器的PRESCALER;
	// 1) PRESCALER[3:0] = 0000,不分频
	USART4->PRESC &= ~(0xF);

	// 5. 使能UE、TE、RE开启串口收发
	USART4->CR1 |= 0xD;
}

/**
 * @brief 发送一个字符
 *
 * @param ch
 */
void hal_char_put(const char ch) {
	while (!GET_BIT(USART4->ISR, 7));
	USART4->TDR = ch;
	while (!GET_BIT(USART4->ISR, 6));
}

/**
 * @brief 发送一个字符串
 *
 * @param str
 */
void hal_string_put(const char* str) {
	while (*str)
		hal_char_put(*str++);
	hal_char_put('\r');
	hal_char_put('\n');
}

/**
 * @brief 接收一个字符
 *
 * @return char
 */
char hal_char_get() {
	while (!GET_BIT(USART4->ISR, 5));
	return USART4->RDR;
}

/**
 * @brief 接收一个字符串
 *
 * @return char*
 */
char* hal_string_get() {
	static char buf[128];
	for (int i = 0; i < sizeof(buf); i++)
		buf[i] = 0;
	int i;
	for (i = 0; i < 126; i++) {
		buf[i] = hal_char_get();
		hal_char_put(buf[i]);
		if (buf[i] == '\b') {
			hal_char_put(' ');
			hal_char_put('\b');
			buf[i--] = '\0';
			buf[i--] = '\0';
		}
		else if (buf[i] == '\r')
			break;
	}
	buf[i] = '\0';
	hal_char_put('\n');
	return buf;
}
相关推荐
一个学Java小白17 小时前
ARM-Linux 完全入门
linux·运维·arm开发
MaoXian_n2 天前
[IMX] 05.串口 - UART
汇编·arm开发·驱动开发·单片机·嵌入式硬件
notion20252 天前
Keil MDK-ARM与C51双环境安装指南(2023最新版)
arm开发·其他
亿道电子Emdoor2 天前
【Arm】应用ArmDS移植最小FreeRTOS系统
arm开发·arm
半吊子全栈工匠2 天前
智能体间协作的“巴别塔困境“如何破解?解读Agent通信4大协议:MCP/ACP/A2A/ANP
arm开发
交叉编译之王 hahaha3 天前
OpenHarmony 5.1.0 Release目录结构详细解析(3级目录)
arm开发·华为·harmonyos
{⌐■_■}5 天前
【go】binary包,大小端理解,read,write使用,自实现TCP封包拆包案例
arm开发·tcp/ip·golang
亿道电子Emdoor5 天前
【ARM】MDK如何将变量存储到指定内存地址
arm开发·stm32·单片机
nuoyigui98895 天前
keil 解决 Error: CreateProcess failed, Command: ‘XXX\ARM\ARMCC\bin\fromelf.exe
arm开发
charlie1145141916 天前
基于Qt6 + MuPDF在 Arm IMX6ULL运行的PDF浏览器——MuPDF Adapter文档
arm开发·qt·学习·pdf·教程·设计·qt6