结构体封装自定义命令,串口输入相应的命令,控制LED灯进行工作

1.通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作--->上传CSDN
    1.例如在串口输入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,...........)      
        }

uk.h代码如下:

#ifndef __UART4__H__
#define __UART4__H__

#include "gpio.h"

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"

typedef struct{
     char* cmd_arr; //命令行字符串
     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;


cmd_t* find_command(const char* str);


//串口初始化
void uk_init();

//发送一个字符
void put_char(const char str);

//发送一个字符串
void put_string(const char *str);

//接受一个字符
char get_char();

//接受一个字符串
char *get_string();


int strcmp(const char* str1,const char* str2);
void led1_on();
void led1_off();

void led2_on();
void led2_off();

void led3_on();
void led3_off();

#endif

uk.c

#include "uk.h"
extern void delay_ms(int ms);
//串口初始化
void uk_init()
{
    /**************************RCC章节初始化********************/
    
    //使能GPIOE组控制器
    RCC->MP_AHB4ENSETR |= (0x1<<4);

    //使能GPIOF组控制器
    RCC->MP_AHB4ENSETR |= (0x1<<5);

    //使能GPIOB组控制器    
    RCC->MP_AHB4ENSETR &=(~(0x1<<1));
    RCC->MP_AHB4ENSETR |=(0x1<<1);
    
    //使能GPIOG组控制器
    RCC->MP_AHB4ENSETR &=(~(0x1<<6));
    RCC->MP_AHB4ENSETR |=(0x1<<6);
    
    //使能UART4组控制器
    RCC->MP_APB1ENSETR &=(~(0x1<<16));
    RCC->MP_APB1ENSETR |=(0x1<<16);

    /*********************GPIO章节初始化***********************/
    //设置GPIOE_MODER寄存器为输出模式
    GPIOE->MODER &= (~(0x3<<20));
    GPIOE->MODER |= (0x1<<20);

    //设置GPIOF_MODER寄存器为输出模式
    GPIOF->MODER &= (~(0x3<<20));
    GPIOF->MODER |= (0x1<<20);
    
    //设置GPIOE_MODER寄存器为输出模式
    GPIOE->MODER &= (~(0x3<<16));
    GPIOE->MODER |= (0x1<<16);

    //设置GPIOE_OTYPER寄存器为推挽输出模式
    GPIOE->OTYPER &= (~(0x1<<10));

    //设置GPIOF_OTYPER寄存器为推挽输出模式
    GPIOF->OTYPER &= (~(0x1<<10));

    //设置GPIOE_OTYPER寄存器为推挽输出模式
    GPIOE->OTYPER &= (~(0x1<<8));

    //设置GPIOE_OSPEEDR寄存器为低速输出模式
    GPIOE->OSPEEDR &= (~(0x3<<20));

    //设置GPIOE_OSPEEDR寄存器为低速输出模式
    GPIOF->OSPEEDR &= (~(0x3<<20));

    //设置GPIOE_OSPEEDR寄存器为低速输出模式
    GPIOE->OSPEEDR &= (~(0x3<<16));

    //设置GPIOE_PUPDR寄存器为禁止上下拉电阻
    GPIOE->PUPDR &=(~(0x3<<20));
    
    //设置GPIOE_PUPDR寄存器为禁止上下拉电阻
    GPIOF->PUPDR &=(~(0x3<<20));
    
    //设置GPIOE_PUPDR寄存器为禁止上下拉电阻
    GPIOE->PUPDR &=(~(0x3<<16));
    
    //设置GPIOB——MODER寄存器为复用功能模式    
    GPIOB->MODER &=(~(0x3<<4));
    GPIOB->MODER |=(0x1<<5);

    //设置GPIOG_MODER寄存器为复用功能模式
    GPIOG->MODER &=(~(0x3<<22));
    GPIOG->MODER |=(0x1<<23);

    //设置GPIOB_AFRL寄存器复用功能模式UART4_RX
    GPIOB->AFRL &=(~(0xf<<8));
    GPIOB->AFRL |=(0x1<<11);

    //设置GPIOG_AFRH寄存器复用功能模式UART4_TX
    GPIOG->AFRH &=(~(0xf<<12));
    GPIOG->AFRH |=(0x3<<13);
    
    /******************UART4章节初始化******************************/

    if(    USART4->CR1 &=(0x1<<0))
    {
        delay_ms(500);
        USART4->CR1 &=(~(0x1<<0));
    }
    //写00 ----->设置数据位宽度为8位
    USART4->CR1 &=(~(0x1<<28));
    USART4->CR1 &=(~(0x1<<12));

    //写0 ----->设置串口无奇偶校验位
    USART4->CR1 &=(~(0x1<<10));
    
    //设置串口1位停止位
    USART4->CR2 &=(~(0x3<<12));
    
    //写0 ----->设置串口采样率,会影响波特率的计算
    USART4->CR1 &=(~(0x1<<15));

    USART4->PRESC &=(~(0xf<<0));
    
    USART4->BRR |= 0x22B;

    //设置串口发送器使能
    USART4->CR1 |=(0x1<<3);
    //[200~设置串口接收器使能
    USART4->CR1 |=(0x1<<2);
    //设置串口使能
    USART4->CR1 |=(0x1<<0);

}

//发送一个字符
void put_char(const char str)
{
    //1.判断发送数据寄存器是否为空,为空才可以发送下一个字节
    //ISR[7]
    //读0:发送数据寄存器满,需要等待
    //读1:发送数据寄存器空,才可以发送下一个字节数据
    while(!(USART4->ISR &(0x1<<7)));
    

    //2.将要发送的字符,写到发送数据寄存器中
    USART4->TDR = str;
    
    //3.判断发送数据寄存器是否完成
    //ISR[6]
    while(!(USART4->ISR &(0x1<<6)));
}

//接受一个字符
char get_char()
{
    char ch;
    //1.判断接收数据寄存器是否有数据可读 ISR[5]
    while(!(USART4->ISR & (0x1<<5)));
    
    //2.将接收到的数据读出来
    ch = USART4->RDR;
    return ch;
}

//发送一个字符串
void put_string(const char *str)
{
    //判断是否为'\0',一个字符一个字符发送
    int i = 0;
    while( str[i]!='\0')
    {
        put_char(str[i]);
        i++;
    }
    put_char('\n');
    put_char('\r');
}


char buffer[50] = {0};
//接受一个字符串
char *get_string()
{
    int i;                                                 
    //for循环                                              
    //当键盘的回车键'\r'按下之后,字符串输入完成           
    for(i=0;i<49;i++)                                      
    {                                                      
        buffer[i] = get_char();//接收一个字符         
        put_char(buffer[i]);//发送一个字符            
        if(buffer[i] == '\r') //判断字符串是否输入完成     
            break;                                         
    }                                                      
    //字符串补'\0'                                         
    buffer[i] = '\0';                                      
    put_char('\n');                                   
    return buffer;    
}


void led1_on()
{
  //设置PE10引脚输出高电平 ODR[10] = 1
  GPIOE->ODR = GPIOE->ODR | (0x1<<10);
}


void led1_off()
{

  //设置PE10引脚输出低电平 ODR[10] = 0
    GPIOE->ODR = GPIOE->ODR & (~(0x1<<10));
}

void led2_on()
{
  //设置PF10引脚输出高电平 ODR[10] = 1
  GPIOF->ODR = GPIOF->ODR | (0x1<<10);
}


void led2_off()
{

  //设置PF10引脚输出低电平 ODR[10] = 0
    GPIOF->ODR = GPIOF->ODR & (~(0x1<<10));
}
void led3_on()
{
  //设置PE8引脚输出高电平 ODR[10] = 1
  GPIOE->ODR = GPIOE->ODR | (0x1<<8);
}


void led3_off()
{

  //设置PE8引脚输出低电平 ODR[10] = 0
    GPIOE->ODR = GPIOE->ODR & (~(0x1<<8));
}

int strcmp(const char* str1,const char* str2)
{
    char*p1 = str1;
    char*p2 = str2;
    while(*p1 != '\0')
    {
        if(*p1 != *p2) return 0;
        p1++;
        p2++;
    }
    return 1;
}

cmd_t cmd_arr[6] = {
    [0] ={
        .cmd_arr = "led1on",
        .gpiox = GPIOE,
        .pin = GPIO_PIN_10,
        .status = gpio_set,
        .gpio_write_pin = hal_gpio_write,
    },
    [1] ={
        .cmd_arr = "led1off",
        .gpiox = GPIOE,
        .pin = GPIO_PIN_10,
        .status = gpio_reset,
        .gpio_write_pin = hal_gpio_write,
    },
    [2] ={
        .cmd_arr = "led2on",
        .gpiox = GPIOF,
        .pin = GPIO_PIN_10,
        .status = gpio_set,
        .gpio_write_pin = hal_gpio_write,
    },
    [3] ={
        .cmd_arr = "led2off",
        .gpiox = GPIOF,
        .pin = GPIO_PIN_10,
        .status = gpio_reset,
        .gpio_write_pin = hal_gpio_write,
    },
    [4] ={
        .cmd_arr = "led3on",
        .gpiox = GPIOE,
        .pin = GPIO_PIN_8,
        .status = gpio_set,
        .gpio_write_pin = hal_gpio_write,
    },
    [5] ={
        .cmd_arr = "led3off",
        .gpiox = GPIOE,
        .pin = GPIO_PIN_8,
        .status = gpio_reset,
        .gpio_write_pin = hal_gpio_write,
    }
};


cmd_t* find_command(const char* str){
    for(int i=0; i<6;i++){
        if(strcmp(str,cmd_arr[i].cmd_arr)==0){
            return &cmd_arr[i];
        }
    }
    return 0;
}

main.c

#include "uk.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()
{

    uk_init();
    cmd_t* cmd_arr;
 
    while(1)
 
    {
        char* string = get_string();
 
        cmd_arr=find_command(string);
 
        if(cmd_arr == 0)
        {
            printf("查找失败\n");
 
        }else
        {
            cmd_arr->gpio_write_pin(cmd_arr->gpiox,cmd_arr->pin,cmd_arr->status);
        }
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值