uart4.h
#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"
typedef struct{
unsigned int moder;
unsigned int otyper;
unsigned int ospeedr;
unsigned int pupdr;
}gpio_init_t;
typedef enum{
GPIO_RESET,
GPIO_SET,
}status_t;
typedef struct{
char* cmd_arr; //命令符字符串
gpio_t* gpio; //gpio组号
unsigned int pin; //对应的引脚编号
status_t status; //LED灯状态
void (*gpio_write_p)(gpio_t * gpio,unsigned int pin, status_t status);
}cmd_t;
//初始化UART4
void hal_uart4_init();
//led初始化
void hal_led_init();
//发送一个字符
void hal_put_char(const char str);
//发送一个字符串
void hal_put_string(const char * str);
//接收一个字符
char hal_get_char();
//接收一个字符串
char* hal_get_string();
//cmd指令操作
cmd_t* hal_cmd_p(char* temp);
//led灯操作
void gpio_write(gpio_t * gpio,unsigned int pin, status_t status);
//字符串比较
int str_cmp(char* arr1,char* arr2);
//引脚初始化
void hal_gpiox_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);
#endif
uart4.c
#include "uart4.h"
extern void delay_ms(int ms);
cmd_t my_cmd[6] = {
[0] = {
.cmd_arr = "led1on",
.gpio = GPIOE,
.pin = 10,
.status = GPIO_SET,
.gpio_write_p = gpio_write,
},
[1] = {
.cmd_arr = "led1off",
.gpio = GPIOE,
.pin = 10,
.status = GPIO_RESET,
.gpio_write_p = gpio_write,
},
[2] = {
.cmd_arr = "led2on",
.gpio = GPIOF,
.pin = 10,
.status = GPIO_SET,
.gpio_write_p = gpio_write,
},
[3] = {
.cmd_arr = "led2off",
.gpio = GPIOF,
.pin = 10,
.status = GPIO_RESET,
.gpio_write_p = gpio_write,
},
[4] = {
.cmd_arr = "led3on",
.gpio = GPIOE,
.pin = 8,
.status = GPIO_SET,
.gpio_write_p = gpio_write,
},
[5] = {
.cmd_arr = "led3off",
.gpio = GPIOE,
.pin = 8,
.status = GPIO_RESET,
.gpio_write_p = gpio_write,
},
};
//初始化UART4
void hal_uart4_init()
{
/*************RCC*************/
//1.GPIOB使能 MP_AHB4ENSETR[1] = 1
RCC->MP_AHB4ENSETR |= (0x1 << 1);
//2.GPIOG使能 MP_AHB4ENSETR[6] = 1
RCC->MP_AHB4ENSETR |= (0x1 << 6);
//3.UART4使能 MP_APB1ENSETR[16] = 1
RCC->MP_APB1ENSETR |= (0x1 << 16);
/************GPIO*************/
//1.设置 FB2 引脚为复用模式 MODER[5:4] = 10
GPIOB->MODER &= (~(0X3 << 4));
GPIOB->MODER |= (0x2 << 4);
//2.设置 FB2 引脚复用为 UART4_RX AFRL[11:8] = 1000
GPIOB->AFRL &= (~(0xf << 8));
GPIOB->AFRL |= (0x8 << 8);
//1.设置 FG11 引脚为复用模式 MODER[23:22] = 10
GPIOG->MODER &= (~(0X3 << 22));
GPIOG->MODER |= (0X2 << 22);
//2.设置 FG11 引脚复用为 UART4_TX AFRL[15:12] = 1000
GPIOG->AFRL &= (~(0XF << 12));
GPIOG->AFRL |= (0X6 << 12);
/***********UART4*************/
//0.设置串口UE = 0
if(USART4->CR1 & 0x1)
{
delay_ms(500);
USART4->CR1 &= (~0x1);
}
//1.设置1位起始位,8位数据位
USART4->CR1 &= (~(0x1 << 28));
USART4->CR1 &= (~(0x1 << 12));
//2.没有奇偶校验
USART4->CR1 &= (~(0x1 << 10));
//3.设置1位停止位
USART4->CR2 &= (~(0x3 << 12));
//4.设置16倍采样位
USART4->CR1 &= (~(0x1 << 15));
//5.设置串口不分频
USART4->PRESC &= (~0xF);
//6.设置串口波特率为115200
USART4->BRR &= (~0xFFFF);
USART4->BRR |= (0x22B);
//7.设置串口发送器使能
USART4->CR1 |= (0x1 << 3);
//8.设置串口接收器使能
USART4->CR1 |= (0x1 << 2);
//9.设置串口使能
USART4->CR1 |= 0x1;
}
//将3盏灯初始化
void hal_led_init()
{
/**********RCC使能***************/
//RCC_GPIOE,RCC_GPIOF置1 MP_AHB4ENSETR[5:4]
RCC->MP_AHB4ENSETR |= (0x3 << 4);
/***********GPIO初始化***********/
gpio_init_t init = {1,0,0,0};
hal_gpiox_init(GPIOE,10,&init);
hal_gpiox_init(GPIOF,10,&init);
hal_gpiox_init(GPIOE,8,&init);
}
void hal_gpiox_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init)
{
//1.GPIO_MODER
gpiox->MODER &= (~(0x3 << pin*2));
gpiox->MODER |= (init->moder << pin*2);
//2.GPIO_OTYPER
gpiox->OTYPER &= (~(0x1 << pin));
gpiox->OTYPER |= (init->otyper << pin);
//3.GPIO_OSPEEDR
gpiox->OSPEEDR &= (~(0x3 << pin*2));
gpiox->OSPEEDR |= (init->ospeedr << pin*2);
//4.GPIO_PUPDR
gpiox->PUPDR &= (~(0x3 << pin*2));
gpiox->PUPDR |= (init->pupdr << pin*2);
}
//发送一个字符
void hal_put_char(const char str)
{
//1.判断是否为空 ISR[7]
//0为满(堵塞),1为空(发送)
while(!(USART4->ISR & (0x1 << 7)));
//2.将要发送内容赋值寄存器
USART4->TDR = str;
//3.判断一帧数据是否发送完成ISR[6]
//0未完成,1已完成
while(!(USART4->ISR & (0x1 << 6)));
}
//发送一个字符串
void hal_put_string(const char* str)
{
//判断是否为‘\0'
//一个一个字符发送
while(*str)
{
hal_put_char(*str++);
}
hal_put_char('\n');
hal_put_char('\r');
}
//接收一个字符
char hal_get_char()
{
//1.判断接收是否有数据ISR[5]
while(!(USART4->ISR & (0x1 << 5)));
//2.将数据读取
return USART4->RDR;
}
char arr[50] = {0};
//接收一个字符串
char* hal_get_string()
{
//循环接收
int i = 0;
while(1)
{
//'\n'回车表示接收完成
arr[i] = hal_get_char();
hal_put_char(arr[i]);
if(arr[i] == '\r') break;
i++;
}
arr[i] = '\0';
hal_put_char('\n');
return arr;
}
//引脚置位函数
void gpio_write(gpio_t * gpio,unsigned int pin, status_t status)
{
if(status == GPIO_RESET)
gpio->ODR &= (~(0x1 << pin));
else
gpio->ODR |= (0x1 << pin);
}
//cmd指令操作
cmd_t* hal_cmd_p(char* temp)
{
int i = 0;
while(i<6)
{
if(!str_cmp(temp,my_cmd[i].cmd_arr))
return &my_cmd[i];
i++;
}
return 0;
}
int str_cmp(char* arr1,char* arr2)
{
int i=0;
while(arr1[i]!='\0' && arr2[i]!='\0')
{
if(arr1[i] - arr2[i])
{
return arr1[i] - arr2[i];
}
i++;
}
return 0;
}
main.c
#include "uart4.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}
int main()
{
//使能初始化
hal_uart4_init();
hal_led_init();
hal_put_string("UART4 TEXT READY");
while(1)
{
cmd_t* temp ;
temp = hal_cmd_p(hal_get_string());
if(0 != temp)
{
hal_put_string("success to ");
hal_put_string(temp->cmd_arr);
temp->gpio_write_p(temp->gpio,temp->pin,temp->status);
}
else
{
hal_put_string("false");
}
}
return 0;
}