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;
}
相关推荐
szxinmai主板定制专家13 小时前
柔宇柔性显示屏+x86、arm显示解决方案,还有库存
arm开发·人工智能·fpga开发
非凡自我_成功20 小时前
库函数开发控制LED
arm开发·stm32
szxinmai主板定制专家20 小时前
基于x86和ARM的EtherCAT运动控制器,最大支持32轴,支持codesys和实时系统优化
arm开发·人工智能·嵌入式硬件·yolo
凤凰战士芭比Q1 天前
Linux内核(升级、编译)
linux·运维·arm开发
nuoxin1143 天前
GSV1011-富利威-HDMI芯片选型
arm开发·驱动开发·fpga开发·ffmpeg·射频工程
磨十三6 天前
MCU 时钟系统全解析:主时钟、PLL、分频与外设时钟门控
arm开发·单片机·嵌入式硬件
磨十三6 天前
ARM Cortex-M 系列 MCU:内核、指令、异常与中断解析
arm开发·单片机·嵌入式硬件
Leinwin6 天前
微软发布全新一代 Arm 架构云原生处理器 Cobalt 200
arm开发·microsoft·架构
卖芒果的潇洒农民6 天前
Work ARM CPU
arm开发
虚伪的空想家6 天前
arm架构服务器使用kvm创建虚机报错,romfile “efi-virtio.rom“ is empty
linux·运维·服务器·javascript·arm开发·云原生·kvm