ARM day8 (串口输入cmd指令点灯)

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值