三、GPIO口

news2024/9/22 0:51:10

我们在刚接触C语言时,写的第一个程序必定是hello world,其他的编程语言也是这样类似的代码是告诉我们进入了编程的世界,在单片机中也不例外,不过我们的传统就是点亮第一个LED灯,点亮电阻,电容的兄弟,也是挺厉害🤭的但是没有必要。

一、创建工程

         在这一章中,我们将了解到这款芯片的初始化配置,我们参考了网上的一些资料,和沁恒官方所提供的手册和例程

        如果还不了解使用这款芯片所用的软件和如何新建工程,可以去阅读专栏的前面两章阅读的地址我放在下面:
1.软件安装icon-default.png?t=N7T8https://blog.csdn.net/jzkj201/article/details/140397936

2.创建工程icon-default.png?t=N7T8https://blog.csdn.net/jzkj201/article/details/140443312

二、这篇文章能了解什么

        我们在正式开始点亮第一个LED灯前,先了解一下读了这篇能获得什么:

  1. 部分GPIO库函数的解读
  2. GPIO的初始化
  3. GPIO函数的写操作
  4. 延迟函数
  5. 代码程序

 2.1 部分GPIO库函数的解读

        找到图片的位置我们就可以看到,这款RISC-V架构的单片机的库函数了,学过STM32标准库的小伙伴,我相信你们也可以快速读懂库函数的。

2.2 GPIO的初始化

        为了方便程序的代码的管理,我新建了一个文件夹,用于放置相关代码的初始化和代码。感兴趣的小伙伴,可以自己搜索如何设置,后续我也会出相关的教程。如果现在不知道怎么创建的小伙伴,可以将初始化的代码,复制到int man()里面while函数的上面,就可以完成GPIO的初始化。

        下面我们就来看看这些代码表示什么意思。

void LED_Init(){
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

1.声明并初始化GPIO初始化结构体:

GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitTypeDef 是一个结构体类型,用于存储GPIO初始化的配置参数。
GPIO_InitStructure = {0}; 将这个结构体初始化为0,以确保所有成员变量都被设置为默认值。


2.使能GPIOA的时钟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd() 函数用于使能或失能外设的时钟。
RCC_APB2Periph_GPIOA 是GPIOA端口的时钟。
ENABLE 参数表示使能这个时钟。使能GPIOA的时钟是必要的,因为在配置和使用GPIOA引脚之前,必须先使能它的时钟。


3.配置GPIO引脚:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Pin_0 | GPIO_Pin_1 指定要初始化的引脚为GPIOA的引脚0和引脚1。通过使用位或运算符|,可以同时选择多个引脚。

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Mode_Out_PP 设置引脚模式为推挽输出模式。(小伙伴们可以去了解数据手册中的其他几个输出模式)

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Speed_50MHz 设置引脚的速度为50MHz。速度配置决定了引脚的最大切换速度,即引脚能够多快地从高电平切换到低电平或者反之。50MHz是较高的切换速度,适用于快速开关操作。


4.调用官方的库函数:

GPIO_Init(GPIOA, &GPIO_InitStructure); 
GPIO_Init() 函数使用上面设置的参数初始化GPIOA的引脚。

GPIOA 是要初始化的GPIO端口。&GPIO_InitStructure 是一个指向结构体的指针,该结构体包含初始化参数。
通过这个函数,GPIOA的引脚0和引脚1被配置为推挽输出模式,并准备以50MHz的速度操作。这些引脚现在可以用来控制LED或者其他输出设备。

2.3 GPIO函数的写操作 

 初始化GPIO口后,现在就可以对LED灯进行操作,在操作前我们先看看"ch32v30x_gpio.h"中的

void GPIO_WriteBit(GPI_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
这两个函数.

GPIO_WriteBit函数

参数说明:
  • GPIOx:指向GPIO端口基地址的指针,可以是GPIOA到GPIOG之一。
  • GPIO_Pin:要写入的端口引脚,可以是GPIO_Pin_x,其中x可以是0到15。
  • BitVal:要写入引脚的值,可以是Bit_RESETBit_SET
功能实现:
  • 判断BitVal是否为Bit_RESET。如果不是Bit_RESET,即为Bit_SET
    • GPIOx->BSHR = GPIO_Pin; 将选定的引脚置位(设置为高电平)。
  • 否则(BitValBit_RESET):
    • GPIOx->BCR = GPIO_Pin; 将选定的引脚清零(设置为低电平)

GPIO_WriteBit函数

参数说明:
  • GPIOx:指向GPIO端口基地址的指针,可以是GPIOA到GPIOG之一。
  • PortVal:要写入端口输出数据寄存器的值。
功能实现:
  • GPIOx->OUTDR = PortVal;PortVal的值写入到指定的GPIO端口的输出数据寄存器(OUTDR)。这会一次性地设置该端口所有引脚的状态。

2.4 延迟函数

        了解GPIO写操作的相关函数后,我们就来了解一下沁恒微电子官方给我提供的一些延迟函数,方便后续的LED灯的闪烁,流水灯,跑马灯等程序的编写。有关与延迟函数的库在debug.h

void Delay_Init(void)

void Delay_Us(uint32_t n)

void Delay_Ms(uint32_t n)

Delay_Init 函数

初始化延迟功能,计算并设置延迟计数变量。

功能:
  • SystemCoreClock 是系统核心时钟的频率。
  • p_us 是系统核心时钟频率除以8000000的结果,表示每个微秒的计数值。
  • p_ms 是每个微秒的计数值乘以1000,表示每个毫秒的计数值。

Delay_Us 函数

实现微秒级延迟。

  • 清除SysTick状态寄存器的第0位。
  • 计算延迟计数值 i,等于 n(微秒数)乘以 p_us
  • 将计数值 i 写入SysTick的比较寄存器(CMP)。
  • 设置SysTick控制寄存器:
    • 第4位:使能SysTick定时器。
    • 第5位和第0位:启动SysTick定时器。
  • 等待直到SysTick状态寄存器的第0位被置位,表示延迟结束。
  • 清除SysTick控制寄存器的第0位,停止定时器。

Delay_Ms 函数 

实现毫秒级延迟。

  • 清除SysTick状态寄存器的第0位。
  • 计算延迟计数值 i,等于 n(毫秒数)乘以 p_ms
  • 将计数值 i 写入SysTick的比较寄存器(CMP)。
  • 设置SysTick控制寄存器:
    • 第4位:使能SysTick定时器。
    • 第5位和第0位:启动SysTick定时器。
  • 等待直到SysTick状态寄存器的第0位被置位,表示延迟结束。
  • 清除SysTick控制寄存器的第0位,停止定时器。

好了,我们了解了一些基本的函数,那现在就开始来写代码吧。

2.5 代码程序

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	USART_Printf_Init(115200);	
	printf("SystemClk:%d\r\n",SystemCoreClock);
	printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
	printf("This is printf example\r\n");

	LED_Init();
	while(1)
    {
	        GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
	        GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);
	}
}

