STM32掌机教程3,工程模板与带灯按键测试

发布者:勾剑寒最新更新时间:2019-05-31 来源: eefocus关键字:STM32  掌机教程  工程模板与  按键测试 手机看文章 扫描二维码
随时随地手机看文章

我们需要“脚手架”

  关于代码,我想体现出这么一个过程:我是如何一步一步修改代码的。我认为,从学习的角度来考虑,直接看最终的代码没有什么意义。 写代码就像工人盖房子,盖房子过程中,工人要搭建脚手架;房子盖好以后,脚手架要拆除。直接领着学生看盖好的房子,说,你就照着这个样子来盖房子,学生是做不出来。他不知道怎么搭建脚手架,甚至都不知道什么是脚手架。 所以我打算这个系列的讲义,每一篇代码都在上一篇的基础上做一些改进,保留代码“进化”的过程。有些过程代码在最终的代码中不会体现,但是也很重要,就像房子盖好以后,你看不到脚手架一样。我们需要脚手架。

在这里插入图片描述

  目前用到的代码先用压缩包的形式上传,等教程写完以后,后续代码的维护使用Git。


各种初始化

  下载压缩包并打开工程以后,可以在main.c里找到主函数。目前为止,主函数进行了一些初始化,死循环内什么都没写,后续可以根据我们的需要写业务逻辑代码。


//main.c

int main(void)

{

LED_Init();

KEY_Init();

delay_init();

initIIC();

initOLED();

while(1)

{



}

}


LED与SLED的初始化

  函数的作用从名字就可以看出来,比较简单。例如LED的初始化。需要初始化哪个引脚,可以从电路图中看出。


在这里插入图片描述

//IO.c

void LED_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; 

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5; 

GPIO_Init(GPIOC, &GPIO_InitStructure);


AllLED_ON();

LED1 = LED_ON;

LED2 = LED_OFF;

}



  具体LED或者SLED对应的引脚可以在原理图中看出来。为了方便使用,我根据外设与引脚关系做了宏定义。


//IO.h

#define SLED1 PCout(0)

#define SLED2 PCout(1)

#define SLED3 PCout(2)

#define SLED4 PCout(3)

#define LED1 PCout(4)

#define LED2 PCout(5)

#define SLED5 PBout(12)

#define SLED6 PBout(13)

#define SLED7 PBout(14)

#define SLED8 PBout(15)

#define SKEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define SKEY2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)

#define SKEY3 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)

#define SKEY4 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)

#define SKEY5 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_6)

#define SKEY6 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_7)

#define SKEY7 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8)

#define SKEY8 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_9)


#define PAUSE GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)

#define BEEP PBout(1)


#define KEY1_PRES    1    //KEY1按下

#define KEY2_PRES    2    //KEY2按下

#define KEY3_PRES    3    //KEY3按下

#define KEY4_PRES    4    //KEY4按下

#define KEY5_PRES    5    //KEY5按下

#define KEY6_PRES    6    //KEY6按下

#define KEY7_PRES    7    //KEY7按下

#define KEY8_PRES    8    //KEY8按下

#define PAUSE_PRES   9


#define LED_ON  0

#define LED_OFF 1

#define DOWN  0 //按键按下

#define FREE  1


  然后编写了两个函数,用于点亮所有LED或者关闭所有LED


//IO.c

void AllLED_ON(void)

{

GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_ResetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);

}

void AllLED_OFF(void)

{

GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);

}


  这些代码。可能对于某些没有使用过STM32的同学来说不太好看懂,不过没有关系,可以仅仅应用的话,这是很简单的。在我之前的博客里也提过一些库函数的基础。例如设置某引脚为推挽输出GPIO_Mode_Out_PP ,不知道什么事推挽输出可以自己查一下。设置哪个引脚为推挽输出?PB12到PB15,PC0到PC5。

  再比如,让某个LED亮起来GPIO_ResetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);很容易看出来,这个操作是把PB12到PB15置为低电平,结合原理图可知,引脚低电平可以点亮LED。


按键初始化与扫描函数

  按键设置为上拉输入,检测到低电平,说明按键被按下。按键扫描函数课可以返回被按下的按键值。


void KEY_Init(void)  //PB0-PB3

