当前位置: 首页 > news >正文

STM32实战之LED循环点亮

接着上一章讲。本章我们来讲一讲LED流水灯,循环点亮LED。
在LED章节有的可能没有讲到,本章会对其进行说明,尽量每个函数说一下作用。也会在最后说一下STM32的寄存器,在编程中寄存器是避免不了的东西,寄存器也是非常好理解的,就是羊肉串串成一串而已。其实对于嵌入式来说,大多数开发者都是根据官方提供的例程写的。很少只有手册让个人写的。只有做芯片底层开发的会根据,芯片的逻辑进行代码的编写。但是对于很多开发者来说,都是基于官方提供的芯片demo进行相关的底层配置与开发。
而我们要写的主要是应用层和一些模块底层的开发。而且多数的外设模块都有代码例程,即使没有文档也是较为清楚的。什么样的没有代码的,就是新出的芯片或者传感器,笔者做过恩智浦的一款新出的包括近期做一个芯驰的开发。网上资料少得可怜,只能参考官方例程。特别是芯驰的是去年10月份刚出的,他们的东西会出现各种问题,网上找不到,但是你也不要慌,他们会提供技术支持的,会告诉你怎么做。这些新出的东西,遇到了不要觉得是自己的问题,有可能是他们芯片或者demo的问题,就像近期做芯驰的开发板demo,调试,只有静置一段时间才可以(就是断电,全部断掉,等一会,这就是他们的问题),所以遇到问题不要怕。
对了,我写实战是根据F1的,和F4的本质都差不多。

1-配置

static void Led_Cofig(void)
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启LED相关的GPIO外设时钟*/RCC_APB2PeriphClockCmd(LED_GPIO_CLCK, ENABLE);/*选择要控制的GPIO引脚*/GPIO_InitStructure.GPIO_Pin = (LED1_GPIO_PIN | LED2_GPIO_PIN | LED3_GPIO_PIN | LED4_GPIO_PIN | LED5_GPIO_PIN | LED6_GPIO_PIN | LED7_GPIO_PIN | LED8_GPIO_PIN);/*设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*设置引脚速率为50MHz */GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //(指的是内部驱动电路的响应速度,速度越大越快,一般情况是有多个不同的速度,也可根据自己的需要安排)GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);/* 关闭led灯	*/GPIO_SetBits(LED_GPIO_PORT, LED1_GPIO_PIN | LED2_GPIO_PIN | LED3_GPIO_PIN | LED4_GPIO_PIN | LED5_GPIO_PIN | LED6_GPIO_PIN | LED7_GPIO_PIN | LED8_GPIO_PIN);
}

1.1 RCC_APB2PeriphClockCmd()函数

RCC_APB2PeriphClockCmd()函数的功能是使能GPIOx对应的外设时钟,若使能GPIOC时钟,对应的代码如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

RCC_APB2Periph_GPIOC是在stm32f10x_rcc.h头文件中定义的。RCC_APB2Periph_GPIOA~RCC_APB2Periph_GPIOG定义的代码如下:

#define RCC_APB2Periph_GPIOA      ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB      ((uint32_t)0x00000008) 
#define RCC_APB2Periph_GPIOC      ((uint32_t)0x00000010) 
#define RCC_APB2Periph_GPIOD      ((uint32_t)0x00000020) 
#define RCC_APB2Periph_GPIOE      ((uint32_t)0x00000040) 
#define RCC_APB2Periph_GPIOF      ((uint32_t)0x00000080) 
#define RCC_APB2Periph_GPIOG      ((uint32_t)0x00000100)

1.2 GPIO_Init()函数

GPIO_Init()函数的功能是初始化(配置)GPIO的模式和速度,也就是设置相应GPIO的CRL和CRH寄存器值。函数原型如下所示:

GPIO_Init()函数的功能是初始化(配置)GPIO的模式和速度,也就是设置相应GPIO的CRL和CRH寄存器值。

