小妹是刚刚接触430的初学者,SOS
想做一个
电子时钟,MSP430F437上,FET
仿真器,液晶屏是定制的,现在做的程度是能在LCD上每秒增加,秒满60进分,分满60进小时这样的。想增加一个设置时间的功能,碍于中断了解不是很懂,程序加上我main里面的anjian()之前每秒在跑的就停止了,不知如何往下做,求指导
加红部分是自己瞎写的地方,不知如何改可以设置时间
想要的功能是 K1键为功能键,按一下移动到秒的个位上——闪烁提示可以修改,再按就往秒十位移动,以此类推
K2、K3配合K1使用 K2为减 K3为加
附上已写乱七八糟的代码
#include<msp430x43x.h>
#define uint unsigned int
#define uchar unsigned char
uchar table[]={0XAF,0XA0,0XCB,0XE9,0XE4,0X6D,0X6F,0XA8,0XEF,0XED};
uchar numxiaoshi,numfenzhong,nummiao,xiaoshishi,xiaoshige,fenzhongshi,fenzhongge,miaoshi,miaoge,keybuf;
void delayms(uint z)//延时函数
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void display()//显示函数
{
//以下4行显示小时
LCDMEM[1]=table[xiaoshishi];
delayms(10);
LCDMEM[2]=table[xiaoshige];
delayms(10);
//以下4行显示分钟
LCDMEM[3]=table[fenzhongshi];
delayms(10);
LCDMEM[4]=table[fenzhongge];
delayms(10);
//以下4行显示秒
LCDMEM[6]=table[miaoshi];
delayms(10);
LCDMEM[7]=table[miaoge];
delayms(10);
}
void init()//定时器A初始化
{
WDTCTL=WDTPW+WDTHOLD;
P3DIR=0x00;
P4DIR=0xff;
P5DIR=0xff;
P2DIR=0xff;
P3SEL=0;
P2SEL=0;
P4SEL=0;
P5SEL=0;
//BCSCTL1=CALBC1_1MHZ;
//DCOCTL=CALBC1_1MHZ;
//TACTL=TASSEL_2+MC_3+ID_3;
TACTL|=TASSEL0+MC0;
CCTL0=CCIE;
CCR0=32768;
_EINT();
}
void init_lcd (void)
{
int j;
FLL_CTL0|=XCAP14PF;
BTCTL=BTDIV+BT_fCLK2_DIV4;
LCDCTL=LCDON+LCD4MUX+LCDP2;
BTCTL|=BTFRFQ1;
P5SEL=0XFC;
for(j=0;j<14;j++)
{
LCDMEM[j]=0;
}
}
/************端口P1初始化,设置时间*****K3/P1.0 K2/P1.3 K1/P1.4 ****/
void anjian()
{
P1DIR|=0X00; // 设置P1.0 P1.3 P1.4 为输入方向
P1IE|=0X19; // 设置P1.0 P1.3 P1.4 可以中断
P1IES|=0X19; // 设置P1.0 P1.3 P1.4 为下降沿中断
P1IFG&=~0X19;
_EINT();
while(1)
{
if(keybuf==0) //如果按键为K1
{
delayms(10);
if(keybuf==0)
{
while(!(P1IN==0x19));
_DINT();
while(1)
{
miaoshi=nummiao/10;
miaoge=nummiao%10;
fenzhongshi=numfenzhong/10;
fenzhongge=numfenzhong%10;
xiaoshishi=numxiaoshi/10;
xiaoshige=numxiaoshi%10;
display();
if(keybuf==1)
{
delayms(10);
if(keybuf==1)
{
while(!(P1IN==0x19));
nummiao++;
if(nummiao>59)
nummiao=0;
}
}
if(keybuf==2)
{
delayms(10);
if(keybuf==2)
{
while(!(P1IN==0x19));
numfenzhong++;
if(numfenzhong>59)
numfenzhong=0;
}
}
/*if(P1IN==0x01)
{
delayms(10);
if(P1IN==0x01)
{
while(!(P1IN==0x19));
numxiaoshi++;
if(numxiaoshi>23)
numxiaoshi=0;
}
}*/
if(keybuf==0)
{
delayms(10);
if(keybuf==0)
{
while(!(P1IN==0x19));
_EINT();
break;
}
}
}
}
}
}
}
unsigned char keycode()
{
unsigned char x;
if((P1IN&0x19)== 0x09) // 是否第一个按键K1
{
delayms(10);
if((P1IN&0x19)== 0x09)
x=0;
}
else
if((P1IN&0x19)== 0x11) // 是否第二个按键K2
{
delayms(10);
if((P1IN&0x19)== 0x11)
x=1;
}
else
if((P1IN&0x19)== 0x18) // 是否第三个按键K3
{
delayms(10);
if((P1IN&0x19)== 0x18)
x=2;
}
return(x);
}
void main(void)
{
init();
init_lcd();
while(1)
{
//anjian(); /*****设置时间*****/
miaoshi=nummiao/10;
miaoge=nummiao%10;
fenzhongshi=numfenzhong/10;
fenzhongge=numfenzhong%10;
xiaoshishi=numxiaoshi/10;
xiaoshige=numxiaoshi%10;
LCDMEM[5]=0x32;
display();
}
}
#pragma vector=
tiMERA0_VECTOR
__interrupt void Timer_A()
{
nummiao++;
LCDMEM[5]=0x00;
if(nummiao>59)
{
nummiao=0;
numfenzhong++;
}
if(numfenzhong>59)
{
numfenzhong=0;
numxiaoshi++;
}
if(numxiaoshi>23)
{
numxiaoshi=0;
}
}
/******************P1中断*********************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{ //端口1 的中断服务程序
P1IFG&=~0X19;
while((P1IN&0X19)!=0x19) //没有按键按下,返回全1――0x19
{
delayms(50); //延时消除抖动
while((P1IN&0X19)!=0x19)
{
keybuf = keycode();
while((P1IN&0X19)==0); //等待按键松开
}
}
//_BIC_SR_IRQ(LPM3_bits);
}
代码看得头疼,我给几个建议
1、变量的设置
时、分、秒为:uchar uHour, uMinute, uSecond;
他们的十位与个位分别为:uchar uHighHour, uLowHour, uHighMinute, uLowMintue, uHighSecond,uLowSecond;//如果定义成数组,那操作就更方便了
(uchar uNumber[6];//后面的代码就用这个,不用上面的那6个变量)
光标位置为:uchar uCursor; // 取值0~6,秒的个位为0, 时的十位为5,退出设置为6
2、按键中断可以判断中断标志 P1IFG,比起直接判断P1IN来得好
例如
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG & BIT0)
{
//K3按下,光标处的数值加一
if(uCursor<6)
{
uNumber[uCursor]++;
//code... 再对 uLowSecond 的取值范围进行判断
}
}
else if(P1IFG & BIT3)
{
//K2按下,光标处的数值减一
//参考上面 K3 的代码
}
else if(P1IFG & BIT4)
{
//K1按下,光标左移
if(uCursor<5)
{
//code... 恢复光标处的数值
uCursor++
}
else if(5 ==uCursor)
{
//code... 将uHighHour, uLowHour合成uHour
//code... 将uHighMinute, uLowMintue合成uMinute
//code... 将 uHighSecond, uLowSecond合成Second
uCursor = 6;
}
else
{
uCursor = 0
}
}
//其它代码
P1IFG = 0;
}
3、使用 display() 函数实现光标闪烁功能void display(){ //以下4行显示小时 static uchar cnt = 0;//计数,范围0~20;0~10显示光标,11~20显示数字。取值范围小,光标闪烁快;取值范围大,光标闪烁慢,自己修改 uchar i; for(i=1;i<7;i++) { if(uCursor == i - 1) { LCDMEM=(cnt<10) ? '_' : table[uNumber[i-1]]; // '_' 是下划线或者其它光标符号对应的8位二进制数,请自行替换
} else { LCDMEMtable[uNumber[i-1]]; } delayms(10); } if(cnt<20) cnt++; else cnt = 0;
}
4、大量使用while结构,对于初学者来说是个不好的习惯,既然你的按键是用中断进行处理,你又何必加上查询呢?这是多此一举的做法。5、主函数太乱了,我就不发表意见了
如有疑问,继续提问
一周热门 更多>