以上这段段代码就实现了LED1和LED2的点亮,目前我并没有最main函数内的串口等相关函数进行修改,后续会根据实际情况对main函数内的函数进行精简。

Tips:为什么在给相应的GPIO置低电平的时候LED灯才会亮呢?下面我们只需要看官方给的原理图就能明白,小伙伴根据自己的原理,给出合理的电平信号,来点亮你的LED灯吧。

2.5.1LED灯电路原理图

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

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

相关文章

锁策略和CAS指令

锁策略 一、锁策略的引入二、锁策略的分类(1)乐观锁和悲观锁(2)重量级锁和轻量级锁(3) 自旋锁和挂起等待锁(4)可重入锁和不可重入锁(5)公平锁和非公平锁&…

SQL面试题练习 —— 统计最大连续登录天数区间

目录 1 题目2 建表语句3 题解 1 题目 2 建表语句 CREATE TABLE IF NOT EXISTS user_login_tb (uid INT,login_date DATE ); insert into user_login_tb(uid, login_date) values( 1, 2022-08-02),(1, 2022-08-03),(2, 2022-08-03),(2, 2022-08-04),(2, 2022-08-05),(2, 2022-08…

使用Python的Turtle模块绘制小黄人

引言 在Python编程的世界里,turtle 模块是一个非常有趣且实用的工具,它允许程序员通过简单的指令控制一个虚拟的画笔(称为“海龟”)在屏幕上移动和绘制图形。本篇博客将详细介绍如何使用turtle模块来绘制一个卡通人物&#xff0c…

Redis-布隆过滤器(Bloom Filter)详解

文章目录 什么是布隆过滤器 布隆过滤器的优点:布隆过滤器的缺点:其他问题 布隆过滤器适合的场景布隆过滤器原理 数据结构增加元素查询元素删除元素 如何使用布隆过滤器 Google开源的Guava自带布隆过滤器Redis实现布隆过滤器 Redis中配置布隆过滤器Redis…

给Wordpress添加评分功能到评论表单

今天要 给你的 Wordpress 添加评分功能到评论表单 吗? 评分功能效果图 什么类型的网站需要评分? 资源站教程站其他,我也没想到。。。 但我这个网站,因为是电影类的网站,好像还是有点需要的,所以&#xf…

完美的用户体验:如何设计一个直观和有效的网站导航?

APP的顶部导航栏对我们来说很熟悉。导航栏是UI设计中不可或缺的一部分,几乎每个页面都使用导航栏。虽然导航栏看起来很简单,不需要太多精力,但是设计一个与产品需求和客户目标高度匹配的导航栏并不是那么容易的。导航栏的设计标准有很多细节需…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址:源码地址 一、什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe&…

C++ : 移除链表元素/合并两个有序链表题解

目录 1.移除链表元素 分析 代码 2.合并两个有序链表 分析 代码 1.移除链表元素 分析 像这种移除元素的,加个哨兵位头节点会比较方便,因为旧的头会有被移除的情况,不好控制。这里只需要用cur指向待遍历的节点,prev指向cur的…

AI大牛Karpathy创办Eureka Labs专注AI+教育

🦉 AI新闻 🚀 AI大牛Karpathy创办Eureka Labs专注AI教育 摘要:前OpenAI大牛Karpathy离职半年后宣布创办专注AI与教育的公司Eureka Labs,旨在通过生成式AI优化教育体验。公司首个项目LLM101n课程已在GitHub获得高赞,目…

C++ 继承详解:从基础到深入

继承是面向对象编程中最强大的功能之一,它不仅促进了代码的重用,还帮助我们构建复杂的系统。在C中,通过继承,我们可以创建一个新的类(称为派生类)来扩展现有类(基类)的功能。本文将全…

基于python的百度资讯爬虫的设计与实现

研究背景 随着互联网和信息技术的飞速发展,网络已经成为人们获取信息的主要来源之一。特别是搜索引擎,作为信息检索的核心工具,极大地改变了人们获取信息的方式。其中,百度作为中国最受欢迎的搜索引擎之一,其新闻搜索…

[GXYCTF2019]Ping Ping Ping1

打开靶机 结合题目名称,考虑是命令注入,试试ls 结果应该就在flag.php。尝试构造命令注入载荷。 cat flag.php 可以看到过滤了空格,用 $IFS$1替换空格 还过滤了flag,我们用字符拼接的方式看能否绕过,ag;cat$IFS$1fla$a.php。注意这里用分号间隔…

【总结】逻辑运算在Z3中运用+CTF习题

国际赛IrisCTF在前几天举办,遇到了一道有意思的题目,特来总结。 题目 附件如下:📎babyrevjohnson.tar 解题过程 关键main函数分析如下: int __fastcall main(int argc, const char **argv, const char**envp){int v4…

Golang | Leetcode Golang题解之第236题二叉树的最近公共祖先

题目: 题解: func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {parent : map[int]*TreeNode{}visited : map[int]bool{}var dfs func(*TreeNode)dfs func(r *TreeNode) {if r nil {return}if r.Left ! nil {parent[r.Left.Val] rdfs(r.L…

用 WireShark 抓住 TCP

Wireshark 是帮助我们分析网络请求的利器,建议每个同学都装一个。我们先用 Wireshark 抓取一个完整的连接建立、发送数据、断开连接的过程。 简单的介绍一下操作流程。 1、首先打开 Wireshark,在欢迎界面会列出当前机器上的所有网口、虚机网口等可以抓取…

气膜体育馆进校园:政策支持与市场前景—轻空间

过去20多年,气膜建筑、场馆相关项目在国内落地众多,展现出强大的市场潜力。2022年8月,《北京晚报》粗略统计,北京全市已建有气膜馆百余座,且数量还在不断增加。这一发展趋势不仅仅体现在北京,全国范围内也都…

微软GraphRAG +本地模型+Gradio 简单测试笔记

安装 pip install graphragmkdir -p ./ragtest/input#将文档拷贝至 ./ragtest/input/ 下python -m graphrag.index --init --root ./ragtest修改settings.yaml encoding_model: cl100k_base skip_workflows: [] llm:api_key: ${GRAPHRAG_API_KEY}type: openai_chat # or azu…

如何通过企业微信会话存档保护企业利益?

赵总: 张经理,最近行业内频发数据泄露事件,我们的客户资料和内部沟通记录安全吗? 张经理: 赵总,我们已经采取了一系列措施来加强数据安全。特别是针对企业微信的沟通记录,我们最近引入了安企神软件,它能很…

【BUG】已解决:AttributeError: ‘NoneType‘ object has no attribute ‘split‘

已解决:AttributeError: ‘NoneType‘ object has no attribute ‘split‘ 英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,…

通用图形处理器设计GPGPU基础与架构(四)

一、前言 本文将介绍GPGPU中线程束的调度方案、记分牌方案和线程块的分配与调度方案。 二、线程束调度 在计算机中有很多资源,既可以是虚拟的计算资源,如线程、进程或数据流,也可以是硬件资源,如处理器、网络连接或 ALU 单元。调…