第一个参数是GPIO_TypeDef类型指针变量,用于确定是哪一个GPIO,GPIOx取值是GPIOA~GPIOG;第二个参数是GPIO_InitTypeDef类型指针变量,用于确定GPIOx的对应引脚以及该引脚的模式和速度等。

1.3 GPIO_ReadInputDataBit ()函数

GPIO_ReadInputDataBit ()函数的功能是读取指定I/O口的对应引脚值,也就是读取IDR(在下面会介绍)寄存器的值。函数原型是:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

第一个参数同GPIO_Init()函数一样,第二个参数是读取GPIOx的对应引脚值。如读取GPIO6(即PC6)引脚代码是:

GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);

1.4 GPIO_ReadInputData ()函数

GPIO_ReadInputData()函数的功能是读取指定I/O口16个引脚的输入值,也是读取IDR寄存器的值。函数原型如下:

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

比如读取GPIOC输入端的值:

tem=GPIO_ReadInputData(GPIOC);
但是如果采用寄存器的话就是:
tem=GPIOC->IDR

1.5 GPIO_ReadOutputDataBit ()和GPIO_ReadOutputData ()函数对比

这两个函数从字面就能知道一个是对单独的IO进行操作,一个是对多个IO进行操作,下面就对这两个进行分析。

//读取GPIO某个引脚的特定输出值。
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);例如:读取GPIOC中PC6的值
GPIO_ReadOutputDataBit(GPIOC.GPIO_Pin_6);
//读取GPIO端口指定组的值。
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
比如读取GPIOC的值:
GPIO_ReadOutputData( GPIOC);

1.6 GPIO_SetBits ()和GPIO_ResetBits ()函数

上一章已经说过了,本章不在多说。
函数GPIO_SetBits ()和GPIO_ResetBits ()的功能是用来设置指定I/O口的引脚输出高电平和低电平,也就是设置寄存器BSRR、BRR的值。

1.7 GPIO_WriteBit ()和GPIO_Write ()函数

这两个函数和1.5的类型是一样的。非别是对单个IO和一组IO控制,后面遇到这样的不在赘述,默认大家都知道。
GPIO_WriteBit ()函数的功能是向指定I/O口的引脚写0或者写1,也就是向寄存器ODR相应位写0或者写1。函数原型如下:

void GPIO_WriteBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin, BitAction BitVal);

GPIO_Write()函数的功能是向指定I/O口写数据,也就是向寄存器ODR写数据。函数原型如下:

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

举例:

//向PC6写入1
GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1);
//向GPIOC写入 0x0FFFC
GPIO_Write(GPIOC, 0x0FFFC);

在这里需要注意一点:
GPIO_WriteBit()函数是对I/O口的一个引脚进行写操作,可以是写0或者写1;
GPIO_SetBits()函数可以对I/O口的多个引脚同时进行置位。
这点大家一定要知道。

GPIO_WriteBit(GPIOC,GPIO_Pin_8 , 0);             //只能对一个引脚置0或置1
GPIO_SetBits(GPIOC, GPIO_Pin_2 | GPIO_Pin_4);    //可以同时对多个引脚置1

``

2 循环点亮LED

我设计的是8个流水灯,采用共阳极的接法,与PC1~7相连接。因为32不像51有移位控制语句。
先来看代码吧,这可以说是非常基础的了,为了方便大家理解。

void LED_Cycle(void)
{uint16_t temp, i;temp = 0x01;for (i = 0; i < 8; i++){GPIO_Write(LED_GPIO_PORT, ~temp);Delay(300);temp = temp << 1;}for (i = 0; i < 8; i++){GPIO_Write(LED_GPIO_PORT, ~temp);Delay(300);temp = temp >> 1;}
}

首先我们从GPIOC0开始点亮这样一直循环下去:PC0点亮此位为0,依次类推如下:

