完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
`小妹是刚刚接触430的初学者,SOS 想做一个电子时钟,MSP430F437上,FET仿真器,液晶屏是定制的,现在做的程度是能在LCD上每秒增加,秒满60进分,分满60进小时这样的。想增加一个设置时间的功能,碍于中断了解不是很懂,程序加上我main里面的anjian()之前每秒在跑的就停止了,不知如何往下做,求指导 加红部分是自己瞎写的地方,不知如何改可以设置时间 想要的功能是 K1键为功能键,按一下移动到秒的个位上——闪烁提示可以修改,再按就往秒十位移动,以此类推 K2、K3配合K1使用 K2为减 K3为加 附上已写乱七八糟的代码 #include #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); } |
|
相关推荐
4个回答
|
|
本帖最后由 1522495332 于 2014-4-9 09:43 编辑
代码看得头疼,我给几个建议 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、主函数太乱了,我就不发表意见了 如有疑问,继续提问
|
|
|
|
同时用到定时器中断和外部中断,一定要设置中断优先级,否则进入外部中断的时候,定时器中断不工作,则定时器中断不响应,时间就不走了。另外,用单片机定时器做的时钟存在误差,如果想准确则必须用到时钟芯片。
|
|
|
|
代码有点乱 最好能有程序的流程图 编程思想比代码重要
|
|
|
|
先画流程图,在设计程序,然后验证比较容易确定问题
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
811 浏览 0 评论
525 浏览 0 评论
嵌入式学习-搭建自己的ubuntu系统之ubuntu网络设置
646 浏览 0 评论
龙芯中科胡伟武:3B6600 八核桌面 CPU 性能将达到英特尔中高端酷睿 12~13 代水平
710 浏览 0 评论
树莓派Pico 2发布,搭载RP2350双核RISC-V和Arm Cortex-M33微控制器!
670 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
10719 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-17 19:55 , Processed in 0.608689 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号