综合作业,串口控制硬件功能

实现串口控制led灯
control.h

#ifndef __UART_CONTROL__
#define __UART_CONTROL__
#include "/home/yyh/code/test/my_project/02-led-c/include/ledx.h"
#include "/home/yyh/code/test/my_project/02-led-c/include/libs.h"
// LED灯信息结构体,用于串口点灯

typedef struct
{
    char *uart_cmd;        // 对应的命令
    ledx_t led;            // 哪个灯
    unsigned int gpio_pin; // 哪个引脚
    led_status_t led_stat; // led灯要设置什么状态
    void(*led_statu)(ledx_t led, led_status_t statu);
} uart_led_t;

uart_led_t * uart_led_status(char *p);



#endif

control.c

#include "/home/yyh/code/test/my_project/02-led-c/include/uart_control.h"

uart_led_t LEDS[6] =
    {
        [0] = {
            .uart_cmd = "led1on",
            .led = LED1,
            .led_stat = led_set,
            .gpio_pin = gpio_pin10,
            .led_statu = led_statu
        },
        [1] = {
            .uart_cmd = "led1off",
            .led = LED1,
            .led_stat = led_reset,
            .gpio_pin = gpio_pin10,
            .led_statu = led_statu
        },
        [2] = {
            .uart_cmd = "led2on",
            .led = LED2,
            .led_stat = led_set,
            .gpio_pin = gpio_pin10,
            .led_statu = led_statu
        },
        [3] = {
            .uart_cmd = "led2off",
            .led = LED2,
            .led_stat = led_reset,
            .gpio_pin = gpio_pin10,
            .led_statu = led_statu
        },
        [4] = {
            .uart_cmd = "led3on",
            .led = LED3,
            .led_stat = led_set,
            .gpio_pin = gpio_pin8,
            .led_statu = led_statu
        },
        [5] = {
            .uart_cmd = "led3off",
            .led = LED3,
            .led_stat = led_reset,
            .gpio_pin = gpio_pin8,
            .led_statu = led_statu
        }};

//处理函数
uart_led_t * uart_led_status(char *p)
{
    for(int i=0;i<6;i++)
    {
        if(!strcmp(LEDS[i].uart_cmd,p))
        {
            return &LEDS[i];
            break;
        }
    }
    return 0;
}

uart.h

#ifndef __UARTS_H__
#define __UARTS_H__
#define LEN 128
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"

void lib_uarts_init();

char uarts_recv_char();

void uarts_send_char(char s);

char *uarts_recv_string();

void uarts_send_string(char *s);

#endif

uart.c

#include "uarts.h"
extern void delay_ms(int ms);
char recvbuff[LEN];
void lib_uarts_init()
{
    // 使能UART4
    RCC->MP_APB1ENSETR |= (0x1 << 16);
    // 使能GPIOB
    RCC->MP_AHB4ENSETR |= (0x1 << 1);
    // 使能GPIOG
    RCC->MP_AHB4ENSETR |= (0x1 << 6);

    // 设置复用模式
    GPIOB->MODER &= ~(0x3 << 4);
    GPIOB->MODER |= (0x1 << 5);
    GPIOB->AFRL &= ~(0XF << 8);
    GPIOB->AFRL |= (0x1 << 11);

    GPIOG->MODER &= ~(0x3 << 22);
    GPIOG->MODER |= (0x1 << 23);
    GPIOG->AFRH &= ~(0xf << 12);
    GPIOG->AFRH |= (0x3 << 13);

    // 设置UART4的CR1寄存器
    if (USART4->CR1 & (0x1))
    {
        delay_ms(100);
        USART4->CR1 &= ~(0x1);
    }
    // 设置数据位
    USART4->CR1 &= ~(0x1 << 28);
    USART4->CR1 &= ~(0x1 << 12);
    // 设置采样率
    USART4->CR1 &= ~(0x1 << 15);
    // 设置奇偶校验位
    USART4->CR1 &= ~(0x1 << 10);
    // 设置停止位
    USART4->CR2 &= ~(0x3 << 12);

    // 设置不分频
    USART4->PRESC &= ~(0xf);
    // 设置波特率
    USART4->BRR |= 0x22b;
    // 发送位使能
    USART4->CR1 |= (0x1 << 3);
    // 接收位使能
    USART4->CR1 |= (0x1 << 2);
    // CR1使能
    USART4->CR1 |= (0x1);
}