PC0亮:PC输出 0x0001,取反为0xFFFE,控制码就是0xFFFE
PC1亮:PC输出 0x0002,取反为0xFFFD,控制码就是0xFFFD
PC2亮:PC输出 0x0004,取反为0xFFFB,控制码就是0xFFFB
PC3亮:PC输出 0x0008,取反为0xFFF7,控制码就是0xFFF7
PC4亮:PC输出 0x0010,取反为0xFFEF,控制码就是0xFFEF
PC5亮:PC输出 0x0020,取反为0xFFDF,控制码就是0xFFDF
PC6亮:PC输出 0x0040,取反为0xFFBF,控制码就是0xFFBF
PC7亮:PC输出 0x0080,取反为0xFF7F,控制码就是0xFF7F
然后重复执行。

根据上面的,只需将控制码从GPIOC输出即可。怎样输出呢,就是出事一位为高然后进行取反操作,在对其进行移位,然后进行循环操作(方法不止这一种,可尝试其他方式)。
“GPIO_Write(GPIOC,~temp);”语句将初始控制码0x0001取反(也就是0xFFFE)后,从GPIOC口输出,使得PC为低电平,点亮PC0,其他位为高电平;然后延时一段时间;让控制码移位,获得下一个控制码;然后再对控制码取反后输出到GPIOC口,就这样依次进行。

主函数

int main()
{LED_Init();while (1){LED_Cycle();}
}

今天太晚了,哪天腾出一章用来写各个寄存器,本来是想和库函数穿插这说的。又考虑到,有些人对寄存器不太熟悉,穿插着对其不太友好。今天就到这了,喜欢就动动手一键三连,谢谢。

相关文章:

STM32实战之LED循环点亮

接着上一章讲。本章我们来讲一讲LED流水灯&#xff0c;循环点亮LED。 在LED章节有的可能没有讲到&#xff0c;本章会对其进行说明&#xff0c;尽量每个函数说一下作用。也会在最后说一下STM32的寄存器&#xff0c;在编程中寄存器是避免不了的东西&#xff0c;寄存器也是非常好理…...

智慧厕所智能卫生间系统有哪些功能

南宁北站智能厕所主要功能有哪些&#xff1f;1、卫生间环境空气监测男厕、女厕环境空气监测系统包括对厕所内的温度、湿度、氨气、硫化氢、PM2.5、烟雾等气体数据的实时监测。2、卫生间厕位状态监测系统实时监测厕位内目前的使用状态(有人或无人&#xff09;&#xff0c;数据信…...

【网络】套接字 -- TCP

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【网络】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文章…...

NDK C++ map容器

map容器// TODO map容器 #include <iostream> #include <map>using namespace std;int main() {// TODO map<int, string>按key值排序&#xff0c;同一个key不可以重复插入map<int, string> map1;map1.insert(pair<int, string>(1, "111&qu…...

linux(Centos)安装docker

官网地址&#xff1a;Install Docker Engine on CentOS 首先检查linux系统版本及内核&#xff1a; 安装docker要求系统版本至少为7.x版本&#xff0c;内核至少为3.8以上 cat /etc/redhat-release # 查看系统版本号uname -r #查看linux系统内核 检查系统是否能连上外网&#…...

Delphi 中 FireDAC 数据库连接(处理错误)

参见&#xff1a;Delphi 中 FireDAC 数据库连接&#xff08;总览&#xff09;本主题描述了如何用FireDAC处理数据库错误。一、概述EFDDBEngineException类是所有DBMS异常的基类。单个异常对象是一个数据库错误的集合&#xff0c;可以通过EFDDBEngineException.Errors[]属性访问…...

算法小抄3-理解使用Python容器之列表

引言 首先说一个概念哈,程序算法数据结构,算法是条件语句与循环语句组成的逻辑结构,而数据结构也就是容器. 算法决定数据该如何处理,而容器则决定如何数据如何存储. 不同的语言对容器有不同的实现方式, 但他们的功能都是相似的, 打好容器基础,你就可以在各式各样的语言中来回横…...

Vue3中watch的value问题

目录前言一&#xff0c;ref和reactive的简单复习1.ref函数1.2 reactive函数1.3 用ref定义对象类型数据不用reactive二&#xff0c;watch的value问题2.1 ref2.1.1 普通类型数据2.1.2 对象类型数据2.1.3 另一种方式2.2 reactive三&#xff0c;总结后记前言 在Vue3中&#xff0c;…...

【线性筛+DP】最大和

看错题了&#xff0c;呃呃&#xff0c;其实就是个简单DP最大和 - 蓝桥云课 (lanqiao.cn)题意&#xff1a;思路&#xff1a;设dp[i]为以1为终点的最大和&#xff0c;然后枚举状态和决策就行了主要是线性筛的应用&#xff0c;它可以预处理出一个数的最小质因子是多少Code&#xf…...

openpnp - configure - 丢弃(Discard)位置的设置

文章目录openpnp - configure - 丢弃(Discard)位置的设置概述笔记设置丢弃位置吸取元件失败后, 吸嘴一直吸气的处理ENDopenpnp - configure - 丢弃(Discard)位置的设置 概述 测试时, 吸取了一个元件, 吸取成功了, 现在想将这个料丢掉. 点击控制面板-Special页中的Discard不好…...

java Object 万字详解 (通俗易懂)

基本介绍构造方法成员方法hashCode()getClass()toString()equals()finalize()JavaBean重写Object类的方法重写toString重写equals一、基本介绍Object类是java类层次最顶层的基类&#xff08;父类&#xff09;&#xff0c;所有类都是直接或间接继承自Object类&#xff0c;因此&a…...

Java并发简介(什么是并发)

文章目录并发概念并发和并行同步和异步阻塞和非阻塞进程和线程竞态条件和临界区管程并发的特点提升资源利用率程序响应更快并发的问题安全性问题缓存导致的可见性问题线程切换带来的原子性问题编译优化带来的有序性问题保证并发安全的思路互斥同步&#xff08;阻塞同步&#xf…...

团队API管理工具-YAPI

团队API管理工具-YAPI 推荐一款接口管理平台&#xff0c;操作简单、界面友好、功能丰富、支持markdown语法、可使用Postman导入、Swagger同步数据展示、LDAP、权限管理等功能。 YApi是高效、易用、功能强大的api管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接…...

学习记录 --- Pytorch优化器

文章目录参考文献什么是优化器optimizer的定义optimizer的属性defaultsstateparam_groupsoptimizer的方法zero_grad()step()add_param_group()state_dict()、load_state_dict()优化一个网络同时优化多个网络当成一个网络优化当成多个网络优化只优化网络的某些指定的层调整学习率…...

Flink State 状态后端分析

flink状态实现分析 state * State* |* -------------------InternalKvState* | |* MergingState |* | |* …...

和年薪30W的阿里测开工程师聊过后,才知道我的工作就是打杂的...

前几天和一个朋友聊面试&#xff0c;他说上个月同时拿到了腾讯和阿里的offer&#xff0c;最后选择了阿里。 阿里内部将员工一共分为了14个等级&#xff0c;P6是资深工程师&#xff0c;P7是技术专家。 其中P6和P7就是一个分水岭了&#xff0c;P6是最接近P7的不持股员工&#x…...

C#开发的OpenRA的界面布局数据加载

C#开发的OpenRA的界面布局数据加载 当显示完成加载界面之后,就是进行其它内容处理。 因为后面内容的加载会比较长时间,所以首先显示加载界面是一种非常友好的方法。 因此在软件设计里,尽可能先显示界面,让用户先看到程序正在运行, 然后再处理时间长的加载。如果不这样做,…...

并查集结构

文章目录并查集特点构建过程查找两个元素是否是同一集合优化查找领头元素设置两个元素为同一集合构建结构应用场景并行计算集合问题并查集特点 对于使用并查集构建的结构&#xff0c;可以使得查询两个元素是否在同一集合&#xff0c;以及合并集合的操作无限接近O(1) 构建过程…...

全国CSM敏捷教练认证将于2023年3月25-26开班,报名从速!

CSM&#xff0c;即Certified Scrum Master&#xff0c;是Scrum联盟发起的Scrum认证。 CSM可以帮助团队正确使用Scrum&#xff0c;从而提高项目整体成功的可能性。 CSM深刻理解Scrum的价值观、实践以及Scrum框架。 CSM是“服务型领导”&#xff0c;帮助Scrum团队一起紧密合作。 …...

JavaEE进阶第六课:SpringBoot ⽇志⽂件

上篇文章介绍了SpringBoot配置文件&#xff0c;这篇文章我们将会介绍SpringBoot ⽇志⽂件 荔枝1.日志有什么用2.自定义日志输出2.1获取程序日志对象2.2使用相关方法输出日志2.3日志级别2.3.1日志级别的作用2.3.2日志级别如何设置2.4日志格式3.持久化日志4.更简单的日志输出4.1使…...

外置MOS管平均电流型LED降压恒流驱动器

产品描述 AP5125 是一款外围电路简单的 Buck 型平均电 流检测模式的 LED 恒流驱动器&#xff0c;适用于 8-100V 电压 范围的非隔离式大功率恒流 LED 驱动领域。芯片采用 固定频率 140kHz 的 PWM 工作模式&#xff0c; 利用平均电 流检测模式&#xff0c;因此具有优异的负载调整…...

python+pytest接口自动化(6)-请求参数格式的确定

我们在做接口测试之前&#xff0c;先需要根据接口文档或抓包接口数据&#xff0c;搞清楚被测接口的详细内容&#xff0c;其中就包含请求参数的编码格式&#xff0c;从而使用对应的参数格式发送请求。例如某个接口规定的请求主体的编码方式为 application/json&#xff0c;那么在…...

开发手册——一、编程规约_3.代码格式

这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】大括号的使用约定。如果是大括号内为空&#xff0c;则简洁地写成{}即可&#xff0c;不需要换行&#xff1b;如果是非空代码…...

十七、Django-restframework之序列化器(二)

1. 序列化器 REST framework提供了一个serializer类&#xff0c;它可以非常方便的序列化模型实例和查询集为JSON或者其他内容形式。它还提供反序列化&#xff0c;允许在验证传入数据后将解析的数据转换回复杂类型。 2. 定义序列化器 在crm应用目录下创建serializers.py文件&a…...

python GUI图形化编程-----wxpython

一、python gui&#xff08;图形化&#xff09;模块介绍&#xff1a; Tkinter :是python最简单的图形化模块&#xff0c;总共只有14种组建 Pyqt :是python最复杂也是使用最广泛的图形化 Wx :是python当中居中的一个图形化&#xff0c;学习结构很清晰 Pywin :是pyth…...

【Python 】yyyy-MM-dd HH:mm:ss 时间格式 时间戳 全面解读超详细

时间格式 时间格式(协议)描述gg时期或纪元。y不包含纪元的年份。不具有前导零。yy不包含纪元的年份。具有前导零。yyyy包含纪元的四位数的年份。M月份数字。一位数的月份没有前导零。MM月份数字。一位数的月份有一个前导零。MMM月份的缩写名称&#xff0c;在AbbreviatedMonthN…...

【C++】C++11 异常

目录 1. C语言传统的处理错误的方式 2. C异常概念 3. 异常的使用 3.1. 异常的抛出和捕获 3.2. 在函数调用链中异常栈展开匹配原则 3.3. 异常的重新抛出 3.4. 异常安全 3.5. 异常规范 4.自定义异常体系 5. C标准库的异常体系 6. 异常的优缺点 6.1. C异常的优点&…...

