LED点灯实验
一.电路图:

三极管:
                
                    
NPN类型:
      
                 
PNP类型:

NPN类型当基极为高电平时,集电极和发射极导通
PNP类型当基极为低电平时,集电极和发射极导通
由电路图可知LED电路图中三极管为NPN类型,只有当基极为高电平时,集电极和发射极导通,LED亮起。因此LED亮起为高电平,LED熄灭为低电平
LED1----PE10
LED2----PF10
LED3----PE8
- 分析RCC章节
作用:使能GPIO
RCC在AHB4总线上(芯片手册第二章),通过RCC_MP_AHB4ENSETR寄存器使能GPIOE组和GPIOF组相关控制器
- 分析GPIO章节
GPIO框图

- MOS管:栅极为低电平时,源极和漏极导通
- MOS管:栅极为高电平时,源极和漏极导通
GPIO相关寄存器
GPIO_MODER: 选择输出模式
GPIO_OTYPER:选择输出类型
GPIO_SPEEDR:选择输出速率
GPIO_PUPDR:选择是否需要上下拉电阻
GPIO_ODR:控制输出高电平还是低电平
代码:
gpio.h:
#ifndef __GPIO_H__
#define __GPIO_H__
//寄存器封装
typedef struct{
	volatile unsigned int MODER;
	volatile unsigned int OTYPER;
	volatile unsigned int OSPEEDR;
	volatile unsigned int PUPDR;
	volatile unsigned int IDR;
	volatile unsigned int ODR;
}gpio_t;
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)
//封装引脚
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15
//模式寄存器封装
typedef enum{
	INPUT,
	OUTPUT,
	ALT,
	ANALOG
}gpio_moder_t;
//输出类型寄存器封装
typedef enum{
	PP,
	OD
}gpio_otyper_t;
//输出速率寄存器封装
typedef enum{
	LOW,
	MED,
	HIGH,
	VERY_HIGH
}gpio_ospeedr_t;
//是否需要上下拉电阻封装
typedef enum{
	NO_PUPD,
	PU,
	PD
}gpio_pupdr_t;
//输出高低电平寄存器封装
typedef enum{
	GPIO_RESET,
	GPIO_SET
}gpio_status_t;
//封装初始化结构体
typedef struct{
	gpio_moder_t moder; //模式 
	gpio_otyper_t otyper; //输出类型 
	gpio_ospeedr_t speed;//速率
	gpio_pupdr_t pupdr; //是否需要上下拉电阻 
}gpio_init_t;
//函数功能:初始化GPIO(根据参数初始化不同LED)
void hal_gpio_init(gpio_t* gpiox,gpio_init_t* init,unsigned int pin);
//函数功能:操作GPIO引脚,实现LED灯亮灭
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t status);
#endif
gpio.c:
#include "gpio.h"
void hal_gpio_init(gpio_t* gpiox,gpio_init_t* init,unsigned int pin)
{
	gpiox->MODER&=(~(0x3<<(pin*2)));//设置IO口模式为输出模式
	gpiox->MODER|=(init->moder)<<(pin*2);
	gpiox->OTYPER&=~(0x1<<(pin));//设置输出类型为推挽类型
	gpiox->OTYPER|=(init->otyper)<<(pin);
	gpiox->OSPEEDR&=~(0x3<<(pin*2));//设置输出速率为低速
	gpiox->OSPEEDR|=(init->otyper)<<(pin*2);
	gpiox->PUPDR&=~(0x3<<(pin*2));//设置不需要上下拉电阻
	gpiox->PUPDR|=(init->pupdr)<<(pin*2);
}
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t status)
{
	if(status==GPIO_SET){  //判断状态
		gpiox->ODR|=(0x1<<pin);//写入高电平
	}else{
		gpiox->ODR&=~(0x1<<pin);//写入低电平
	}
}
main.c:
#include "gpio.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++);
}
void led_init()
{
	//1.时钟使能
	RCC_AHB4_ENSETR|=(0x3<<4);	
	//2.初始化结构体
	gpio_init_t init={OUTPUT,PP,LOW,NO_PUPD};
	//3.调用gpio初始化函数
	hal_gpio_init(GPIOE,&init,10);
	hal_gpio_init(GPIOF,&init,10);
	hal_gpio_init(GPIOE,&init,8);
}
int main()
{
	led_init();
	while(1)
	{
		hal_gpio_write(GPIOE,10,GPIO_SET);
		delay_ms(1000);
		hal_gpio_write(GPIOE,10,GPIO_RESET);
		
		hal_gpio_write(GPIOF,10,GPIO_SET);
		delay_ms(1000);
		hal_gpio_write(GPIOF,10,GPIO_RESET);
		
		hal_gpio_write(GPIOE,8,GPIO_SET);
		delay_ms(1000);
		hal_gpio_write(GPIOE,8,GPIO_RESET);
	}
	return 0;
}
串口解析器
led.h
#ifndef __LED_H__
#define __LED_H__
#include "../common/include/stm32mp1xx_gpio.h"
/*
//LED1初始化
void led1_init();
//LED1点亮
void led1_on();
//LED1熄灭
void led1_off();
*/
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15
typedef enum{
	GPIO_RESET,
	GPIO_SET
}gpio_status_t;
typedef struct{
	char* cmd_str;           //字符串
	gpio_t* gpiox;            //GPIO组		
	unsigned int pin;		//引脚
	gpio_status_t stat; 			//LED状态
	void (*gpio_write_p)(gpio_t* gpiox,unsigned int pin,gpio_status_t stat);	
}cmd_t;   
void hal_gpio_init();
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t stat);
void put_char(const char c);
char get_char();
char* get_string();
cmd_t* cmp_str(char* str);
int my_strcmp(char* str1 ,char* str2);
void put_string(char* string);
#endif
led.c
#include "../include/led.h"
#include "../common/include/stm32mp1xx_gpio.h"
#include "../common/include/stm32mp1xx_rcc.h"
#include "../common/include/stm32mp1xx_uart.h"
extern void printf(const char *fmt, ...);
//初始化/
void hal_gpio_init(){
	RCC->MP_AHB4ENSETR|=0x1<<4;
	RCC->MP_AHB4ENSETR|=0x1<<5; 
	//LED1----PE10
	GPIOE->MODER&=(~(0x3)<<20);
	GPIOE->MODER|=(0x1<<20);
	
	GPIOE->OTYPER&=(~(0x1<<10));
	GPIOE->OSPEEDR&=(~(0x3<<20));
	GPIOE->PUPDR&=(~(0x3<<20));
	//LED2----PF10
	GPIOF->MODER&=(~(0x3)<<20);
	GPIOF->MODER|=(0x1<<20);
	
	GPIOF->OTYPER&=(~(0x1<<10));
	GPIOF->OSPEEDR&=(~(0x3<<20));
	GPIOF->PUPDR&=(~(0x3<<20));
	//LED3----PE8
	GPIOE->MODER&=(~(0x3)<<16);
	GPIOE->MODER|=(0x1<<16);
	
	GPIOE->OTYPER&=(~(0x1<<8));
	GPIOE->OSPEEDR&=(~(0x3<<16));
	GPIOE->PUPDR&=(~(0x3<<16));
	//UART
	RCC->MP_AHB4ENSETR |= (0x1 << 1);
    RCC->MP_AHB4ENSETR |= (0x1 << 6);
    // 使能UART控制器的时钟
    RCC->MP_APB1ENSETR |= (0x1 << 16);
    /*******GPIO章节初始化*******/
    // 设置PG11为复用模式
    GPIOG->MODER &= (~(0x3 << 22));
    GPIOG->MODER |= (0x2 << 22);
    //设置PB2为复用模式
    GPIOB->MODER &= (~(0x3 << 4));
    GPIOB->MODER |= (0x2 << 4);
    //设置PG11为UART4_TX复用功能
    GPIOG->AFRH &= (~(0xf << 12));
    GPIOG->AFRH |= (0x6 << 12);
    //设置PB2为UART4_RX复用功能
    GPIOB->AFRL &= (~(0xf << 8));
    GPIOB->AFRL |= (0x8 << 8);
    /*******UART章节初始化*******/
    //设置UART4传输数据宽度为8位
    USART4->CR1 &= (~(0x1 << 28));
    USART4->CR1 &= (~(0x1 << 12));
    //设置UART4串口16倍采样率
    USART4->CR1 &= (~(0x1 << 15));
    //设置UART4串口无奇偶校验位
    USART4->CR1 &= (~(0x1 << 10));
    //设置UART4串口发送寄存器和接收寄存器使能
    USART4->CR1 |= (0x3 << 2);
    //设置UART4串口1位停止位
    USART4->CR2 &= (~(0x3 << 12));
    //设置UART4串口不分频
    USART4->PRESC &= ~0xf;
    //设置UART4串口波特率为115200
    USART4->BRR &= ~0xffff;
    USART4->BRR |= 0x22b;
    //设置UART4串口使能
    USART4->CR1 |= 0x1;
}
//初始化结构体
cmd_t cmd_arr[6]={
	[0]={
		.cmd_str="LED1ON",
		.gpiox=GPIOE,
		.pin=GPIO_PIN_10,
		.stat=GPIO_SET,
		.gpio_write_p=hal_gpio_write,
	},
	[1]={
		.cmd_str="LED1OFF",
		.gpiox=GPIOE,
		.pin=GPIO_PIN_10,
		.stat=GPIO_RESET,
		.gpio_write_p=hal_gpio_write,
	},
	[2]={
		.cmd_str="LED2ON",
		.gpiox=GPIOF,
		.pin=GPIO_PIN_10,
		.stat=GPIO_SET,
		.gpio_write_p=hal_gpio_write,
	},
	[3]={
		.cmd_str="LED2OFF",
		.gpiox=GPIOF,
		.pin=GPIO_PIN_10,
		.stat=GPIO_RESET,
		.gpio_write_p=hal_gpio_write,
	},
	[4]={
		.cmd_str="LED3ON",
		.gpiox=GPIOE,
		.pin=GPIO_PIN_8,
		.stat=GPIO_SET,
		.gpio_write_p=hal_gpio_write,
	},
	[5]={
		.cmd_str="LED3OFF",
		.gpiox=GPIOE,
		.pin=GPIO_PIN_8,
		.stat=GPIO_RESET,
		.gpio_write_p=hal_gpio_write,
	}
};
// 2.发送一个字符
void put_char(const char str)
{
    while (!(USART4->ISR & (0x1 << 7)));
    USART4->TDR = str;
    while (!(USART4->ISR & (0x1 << 6)));
}
// 3.发送一个字符串
void put_string( char *str)
{
    while (*str)
    {
        put_char(*str++);
    }
    put_char('\n');
    put_char('\r');
}
// 4.接收一个字符
char get_char()
{
    char ch;
    while (!(USART4->ISR & (0x1 << 5)));
    ch = USART4->RDR;
    return ch;
}
char buffer[50] = {0};
char *get_string()
{
    unsigned int i;
    for (i = 0; i < 49; i++)
    {
        buffer[i] = get_char();
        put_char(buffer[i]);
        if (buffer[i] == '\r')
            break;
    }
    buffer[i] = '\0';
    put_char('\n');
    return buffer;
}
int my_strcmp(char* str1,char* str2){           //比较字符串
while ((*str1 != '\0') && (*str1 == *str2))//判断字符串是否结束。
    {
        str1++;
        str2++;//
    }
    int t;
    t = *str1 - *str2;//比较对应字符大小。
    if (t == 0)
        printf("same string\n");
    else if (t > 0)
        printf("str1 is bigger\n");
    else
        printf("str2 is bigger\n");
    return t;//若相等返回0,前者大返回正值,反之则负。
}
cmd_t* cmp_str(char* str)            //循环比较字符串和结构体数组中的字符串
{
	for(unsigned int i=0;i<6;i++){
		if(my_strcmp(str,cmd_arr[i].cmd_str)==0){
			return &cmd_arr[i];
		}
	}
	return 0;
}
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,gpio_status_t status)
{
	if(status==GPIO_SET){
		gpiox->ODR|=(0x1<<pin);
	}else{
		gpiox->ODR&=~(0x1<<pin);	
	}
}
main.c
#include "led.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_gpio_init();
	char* string="";
	cmd_t *p;
	while(1)
	{
		string=get_string();
		printf("%s\n",string);
		p=cmp_str(string);
		if(p==0){
			put_char('n');   //测试
		}else{
			put_char('y');    //测试
			p->gpio_write_p(p->gpiox,p->pin,p->stat);    
		}
	}
	return 0;
}













![[ docker相关知识 ] 删除 docker 拉取的容器 -- 解决删除镜像报错问题](https://img-blog.csdnimg.cn/cb001eb61b2f483ba7b20931249f7652.png)



![SpringCloud系列(八)[docker 篇] - 关于 Docker 的一些介绍及架构](https://img-blog.csdnimg.cn/aa3ca34ab0fa4d09b3c315da5b50805b.png#pic_center)

