2019-03-24 09:37发布
qiushenghua 发表于 2015-12-17 11:38 如果是我来写这段程序,首先我就不会增加那么多的delay_ms函数。因为你这用的MSP430是低功耗MCU,所以我会 ...
最多设置5个标签!
再说说处理按键,我会使用一个全局变量Key_State来储存当前按键按下的信息,使用静态变量Last_Key_State来记住上一按键状态信息。使用unsigned char类型,那么一个变量能储存8个按键的信息。
在采集按键前,将Key_State存进Last_Key_State,然后更新Key_State。如果Last_Key_State与Key_State的某位不同,说明该位代表的按键经历过变动。当然这个变动可能是按键按下也可能是按键弹起。
在消抖这件事情上,可以通过这样的方式来做:连续两个采样周期采集到的按键状态一致。如果满足这个条件,那么我们完全可以认为按键没有抖动。当然,两个按键采样周期之间的时间间隔需要大于10ms。
楼主不妨贴出完整的代码(文本而不是图片),和硬件连接等信息,这样我们可以在楼主代码基础上改动,也更容易找出问题所在。另外,我们尚且未知楼主的MCU的具体型号,很多判断均基于本版是MSP430版,既然楼主在本版发帖,那么使用的就是MSP430MCU这一假设做出,即便如此,MSP430不同系列不同型号之间也存在差异,仍可能存在判断不准确的情形。
因为我的这个实验是创新实验,我是第一次使用430来做实验,之前也并没有做过什么芯片,对这些都不大熟悉。只是会在别人的程序上再做修改。其实这个程序在没有添加ADC采集的时候,是完全可以运行的,没有出现任何错误,添加上ADC采集就不行了。
#include <msp430x14x.h>
#include "Key.h"
#include "Delay.h"
#include "PWM1.h"
#include "PWM2.h"
#include "ADC.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
unsigned char Key;
Key_INIT(); //按键初始化
ADC();
for (;;)
{
ADC12CTL0|=ENC;//转换允许使能
ADC12CTL0|=ADC12SC; //开转换
_BIS_SR(LPM0_bits+GIE);//开中断
Key=Key_Scan();//按键扫描
if(Key!=0) //如果按键不等于0即按有按键按下
{
switch(Key)//转到按键程序
{
case 1:
PWM1();
break;
case 2:
PWM2();
break;
default : break;
}
}
else delay_ms(10);//消除抖动
}
}
这是主程序部分,包括了ADC采集程序,产生两个不同频率的PWM波程序9在430的P1.2端口输出PWM波),还有延时程序
下面是按键初始化及扫描的程序(按键的一端接地,一端接430的P1.0和P1.1端,在端口与按键之间并接430的VCC端,就是说没按键按下的时候P1.0/P1.1端口是高电平,按键按下是低电平:
#include "msp430x14x.h"
#include "Key.h"
#include "Delay.h"
void Key_INIT(void)
{
// DIR=0,输入模式,DIR=1,输出模式
P1DIR &= ~BIT0;//配置P1.0为输入模式
P1DIR &= ~BIT1;//配置P1.1为输入模式
}
unsigned char Key_Scan(void)
{
static unsigned char KEY=0;//定义没有按键按下时,KEY=0
static unsigned char key_up=1; //没有按键按下时,key_up=1
if(key_up&&(KEYin1==0||KEYin2==0))//有一个键按下
{
delay_ms(10); //去抖动
key_up=0;//有按键按下,证明按键为低电平
if(KEYin1==0)//按键1按下,转为低电平
{
KEY=1; //KEY1按下
}
else if(KEYin2==0)//按键2按下,转为低电平
{
KEY=2;//KEY2按下
}
}
else if(KEYin1!=0&&KEYin2!=0)//无按键按下,返回值为0
{
key_up=1;
KEY=0;
}
return KEY;
}
下面是ADC采集程序(从P6.0采集到电压信号,低于1.65V就在P3.4输出低电压到电池管理芯片LN2054的使能控制端,使电池充电):
#include "msp430x14x.h"
#include "ADC.h"
void ADC(void)
{
WDTCTL=WDTPW+WDTHOLD;//关看门狗
ADC12CTL0=SHT0_8+ADC12ON+MSC;//打开ADC12,设置采样时间
ADC12CTL1=SHP+CONSEQ_2;//单通道多次转换,采样定时器采样方式
ADC12IE|=BIT0; //只使能ADC12MEM0中断,即转换的数据存入MEM0时中断可处
P6DIR|=0X00;
P6SEL|=BIT0;
P3DIR|=BIT4;
}
#pragma vector=ADC12_VECTOR //进入ADC12中断
__interrupt void ADC12ISR(void)
{
if(ADC12MEM0<0x7ff) //如果P6.0小于1.65V
P3OUT&=~BIT4; //P3.4=0
else
P3OUT|=BIT4; //P3.4=1
_BIC_SR_IRQ(LPM0_bits); //退出中断
ADC12CTL0&=~ENC;//清除中断标志位
}
一周热门 更多>