关于Thread.start()后的困惑、imap

在for循环中&#xff0c;接着开thread&#xff0c;开完就start&#xff0c;当时有个困惑&#xff0c;就是比如开的一个thread的这个start执行完&#xff0c;但是这个for循环还没执行完&#xff0c;那程序会跑到for循环的后面逻辑吗&#xff1f;比如下面13行for循环开始开第一个…...

qml学习之qwidget与qml结合使用并调用信号槽交互

学习qml系列之一说明&#xff1a; 学习qml系列之qwiget和qml信号槽的交互使用&#xff0c;并在qwidget中显示qml界面 在qml中发送信号到qwidget里 在qwidget里发送信号给qml 在qwidget里面调用qml界面方式 方式一&#xff1a;使用QQuickView 这个是Qt5.0中提供的一个类&…...

【 华为OD机试 2023】 组装新的数组(C++ Java JavaScript Python)

文章目录 题目描述输入描述输出描述备注用例题目解析C++JavaScriptJavaPython题目描述 给你一个整数M和数组N,N中的元素为连续整数,要求根据N中的元素组装成新的数组R,组装规则: R中元素总和加起来等于MR中的元素可以从N中重复选取R中的元素最多只能有1个不在N中,且比N中…...

提供网站建设工具的公司/seo网站优化方案书

自定义注解 Target 自定义注解的使用范围 ElementType.METHOD&#xff1a;方法声明 ElementType.TYPE&#xff1a;类、接口&#xff08;包括注解类型&#xff09;或enum声明 ElementType.CONSTRUCTOR&#xff1a;构造器的声明 ElementType.FIELD&#xff1a;域声明&#xff0…...

做服务器的网站都有哪些功能/项目推广平台有哪些

触控科技CocoaChina2013秋季开发者大会今日在北京国家会议中心召开&#xff0c;触控科技CEO陈昊芝围绕“2013、2014、2015”为主题对中国手游行业的现在以及将来做了自己的分析与预测。 轻量级游戏是趋势 今年触控科技将重启大规模营销&#xff0c;近期成为“中国好声音”的标王…...

常用的网络营销推广方法有哪些/百度搜索结果优化

代码版本控制对于我们嵌入式软件开发岗是一项基础、必备的技能&#xff0c;需要熟练掌握。实际工作中常用的版本控制系统有&#xff1a;Git(分布式版本控制系统)与SVN(集中式版本控制系统)。本次分享Git在实际工作中的基本使用方法。一、Git的下载、安装及配置1、Git与Github&a…...

大学网站建设专业/百度查询入口

printf输出函数printf输出函数printf输出函数 printf 函数称为格式输出函数&#xff0c;其关键字最末一个字母 f 即为“格式”(format)之意。 其功能是按用户指定的格式&#xff0c;把指定的数据显示到显示器屏幕上。 printf 函数调用的一般形式 printf 函数是一个标准库函数…...

html网站登录界面模板下载/百度seo关键词报价

今天&#xff0c;IBM 与西安电子科技大学&#xff08;简称&#xff1a;“西电”&#xff09;签署协议&#xff0c;将基于西电的分析云中心开展全面的科学研究、行业应用创新及相关人才培养的合作。西安电子科技大学校长助理高新波教授&#xff0c;IBM大中华区硬件开发实验室副总…...

城乡建设委员会网站/站长工具seo词语排名

广州疯狂软件学院拥有三大课程体系包括&#xff1a;java课程&#xff0c;android课程&#xff0c;ios课程&#xff0c;疯狂软件年终钜惠&#xff0c;报名java就业班&#xff0c;免费赠送基础班&#xff0c;名额有限&#xff0c;本月火热报名中&#xff0c;欢迎有志之士电话或者…...