目录
第3篇: 辉芒微教程第三篇《IO口输入设置与按键切换继电器状态》
第4篇: 辉芒微教程第四篇《EEPROM-断电记忆开关状态》
第6篇: 辉芒微教程第六篇《定时器1和定时器2多个定时器混用》
第7篇: 辉芒微教程第七篇《PWM是什么与PWM3调节LED灯的亮度》
第8篇: 辉芒微教程第八篇《PWM4/PWM5调节舵机的角度》
第9篇: 辉芒微教程第九篇《模拟串口打印数据》
第10篇:辉芒微教程第十篇《矩阵键盘与串口打印按下数据》
第11篇:辉芒微教程第十一篇《ADC读取电压数据并且打印出来》
第12篇:辉芒微教程第十二篇《睡眠模式与待机省电计算》
第13篇:辉芒微教程第十三篇《按键外部中断唤醒》
第14篇:辉芒微教程第十四篇《IIC协议与读写24C02》
第15篇:辉芒微教程第十五篇《SPI协议与读取W25Q64》
第16篇:辉芒微教程第十六篇《IR红外发射》
第17篇:辉芒微教程第十七篇《IR红外接收》
第18篇:辉芒微教程第十八篇《防芯片运行宕机-看门狗》
第19篇:辉芒微教程第十九篇《有用的废话篇-项目综合开发的书写习惯》
第20篇:辉芒微教程第二十篇《有用的废话篇-怎么进行辉芒微软件上的量产工作》
第21篇:辉芒微教程第二十一篇《有用的废话篇-芯片选型+获取资料+如何读数据手册》
前言
本篇章将讲解如何配置IO为输入模式,并且通过消抖后的按键,来控制继电器模块的开关。由于我们的板子没有继电器电路,所以我购买了继电器模块给大家演示效果。
一、分析电路原理
(1)继电器
继电器是一种利用电磁感应、机电或电子元件来实现自动切换电路的装置。它的核心功能是通过较小的电流或电压信号来控制较大功率的电路,起到 “开关” 的作用,同时还能实现电路的保护、控制和信号转换。
这里我们使用外接的继电器,这个继电器是5V供电,所以我们需要接继电器的VCC和GND接到板子上的5-12V脚和GND脚,并且将IN3接到PA3脚,用于驱动继电器的信号。
外接继电器管脚对应接法
开发板 | 继电器 | |
1 | 5~12V管脚 | VCC |
2 | GND | GND |
3 | PA3管脚 | IN |
(2)按键
按键我们使用板载的按键,按键是直接接地的,没有做硬件消抖,因此程序上我们要做软件消抖,并且对应的IO口,PC2我们要做内部上拉,让其平时处于高电平状态,只要按键按下,就变成低电平。
当你完成程序下载后,我们断开板子和烧录器的连接,并且插入5V电源到DC母座,注意!注意!注意!当外部接入电源的时候,一定要断开板子和烧录器的连接,不然程序会有种死机的感觉!!!
二·、继电器开、关的尝试
#include "SYSCFG.h" //这个芯片的必要头文件
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time us
* 返回参数:无
-------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无
-------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
void interrupt ISR(void) //中断函数,本节无需要
{
}
void SingleChipConfig(void) //单片机配置函数
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2T=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B00000000; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
MSCKCON = 0B00000000;
//Bit6->0,禁止PA4,PC5稳压输出
//Bit5->0,TIMER2时钟为Fosc
//Bit4->0,禁止LVR
CMCON0 = 0B00000111; //关闭比较器,CxIN为数字IO口
}
void main(void) //主函数
{
SingleChipConfig();
while(1)
{
PA3 = 1; //使PC4端口输出高电平(1:高电平,0:低电平)
DelayMs(1000);
PA3 = 0;
DelayMs(1000);
}
}
这里我们结合上节课所学的IO输出配置方式,配置我们的PA3为高电平,然后另PA3 = 1输出高电平,等待一秒后,输出低电平,再等待一秒后输出....,不停地这样,把程序下载到板子上,就可以听到滴答滴答的继电器响声,就代表实验成功了。
三、为什么按键需要消抖
机械按键在按下和释放的瞬间,触点不会立即稳定接触或断开,而是会经历一段短暂的高频振动过程,这种现象称为 “按键抖动”。
(你想象的按键按下去瞬间的电平变化) (实际电平变化)
按键按下去的瞬间电平是紊乱的,大概20毫秒左右电平会变得稳定,因此我们需要进行判断两次,第一次判断为低电平后,等待20-50毫秒,再判断第二次电平是否为低电平,如果还为低电平,则进行对应的动作。
四、按键控制继电器实验编程
明白原理之后,我们接下来要编写一个程序,当按下按键的时候,继电器打开,再次按下继电器关闭...如此循环。在IO口输入的时候,由于我们按键是PC2,所以WPUC要配置为0B00000100,即配置PC2为上拉输入模式。
但是,光配置WPUC没用,我们一定要知道一个巨坑!巨坑! 巨坑!
这个巨坑,曾经让我写程序,找了一整个下午的问题,我把烧录器的问题,电脑的问题,代码的问题统统怀疑了一个遍,如果不是我们公司有芯片代理商提供技术支持,我还真找不出问题。如果你没看我文章,并且遇到了这个问题,恭喜你被坑了,因为即使你是懂STM32的也好,51的也好,都不会压根怀疑到这个问题的。
辉芒微的8位系列芯片有三种,一种是普通IO口系列的,一种是AD系列的,一种是Touch系列的,而我们使用的芯片就是AD系列的,AD顾名思义就是能够进行AD采集,例如进行电压采集,获取某个管脚的电压值。
在芯片手册中,写着AN0,AN1...AN6这些代表不同通道的ADC,这里如果新手不知道ADC是啥,我们暂且不去深入了解这个东西,但是要注意这个坑,凡是写着ANx管脚,如果你不配置,它默认设置是关闭上拉/下拉及数字输入!!!说人话就是比如说没有办法通过WPUC寄存器配置上下拉,例如你配置了按键上拉输入也没用。
这个是我从数据手册里面截取到的寄存器信息,默认是关闭的数字输入的,因此我们需要对这个寄存器进行配置。
默认ANSEL = 0B11111111,每个位从左到右代表AN7-AN0,如果需要用到哪个通道的ADC,就把对应的位置1,不用则置0,置0则不关闭上下拉输入,只有置0,我们才能配置按键输入。
在下面的代表中,由于我们这几节课都用不到ADC,我们把所有的ADC都取消掉。每个位配置为0,即ANSEL = 0B00000000;
#include "SYSCFG.h" //这个芯片的必要头文件
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time us
* 返回参数:无
-------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无
-------------------------------------------------*/
void DelayMs(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
void interrupt ISR(void) //中断函数,本节无需要
{
}
void SingleChipConfig(void) //单片机配置函数
{
OSCCON = 0B01110001; //IRCF=111=16MHz/2T=8MHz,0.125us
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B00000000; //PA输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B00000100; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000100; //PC端口上拉控制 1-开上拉 0-关上拉
OPTION = 0B00001000; //Bit3=1,WDT MODE,PS=000=WDT RATE 1:1
MSCKCON = 0B00000000;
//Bit6->0,禁止PA4,PC5稳压输出
//Bit5->0,TIMER2时钟为Fosc
//Bit4->0,禁止LVR
CMCON0 = 0B00000111; //关闭比较器,CxIN为数字IO口
ANSEL = 0B00000000;
}
void main(void) //主函数
{
SingleChipConfig();
while(1)
{
if(!PC2)
{
DelayMs(50);
if(!PC2)
{
PA3 = !PA3;
while(PC2 == 0)
{
};
}
}
}
}
在while循环里面,我做了软件消抖,即如果PC2为低电平,再等待50毫秒后继续判断是否为低电平,如果为低电平,则将继电器的管脚PA3取反,则可以通过一个按键进行继电器的开关。
(注意:!PC2等同于PC2==0)
在最后,我们可以将ANSEL = 0这段代表注释掉看看效果,你会发现即使配置了上拉输入,PC2按键管脚没有按下去的时候,电压接近0V,而非3.3V。所以,对于辉芒微的AD芯片系列,我们一定要配置ANSEL管脚,否则我们的输入管脚将会无效!!!