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;
}
相关推荐
韦德斯1 天前
嵌入式Linux的RTC读写操作应用
linux·运维·c语言·arm开发·实时音视频
byte轻骑兵1 天前
嵌入式 ARM Linux 系统构成全解:从硬件到应用层层剖析
linux·arm开发·arm·嵌入式开发
思尔芯S2C1 天前
面向未来的智能视觉参考设计与汽车架构,思尔芯提供基于Arm技术的创新方案
arm开发·架构·汽车·iot·fpga原型验证·prototyping·智慧视觉
Eternal-Student2 天前
【docker了解】如何将x86镜像转换为适用于Jetson的ARM镜像
arm开发·docker·容器
不怕犯错,就怕不做2 天前
修复kernel编译栈帧大小异常问题error: the frame size of 1928 bytes is larger than 1024 bytes
linux·arm开发·驱动开发
憧憬一下3 天前
UART硬件介绍
arm开发·嵌入式硬件·串口·嵌入式·linux驱动开发
Petal9909124 天前
UEFI学习笔记(十八):ARM电源管理之PSCI和SCMI概述
arm开发·笔记·学习·uefi
古月居GYH4 天前
一文了解ARM内部架构
arm开发·架构
白书宇4 天前
13.100ASK_T113-PRO RTC实验
linux·arm开发·驱动开发·嵌入式硬件·物联网·硬件工程
简简单单一天吃六顿5 天前
rootfs根文件系统在Linux下制作动态库
linux·服务器·arm开发·iot