1.11 LED灯点亮串口解析器

news2025/1/16 5:06:34

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框图

 

  1. MOS管:栅极为低电平时,源极和漏极导通
  1. 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156035.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我在CSDN的2022---2023Flag

一、加入CSDN我是在2020年12月注册的CSDN&#xff0c;大一上学期就听同学给我讲了这个软件&#xff0c;然后就下载了&#xff0c;里面确实很多优质文章&#xff0c;对于当时向我们这样的初学者来说就是很实用。还记得都是搜什么&#xff0c;求最大值&#xff0c;最小值&#xf…

Redis热点数据处理

1、概念热点数据就是访问量特别大的数据。2、热点数据引起的问题流量集中&#xff0c;达到物理网卡上限。请求过多&#xff0c;缓存分片服务被打垮。redis作为一个单线程的结构&#xff0c;所有的请求到来后都会去排队&#xff0c;当请求量远大于自身处理能力时&#xff0c;后面…

RabbitMQ消息可靠性问题、死信交换机、延迟消息、惰性队列

目录消息可靠性生产者确保将消息成功送入队列消息确认消息回执消费者确保消息成功从队列中取出并成功消费消费确认机制消费失败重试机制失败策略使用第三种方式&#xff1a;消费者指定失败后转发的交换机使用第一种方式&#xff1a;在队列中指定死信交换机消息持久化问题交换机…

软件测试常见性能问题案例分析

在用户场景不确定的情况下&#xff0c;我们为了保障软件的正常运行就必须对软件的性能进行测试。下面我们一起来看看在软件测试中常见的性能问题&#xff0c;希望大家可以通过这七个比较典型的案例分析&#xff0c;充分掌握各种性能问题的解决方法。 案例一&#xff1a;某次压…

Spring Cloud 03 --- Nacos注册中心

前言 注册中心以Map形式存储消费者与生产者的IP和端口 基本概念 &#xff08;1&#xff09;Nacos 是阿里巴巴推出来的一个新开源项目&#xff0c;是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供…

2023年使用率会很高的9个SSH远程连接工具有这些!网工、运维你们用的是哪个?

网络工程师和运维工程师我想每天做的最多的一件事就是远程连接了&#xff0c;例如远程连接网络设备、远程连接服务器&#xff08;物理服务器或者云服务器&#xff09;&#xff0c;这个时候大多数用的工具都是基于SSH协议的&#xff0c;每位工程我想都有自己熟悉或者青睐的SSH工…

时序图文献精度——5.2019-IJCIA-Node Embedding over Temporal Graphs

Node Embedding over Temporal Graphs Abstract 作者提出了一种在时间图中嵌入节点的方法。学习时间图的节点和边随时间的演变&#xff0c;并将这种动态整合到时间节点嵌入框架中&#xff0c;用于不同的图预测任务。作者也提出了一个联合损失函数&#xff0c;它通过学习组合节…

【java算法】稀疏数组/队列/单双链表

文章目录线性和非线性结构稀疏数组前言代码刷类型题队列非环形队列环形队列刷题单链表单链表的定义案例演示--代码1.按照顺序添加2.按英雄排名插入3.根据no编号来修改节点信息4.删除节点单链表刷题1.求单链表中有效节点的个数2.查找单链表中的倒数第k个节点3.单链表的反转4.从尾…

SAP入门技术分享三:OPEN SQL

OPEN SQL1. 概要&#xff08;1&#xff09;R/3体系结构&#xff08;2&#xff09;SQL定义&#xff08;3&#xff09;OPEN SQL经常使用的命令2. OPEN SQL&#xff08;1&#xff09;SELECT 语句&#xff08;2&#xff09;INTO语句3. FROM语句&#xff08;1&#xff09;选择静态表…

JSONArray

目录1. 需求2. 测试3. 实现需求4. 相关操作1. 将JSONObject装入JSONArray2. JSONArray与String的相互转换1. 需求 最近有个需求&#xff1a; 要接收某个接口的 JSON 数据&#xff0c;而这个JSON数据有可能是一个 JSON 对象&#xff0c;也有可能是一个 JSON数组。 "{name…

