1.通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作
例如在串口输入led1on,开饭led1灯点亮
2.例如在串口输入led1off,开饭led1灯熄灭
3.例如在串口输入led2on,开饭led2灯点亮
4.例如在串口输入led2off,开饭led2灯熄灭
5.例如在串口输入led3on,开饭led3灯点亮
6.例如在串口输入led3off,开饭led3灯熄灭
2.编程要求:
1)结构体封装
typedef struct{
char* cmd_arr; //命令行字符串
gpio_t* gpiox;//GPIO组号
unsigned int pin; //引脚编号
status_t status; //LED灯状态
void(*gpio_write_pin)(gpio_t* gpiox,unsigned int pin,status_t status);
}cmd_t;
2)结构体数组
方式1:cmd_t cmd_arr[6] = {{"led1off",GPIOE,GPIO_PIN_10,GPIO_RESET_T},{},};
cmd_t cmd_arr[6] = {
[0] ={ .cmd_arr = "led1off", .gpiox = GPIOE, .pin = GPIO_PIN_10, .status = GPIO_RESET_T, .gpio_write_pin = hal_gpio_write, }, [1] = {}, [2] = {}, };
3)在串口输入一个字符串
1>在串口输入一个字符串,需要定义一个变量接收,串口接收到的字符串 char* string = uart_get_string();
2>串口中输入的字符串,与结构体中每个元素中的cmd_arr变量进行比较
3>如果比较成功,代表查到输入的字符串 思考:函数实现如何编写?
cmd_t* find_command(const char* str) {
//串口中输入的字符串,与结构体中每个元素中的cmd_arr变量进行比较
//遍历比较,自己编写strcmp比较的函数 return 0;
//失败返回0 }
4)思考main.c函数编写
cmd_t* cmd_arr;
char* string = uart_get_string();
cmd_arr = find_command(string);
if(cmd_arr == 0)
{
查找失败
}else {
cmd_arr->gpio_write_pin(cmd_arr->gpiox,...........)
}
头文件
#ifndef __TEST_H__
#define __TEST_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_uart.h"
#include "gpio.h"
typedef struct{
char* cmd_str; //命令行字符串
gpio_t* gpiox; //GPIO组号
unsigned int pin; //引脚编号
gpio_status_t status; //LED灯状态
void(*gpio_write_pin)(gpio_t* gpiox,unsigned int pin,gpio_status_t status);
}cmd_t;
//UART初始化
void uart_init();
//LED初始化
void LED_init(gpio_t* GPIOX,unsigned int PIN);
//发送一个字符
void put_char(const char ch);
//接收一个字符
char get_char();
//发送一个字符串
void put_string(const char* str);
//接收一个字符串
char* get_string();
//点亮LED
void LED_lighting(gpio_t* GPIOX,unsigned int PIN,gpio_status_t status);
//字符串比较函数
int strcmp(const char* string,const char* arr_string);
cmd_t* find_command(const char* str);
#endif
源文件
#include "test.h"
cmd_t cmd_arr[6] = {
[0] ={
.cmd_str = "led1on",
.gpiox = GPIOE,
.pin = gpio_PIN_10,
.status = gpio_set,
.gpio_write_pin = LED_lighting,
},
[1] ={
.cmd_str = "led1off",
.gpiox = GPIOE,
.pin = gpio_PIN_10,
.status = gpio_reset,
.gpio_write_pin = LED_lighting,
},
[2] ={
.cmd_str = "led2on",
.gpiox = GPIOF,
.pin = gpio_PIN_10,
.status = gpio_set,
.gpio_write_pin = LED_lighting,
},
[3] ={
.cmd_str = "led2off",
.gpiox = GPIOF,
.pin = gpio_PIN_10,
.status = gpio_reset,
.gpio_write_pin = LED_lighting,
},
[4] ={
.cmd_str = "led3on",
.gpiox = GPIOE,
.pin = gpio_PIN_8,
.status = gpio_set,
.gpio_write_pin = LED_lighting,
},
[5] ={
.cmd_str = "led3off",
.gpiox = GPIOE,
.pin = gpio_PIN_8,
.status = gpio_reset,
.gpio_write_pin = LED_lighting,
}
};
//UART初始化
void uart_init(){
//RCC_AHB4ENSETR
RCC->MP_AHB4ENSETR |= (0x1<<1); //GPIOB使能
RCC->MP_AHB4ENSETR |= (0x1<<6); //GPIOG使能
//RCC_APB1ENSETR
RCC->MP_APB1ENSETR |= (0x1<<16); //UART4使能
//GPIOB
GPIOB->MODER &= (~(0x3<<4)); //GPIOB_MODER设置复用功能模式
GPIOB->MODER |= (0x1<<5);
GPIOB->AFRL &= (~(0xf<<8)); //设置GPIOB引脚功能复用模式
GPIOB->AFRL |= (0x1<<11);
//GPIOG
GPIOG->MODER &= (~(0x3<<22)); //GPIOG_MODER设置复用功能模式
GPIOG->MODER |= (0x1<<23);
GPIOG->AFRH &= (~(0xf<<12)); //设置GPIOG引脚功能复用模式
GPIOG->AFRH |= (0x3<<13);
//uart初始化
USART4->CR1 &= (~(0x1<<0)); //判断UE是否等于0
USART4->CR1 &= (~(0x1<<12));
USART4->CR1 &= (~(0x1<<28)); //设置数据位宽度为8位
USART4->CR2 &= (~(0x3<<12)); //设置1位停止位
USART4->CR1 &= (~(0x1<<15)); //设置16倍采样率
USART4->CR1 &= (~(0x1<<10)); //设置串口无奇偶位
USART4->BRR = 0x22B;
USART4->CR1 &= (~(0x1<<3));
USART4->CR1 |= (0x1<<3); //发送使能
USART4->CR1 &= (~(0x1<<2));
USART4->CR1 |= (0x1<<2); //接收器使能
USART4->PRESC &= (~(0xf<<0)); //一级分配
USART4->CR1 |= (0x1<<0); //UART使能
}
//LED初始化
void LED_init(gpio_t* GPIOX,unsigned int PIN){
//RCC_AHB4ENSETR
if(GPIOX == GPIOE){
RCC->MP_AHB4ENSETR |= (0x1<<4); //GPIOE使能
}else{
RCC->MP_AHB4ENSETR |= (0x1<<5); //GPIOF使能
}
//GPIOX
GPIOX->MODER &= (~(0x3<<(PIN*2))); //设置输出模式
GPIOX->MODER |= (0x1<<(PIN*2));
GPIOX->OTYPER &= (~(0x1<<PIN)); //设置推挽输出
GPIOX->OSPEEDR &= (~(0x3<<(PIN*2))); //设置低速输出模式
GPIOX->PUPDR &= (~(0x3<<(PIN*2))); //设置禁止上下拉电阻
}
//发送一个字符
void put_char(const char ch){
//判断发送寄存器是否为空
while(!(USART4->ISR & (0x1<<7)));
//将数据放入发送寄存器中
USART4->TDR = ch;
//如果字符是\n,则再发送一个回车\r
if(ch == '\n'){
while(!(USART4->ISR & (0x1<<7)));
USART4->TDR = '\r';
}
//判断一帧数据是否发送成功
while(!(USART4->ISR & (0x1<<6)));
}
//接收一个字符
char get_char(){
char ch;
//判断接收数据寄存器是否为空
while(!(USART4->ISR & (0x1<<5)));
//将接收到的数据放入接收数据寄存器中
ch = USART4->RDR;
return ch;
}
//发送一个字符串
void put_string(const char* str){
//循环发送字符
for(int i=0; str[i]!='\0'; i++){
put_char(str[i]);
}
put_char('\n');
put_char('\r');
}
char buf[50]={0};
//接收一个字符串
char* get_string(){
int i = 0;
for(i=0; (buf[i]=get_char()) != '\r';i++){
put_char(buf[i]);
}
buf[i]='\0';
put_char('\n');
put_char('\r');
return buf;
}
//点亮LED
void LED_lighting(gpio_t* GPIOX,unsigned int PIN,gpio_status_t status){
if(status == gpio_set){ //如果num=1,则点亮灯
GPIOX->ODR |= (0x1<<PIN);
}else{ //否则熄灭灯
GPIOX->ODR &= (~(0x1<<PIN));
}
}
//字符串比较函数
int strcmp(const char* string,const char* arr_string){
while((*string != '\0') && (*arr_string != '\0')){
if(*string > *arr_string){
return *string-*arr_string;
}else if(*string < *arr_string){
return *string-*arr_string;
}
string++;
arr_string++;
}
return 0;
}
cmd_t* find_command(const char* str){
for(int i=0; i<6;i++){
if(strcmp(str,cmd_arr[i].cmd_str)==0){
return &cmd_arr[i];
}
}
return 0;
}
main.c
#include "test.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()
{
//初始化UART
uart_init();
//初始化LED1
LED_init(GPIOE,10);
//初始化LED2
LED_init(GPIOF,10);
//初始化LED3
LED_init(GPIOE,8);
put_string("UART AND LED TEST!!!");
while(1)
{
cmd_t* cmd_p;
char* string = get_string();
cmd_p = find_command(string); //让接收到的字符串进行比较
if(cmd_p == 0){
printf("输入错误\n");
}else{
cmd_p->gpio_write_pin(cmd_p->gpiox,cmd_p->pin,cmd_p->status);
}
}
return 0;
}
运行结果