实现串口控制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;
}