python数据结构之字符串

一、字符串的格式化输出 1.1、格式化运算符 print("我跑完了第" str(lap 1) "圈")上面这段输出的代码使用了两个加号做了字符串拼接&#xff0c;并且将整形转换成了字符串。也可以使用一种更好的办法&#xff0c;格式化输出来打印这句话。 print(&quo…

内存取证——基础知识(volatility内存取证)

目录 一、基本概念 二、运行内存镜像的获取 2.1 Windows内存镜像获取 2.1.1 Magnet RAM Capture获取内存镜像 2.1.2 AccessData FTK Imager软件获取内存镜像 2.1.3 DumpIt软件获取内存镜像 2.1.4 额外知识补充&#xff1a; 2.2 Linux\Mac OS 下内存镜像获取方法 三、内…

什么是云渲染?云渲染速度快吗?

近年来随着计算机技术的逐步发展&#xff0c;万物上‘’云‘’的趋势越发明显&#xff0c;一种基于云计算的SAAS服务平台——云渲染农场开始走入CG行业。而且云渲染农场&#xff08;如Renderbus瑞云渲染&#xff09;也在众多CG小伙伴的眼里成为了不可或缺的一部分。有人问云渲染…

[ docker相关知识 ] 删除 docker 拉取的容器 -- 解决删除镜像报错问题

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

CSS入门八、CSS3动画

零、文章目录 文章地址 个人博客-CSDN地址&#xff1a;https://blog.csdn.net/liyou123456789个人博客-GiteePages&#xff1a;https://bluecusliyou.gitee.io/techlearn 代码仓库地址 Gitee&#xff1a;https://gitee.com/bluecusliyou/TechLearnGithub&#xff1a;https:…

三、Gradle使用

文章目录三、Gradle使用1 在 idea 中创建普通 java 工程2 在 idea 中创建 ssm 工程3 项目部署3.1 本地tomcat部署项目3.2 Gretty 部署项目3.3 具体使用4 Gradle 对测试支持4.1 默认测试目录及标准输出4.2 Junit 使用4.3 包含和排除特定测试【尚硅谷】Gradle教程-讲师&#xff1…

Blender 物理属性 (一)刚体

文章目录添加与去除刚体查看刚体效果刚体属性刚体设置碰撞表面响应添加与去除刚体 1 添加&#xff1a;物体模式选中一个物体&#xff0c;属性栏/物理属性&#xff08;蓝色圆圈&#xff09;&#xff0c;选择刚体 2 去除&#xff1a;再次点击刚体按钮即可 查看刚体效果 1 点击…

SpringCloud系列(八)[docker 篇] - 关于 Docker 的一些介绍及架构

近几年 Docker 还是挺火的, 学习微服务也肯定要知道 Docker 的存在并最好掌握一些基本操作, 毕竟一些体量非常大的项目运行环境会比较复杂, 部署的时候难免会遇到某些问题, 如兼容性 / 生产环境有差异等问题… 本篇文章将以图文的形式对 Docker 进行介绍, 加深对 Docker 的印象…

S2B2b2C电商框架图

S2B2b2C电商框架图 以下是S2B2b2C系统的结构图和流程说明&#xff1a; 它是品牌商赋能门店流量&#xff0c;以用户为中心、提升用户体验的一种电商模式。 这个品牌商可以是工厂、连锁品牌、省代市代等商贸流通型企业&#xff0c;它可以一个或者多个仓库&#xff0c;甚至有自己…

文件恢复软件哪个最好用?5 款最佳照片文件恢复软件

丢失照片很常见&#xff0c;但恢复它们取决于您选择的方法或软件。找到最好的照片恢复软件来恢复永久删除的照片并不容易。在许多网页上&#xff0c;您可以找到一大堆照片恢复工具&#xff0c;无论它们的性能如何。这可能会造成很多混乱&#xff0c;不知道优先使用什么照片恢复…