char uarts_recv_char()
{
    char recv_ch;
    if (USART4->ISR & (0x1 << 5))
    {
        recv_ch = USART4->RDR;
        return recv_ch;
    }
    return 0;
}

void uarts_send_char(char s)
{
    while (1)
    {
        if (USART4->ISR & (0x1 << 6))
        {
            if (USART4->ISR & (0x1 << 7))
            {
                USART4->TDR = s;
                break;
            }
            else
            {
                continue;
            }
        }
        else
        {
            continue;
        }
    }
}

char *uarts_recv_string()
{
    int i = 0;
    while (i < LEN)
    {
        while (!(USART4->ISR & (0x1 << 5)))
            ;
        recvbuff[i] = USART4->RDR;
        uarts_send_char(recvbuff[i]);
        if (recvbuff[i] == '\r')
        {
            break;
        }
        i++;
    }
    recvbuff[i] = '\0';
    uarts_send_char('\n');
    return recvbuff;
}

void uarts_send_string(char *s)
{
    while (*s)
    {
        uarts_send_char(*s);
        s++;
    }
    uarts_send_char('\n');
    uarts_send_char('\r');
}


lib.h

#ifndef __LIBS_H__
#define __LIBS_H__
int strcmp(char *Dest, char *Src);
void bzero(char *str,unsigned int lens);
#endif //__LIBS_H__

lib.c

#include "libs.h"
int strcmp(char *Dest, char *Src)
{
    while ((*Dest + *Src != '\0'))
    {
        if (*(Dest) == *(Src))
        {
            if (0 == *Dest)
            {
                return -1;
            }
            else if(0 == *Src)
            {
                return 1;
            }
            Dest++;
            Src++;
            continue;
        }
        else
        {
            return *Src - *Dest;
            break;
        }
    }
    return 0;
}
void bzero(char *str,unsigned int lens)
{
    while(lens)
    {
        *(str++) = '\0';
        lens --;
    }
}


led.h

#ifndef __LED_H__
#define __LED_H__
#include "/home/yyh/code/test/my_project/02-led-c/common/include/stm32mp1xx_gpio.h"
#include "/home/yyh/code/test/my_project/02-led-c/common/include/stm32mp1xx_rcc.h"
#include "/home/yyh/code/test/my_project/02-led-c/common/include/stm32mp1xx_uart.h"
#include "/home/yyh/code/test/my_project/02-led-c/include/gpio1.h"


// LED初始化
void led_init();

// LED状态
void led_statu(ledx_t led, led_status_t statu);



#endif

led.c

#include "ledx.h"
#include "uarts.h"
#include "libs.h"
extern char recvbuff[LEN];
void led_init()
{
    RCC->MP_AHB4ENSETR |= (0x3 << 4);
    gpio_inits_t init =
        {
            .moder = output,
            .pin = gpio_pin8 | gpio_pin10,
            .ospeedr = lowspeed,
            .otyper = push_pull,
            .pupd = noall,
        };
    hal_gpio_init(GPIOE, &init);

    init.pin = gpio_pin10;
    hal_gpio_init(GPIOF, &init);
}
void led_statu(ledx_t led, led_status_t statu)
{
    switch (led)
    {
    case LED1:
        if (led_set == statu)
        {
            set_led_status(GPIOE, gpio_pin10, led_set);
        }
        else
        {
            set_led_status(GPIOE, gpio_pin10, led_reset);
        }
        break;
    case LED2:
        if (led_set == statu)
        {
            set_led_status(GPIOF, gpio_pin10, led_set);
        }
        else
        {
            set_led_status(GPIOF, gpio_pin10, led_reset);
        }
        break;
    case LED3:
        if (led_set == statu)
        {
            set_led_status(GPIOE, gpio_pin8, led_set);
        }
        else
        {
            set_led_status(GPIOE, gpio_pin8, led_reset);
        }
        break;
    default:
        break;
    }
}

gpio.h

#ifndef __GPIO1_H__
#define __GPIO1_H__
#include "/home/yyh/code/test/my_project/02-led-c/common/include/stm32mp1xx_gpio.h"

#define gpio_pin0 0x0001U
#define gpio_pin1 0x0002U
#define gpio_pin2 0x0004U
#define gpio_pin3 0x0008U

#define gpio_pin4 0x0010U
#define gpio_pin5 0x0020U
#define gpio_pin6 0x0040U
#define gpio_pin7 0x0080U

#define gpio_pin8 0x0100U
#define gpio_pin9 0x0200U
#define gpio_pin10 0x0400U
#define gpio_pin11 0x0800U

#define gpio_pin12 0x1000U
#define gpio_pin13 0x2000U
#define gpio_pin14 0x4000U
#define gpio_pin15 0x8000U

typedef enum
{
    input,
    output,
    alternet,
    analog
} gpio_moder_t;

typedef enum
{
    push_pull,
    open_drain
} gpio_otyper_t;

typedef enum
{
    lowspeed,
    medspeed,
    highspeed,
    vhighspeed
} gpio_ospeedr_t;

typedef enum
{
    noall,
    pull_up,
    pull_down,
    reserved
} gpio_pupd_t;

typedef enum
{
    led_reset = 0,
    led_set
} led_status_t;

typedef struct
{
    volatile unsigned int pin;
    gpio_moder_t moder;
    gpio_otyper_t otyper;
    gpio_ospeedr_t ospeedr;
    gpio_pupd_t pupd;
} gpio_inits_t;

typedef enum
{
    LED1 = 1,
    LED2,
    LED3
} ledx_t;
void hal_gpio_init(gpio_t *gpio, gpio_inits_t *init);
led_status_t led_status(gpio_t *gpio, unsigned int pin);
void set_led_status(gpio_t *gpio, unsigned int pin, led_status_t statu);
#endif

gpio.c

#include "gpio1.h"

void hal_gpio_init(gpio_t *gpio, gpio_inits_t *init)
{
    unsigned int CurrentPins = 0;
    for (CurrentPins=0; CurrentPins < 16; CurrentPins++)
    {
        if (init->pin & (0x1 << CurrentPins))
        {
            gpio->MODER &= ~(0x3 << (2 * CurrentPins));
            gpio->MODER |= (init->moder << (2 * CurrentPins));

            gpio->OTYPER &= ~(0x1 << CurrentPins);
            gpio->OTYPER |= (init->otyper << CurrentPins);

            gpio->OSPEEDR &= ~(0x3 << (2 * CurrentPins));
            gpio->OSPEEDR |= (init->ospeedr << (2 * CurrentPins));

            gpio->PUPDR &= ~(0x3 << (2 * CurrentPins));
            gpio->PUPDR |= (init->pupd << (2 * CurrentPins));
        }
    }
}

// 返回当前led状态
led_status_t led_status(gpio_t *gpio, unsigned int pin)
{
    if (gpio->IDR & (0x1 << pin))
    {
        return led_set;
    }
    else
    {
        return led_reset;
    }
}

void set_led_status(gpio_t *gpio, unsigned int pin, led_status_t statu)
{
    if (statu == led_set)
    {
        //gpio->ODR |= pin;
        for(unsigned int i=0;i<16;i++)
        {
            if(pin & (0x1 << i))
            {
                gpio->ODR |= (0x1 << i);
                break;
            }
        }
    }
    else
    {
        //gpio->ODR &= ~(pin);
        for(unsigned int i=0;i<16;i++)
        {
            if(pin & (0x1 << i))
            {
                gpio->ODR &= ~(0x1 << i);
                break;
            }
        }
    }
}

main.c

#include "ledx.h"
#include "gpio1.h"
#include "uarts.h"
#include "libs.h"
#include "si7006.h"
#include "uart_control.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()
{
	led_init();
	uart_led_t *p;
	char *recv;
	while (1)
	{
		recv = uarts_recv_string();
		p = uart_led_status(recv);
		if(p)
		{
			p->led_statu(p->led,p->led_stat);
			bzero(recv,sizeof(recv));
		}
		else
		{
			printf("没有找到\n");
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值