{

GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/*

//PB3与PB4默认用作调试口,如果用作普通的IO,需要加上以下两句 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入

GPIO_Init(GPIOA, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 

GPIO_Init(GPIOB, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; 

GPIO_Init(GPIOC, &GPIO_InitStructure);

  

}

unsigned char KEY_Scan(unsigned char mode)

{    

static u8 key_up=1;//按键按松开标志

if(mode)key_up=1;  //支持连按          

if(key_up&&(SKEY1==DOWN||SKEY2==DOWN||SKEY3==DOWN||SKEY4==DOWN||SKEY5==DOWN||SKEY6==DOWN||SKEY7==DOWN||SKEY8==DOWN||PAUSE==DOWN))

{

delay_ms(10);//去抖动

key_up=0;

if(PAUSE==DOWN)return PAUSE_PRES;

else if(SKEY1==DOWN)return KEY1_PRES;

else if(SKEY2==DOWN)return KEY2_PRES;

else if(SKEY3==DOWN)return KEY3_PRES;

else if(SKEY4==DOWN)return KEY4_PRES;

else if(SKEY5==DOWN)return KEY5_PRES;

else if(SKEY6==DOWN)return KEY6_PRES;

else if(SKEY7==DOWN)return KEY7_PRES;

else if(SKEY8==DOWN)return KEY8_PRES;

}else if(SKEY1==FREE && SKEY2==FREE && SKEY3==FREE && SKEY4==FREE && SKEY5==FREE && SKEY6==FREE && SKEY7==FREE && SKEY8==FREE && PAUSE==FREE)key_up=1;         

return 0;// 无按键按下

}


其它初始化

  延时函数的初始化借用了别人的代码,就不贴了。

  0.96OLED屏幕用到了IIC总线,所以既需要初始化IIC总线,也需要初始化OLED屏幕。其实初始化的代码也不是我写的,借用的。有的读者可能会说,屏幕的初始化好像挺难的,我不知道这些初始化函数怎么写出来。这个问题很好解决——如果厂家不提供初始化的代码,我们不买它的屏幕就行了。谁提供代码,提供技术支持,我们选谁的屏幕。毕竟


  另外,对于定时器和蜂鸣器,我也写好了初始化代码。用到再说吧。


带灯按键检测

  在LED的初始化函数中,已经点亮了所有的带灯按键。如果按键上的灯不亮,就只能找硬件问题了。接下来写一小段测试代码,判断按键按下能否检测到。

  我的思路是,如果按下了某个按键,那么按键对应的LED灯状态翻转。STM32中,让引脚状态翻转其实是比较高阶的操作,原理比较复杂,感兴趣的可以搜下STM32的位带操作。但是用起来很简单,把寄存器当数据操作,假装寄存器可以取反。例如,LED1的状态取反LED1 = !LED1,如此操作,可以不用关心LED之前是亮是灭,看到的现象就是状态变了。

  我们可以写一个switch case语句,根据按键值来操作对应的LED。


while(1)

{

switch(KEY_Scan(0))

{

case PAUSE_PRES:

LED1 = !LED1;

LED2 = !LED2;

break;

case KEY1_PRES:

SLED1 = !SLED1;

break;

case KEY2_PRES:

SLED2 = !SLED2;

break;

case KEY3_PRES:

SLED3 = !SLED3;

break;

case KEY4_PRES:

SLED4 = !SLED4;

break;

case KEY5_PRES:

SLED5 = !SLED5;

break;

case KEY6_PRES:

SLED6 = !SLED6;

break;

case KEY7_PRES:

SLED7 = !SLED7;

break;

case KEY8_PRES:

SLED8 = !SLED8;

break;

default:

break;

}

}


  现象就是,上电以后,所有的按键灯都亮,如果按下某个按键,那么按键对应的灯状态翻转。



关键字:STM32  掌机教程  工程模板与  按键测试 引用地址:STM32掌机教程3,工程模板与带灯按键测试

上一篇:STM32掌机教程4,STM32驱动OLED屏幕
下一篇:STM32掌机教程2,掌机的原理

推荐阅读最新更新时间:2024-11-11 10:35

毕业设计| STM32单片控制的智能家居系统设计
☞ 智能家居系统功能概述 上面视频演示的STM32智能家居的功能是: ✔ 通过语音识别和上位机App进行控制 ✔ 实现有人闯入自动警报 ✔ 照明控制,温度和湿度控制,空气质量测量,家用电器定时和自动窗帘等功能的控制 主控是STM32F103RCT6单片机,连接到每个传感器。通过LD3320语音芯片生成语音信号到MCU的串口,在串口识别出发送的数据后,可以控制每个传感器,还通过蓝牙HC05将AT命令连接发送到手机App的控制端,进而控制家电。 ☞ 离线语音识别功能: 该功能的语音识别词分为两级: 第一级识别词:“小白”用来唤醒智能家居系统,此时LD3320的模块灯常亮。 第二级识别词用来控制“家居”,如:“开灯”“
[单片机]
毕业设计| <font color='red'>STM32</font>单片<font color='red'>机</font>控制的智能家居系统设计
关于STM32的com事件概念
COM事件是专门为电机控制用的,它只出现在高级定时器TIM1和TIM8中,普通定时器TIM2~TIM4没有COM事件。 COM事件是用于同时控制所有通道的输出转换,在电机控制中同时转换所有通道的输出是十分必要的 比如无刷电机换向时,一般是三相要同时换向的,但是你在软里设置换向时肯定是一次只能设置一相,这就达不到三相同时换向了不。其实简单的办法就是启用 STM32的COM事件,你先逐个设置好每相的换向(注意:此时虽然设置了,但实际上并不会进行换向),然后再调用COM事件,此时,三相将同时换向,就这么来的。阿呆版主,这够清楚了吧 COM事件发生在STM32的高级控制定时器(TIM1、TIM8)的 六步PWM的产生 ,而6-step P
[单片机]
基于语音识别的汽车空调控制系统设计
引言 现在汽车上使用的电器越来越多,驾驶员需要手动操作的电器开关也越来越多,不但增加了驾驶员的负担,还影响了行车安全。本文以STM32F103VET6(以下简称STM32)芯片为控制核心,采用高性能LD3320语音识别芯片,设计基于语音识别的汽车空调控制系统。该系统可以用语音有效控制汽车空调,减轻了驾驶员的操作负担,保证行车过程中的安全。 1 系统硬件设计 运用语音识别技术,结合各种传感器对车身内外的环境(如气温、阳光强度等)以及制冷压缩机的状态等多种参数进行实时检测,与设定参数相比较,微控制器经过运算处理做出判断,输出相应的调节和控制信号。执行机构经过实时调整和修正,实现对车厢内空气环境全方位、多功能的调节和控制。系统的
[单片机]
基于语音识别的汽车空调控制系统设计
为什么STM32从Flash地址0x08000000的启动重映射
在初写STM32程序时,遇到一个困惑,STM32的Flash在MDK里被设置为起始地址0x0800 0000,而CM3手册规定芯片复位时要从0x0000 0000地址开始取出中断向量 ,那STM32怎么样执行代码呢?地址重映射?或者在0x0000 0000里有对应有实际存储器? 仔细阅读手册,发现这件事是因为STM32设计的Flash起始地址是在0x0800 0000位置开始的。全部代码都只能从这里开始存储。详见STM32 referenc manual手册第54页。 那既然从这里才能存储代码,就必须在MDK里设置Flash地址为0x0800 0000,下面是MDK设置页面,这个应该都看到过。 这样就还有一个问题,理论上,CM3
[单片机]
STM32单片寄存器的位置是如何定义的
一直都是用STM32做项目中的主控芯片,在编程的时候,之前一直忽视了一个问题,那就是寄存器的位置是如何定义的,为什么用一个USART1-》CR操作就能够给这个CR寄存器赋值?其实这是一个比较底层的问题,不懂这方面的知识也并不影响使用STM32,因为底层的定义工作,厂家一般都会做好,但是多了解一点原理性的东西,对自己还是很有帮助的。 这里我就以STM32F407的USART寄存器为例,介绍一下ST厂家是如何做寄存器定义的。 首先在stm32f4xx.h中 typedefstruct { __IOuint16_tSR;/*! uint16_tRESERVED0;/*! __IOuint16_tDR;/*! uint16_tRESE
[单片机]
基于STM32 MCU应用的EMC指南之软件篇
在基于微控制器的电子系统中,强壮的软件设计是提高 EMC 性能的主要因素。必须尽量在项目设计阶段的早期考虑 EMC 干扰导致的问题。EMC 导向的软件提高了应用的安全性和可靠性。强化 EMC 性能的软件的实施成本低,可提高最终的抗扰性能,并节约硬件和开发成本。用户应考虑到模拟或数字数据受到的 EMC 干扰,就像任何其它应用参数一样。 EMC 干扰导致的问题示例: 微控制器无响应 程序计数器失控 执行意外指令 地址指向错误 子程序执行错误 寄生复位和 / 或寄生中断 IP 配置损坏 I/O 失灵 软件故障的后果示例: 产品意外响应 上下文丢失 进程中的意外分支 中断丢失 数据完整性缺失 输入值误读 01使用看门狗或时间控制 为了
[单片机]
基于<font color='red'>STM32</font> MCU应用的EMC指南之软件篇
STM32-(SysTick定时器,EXTI外部中断/事件控制器)
Systick系统定时器 介绍:systick定时器上属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24位向下计数的计数器,计数器每一次计数的时间是1/SYSTICK,一般我们设置SYSTICK为72M。当重载数值寄存器的值递减到0时,系统定时器产生一次中断,以此循环。 使用范围:1.一般用于操作系统,用于产生时基,维持操作系统的心跳。 使用的寄存器:CTRL,LOAD,VAL,CALIB; 例程1:利用systick产生1s的时基。 步骤: 1.设置重载寄存器的值 2.清除当前数值寄存器的值 3.配置控制于状态寄存器 systick配置库函数: _STATIC_INLINE uint32_t
[单片机]
STM32-(SysTick定时器,EXTI外部中断/事件控制器)
教室智能照明控制系统的设计说明
摘要:针对室内不同区域对于光照强度的不同要求,设计了一个利用STM32作为控制器的教室智能照明控制系统,能够依据室内照明强度以及室内人员分布情况对教室内光照强度进行实时,动态的调整。结果表明,该系统既可以保证教室内的光照强度充足,又不会造成电力浪费。 0. 引言 在学校的每个教室里,照明设备都是不可或缺的。然而,有时会见到某个空无一人的教室灯火通明,或者在白天室外阳光强烈,无需开灯的情况下,教室里的灯却开着。这些情况都造成了很大的浪费。因此,教室智能照明控制系统要能够依据室内光照强度以及室内人员分布情况对教室内光照强度进行实时,动态的调整,既使得教室内的光照强度充足,又不会造成电力浪费。 1. 系统的总体设计 教室智能照明
[单片机]
教室智能照明控制系统的设计说明
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved