请帮我用8951做个定时器,用C语言写,做好注释

请帮我用8951做个定时器,用C语言写,做好注释,第1张

定时器程序如下

可设定时间的倒计时定时器,可选择5/15/20/30/35/45/50分钟倒计时

倒计时时间由四位拨码开关的1/2/3位来控制,

第2位表示5分钟,第3位表示15分钟,第4位表示30分钟,

通过不同的组合可以产生5/15/20/30/35/45/50分钟倒计时

P10口的外接的发光二极管为状态LED,定时未开始时LED常亮,定时过程中LED闪烁

K1为开始按钮,K2为停止按钮

a_bit equ 20h ;数码管个位数存放内存位置

b_bit equ 21h ;数码管十位数存放内存位置

temp equ 22h ;计数器数值存放内存位置

;开机初始化

MOV P3,#0FFH ;对P3口初始化,设置为高电平,用于按键输入

MOV P0,#0FFH ;使显示时间数码管熄灭

CLR P10 ;点亮LED指示灯

;等待键盘输入

START:JB P36,$ ;循环判断开始按钮K1是否按下

ACALL DELAY10 ;延时10毫秒触点消抖

JB P36,START ;如果是干扰就返回

JNB P36,$ ;等待按键松开

;读拨码开关的状态,获得倒计时时间

SET1:

MOV A,#0 ;首先对A清零

JB P20,A1 ;判断拨码开关的第2位是否接通,接通就对A加5

ADD A,#5

A1: JB P21,A2 ;判断拨码开关的第3位是否接通,接通就对A加15

ADD A,#15

A2: JB P22,A3 ;判断拨码开关的第4位是否接通,接通就对A加30

ADD A,#30

A3: MOV TEMP,A ;这时TEMP中的值就是倒计时时间

;数码管显示定时时间的程序

display:

CLR P24 ;使继电器1释放,开始定时(开机时继电器处于吸合状态)

CLR P23 ;使继电器2释放,开始定时(开机时继电器处于吸合状态)

MOV R2,#120

AB1:MOV R3,#250

TIME1: mov a,temp ;将temp中的十六进制数转换成10进制

mov b,#10 ;10进制/10=10进制

div ab

mov b_bit,a ;十位在a

mov a_bit,b ;个位在b

mov dptr,#numtab ;指定查表启始地址

mov r0,#4

dpl1: mov r1,#250 ;

dplop: mov a,a_bit ;取个位数

MOVC A,@A+DPTR ;查个位数的7段代码

mov p0,a ;送出个位的7段代码

clr p27 ;开个位显示

ACALL DELY1 ;显示1毫秒

setb p27 ;关闭个位显示,防止鬼影

mov a,b_bit ;取十位数

MOVC A,@A+DPTR ;查十位数的7段代码

mov p0,a ;送出十位的7段代码

clr p26 ;开十位显示

ACALL DELY1 ;显示1毫秒

setb p26 ;关闭十位显示,防止鬼影

;插入一段判断定时过程中是否有按键输入的程序段

C1: JB P36,B1

ACALL DELAY10 ;延时10毫秒消抖

JB P36,C1

JNB P36,$ ;等待按键松开

AJMP SET1

B1: JB P37,M33

ACALL DELAY10 ;延时10毫秒消抖

JB P37,B1

JNB P37,$ ;等待按键松开

AJMP OVER

M33: djnz r3,TIME1 ;2毫秒循环执行250次,时间约05秒

CPL P10 ;使LED每1秒闪烁一次

djnz r2,AB1 ;循环执行120次,时间为1分钟

DEC TEMP ;满一分钟对定时时间减1

MOV A,TEMP

JNZ DISPLAY ;判断TEMP的数值是否为0不为0循环

;结束定时

OVER:CLR P10 ;LED指示灯常亮

SETB P24 ;继电器1吸合,定时结束,退回到开机时的状态

SETB P23 ;继电器2吸合,定时结束,退回到开机时的状态

AJMP START ;退到开机初始化状态

;1毫秒延时子程序

DELY1: MOV R4,#2

D1: MOV R5,#248

DJNZ R5,$

DJNZ R4,D1

RET

;10毫秒延时子程序

DELAY10:MOV R4,#20

D2: MOV R5,#248

DJNZ R5,$

DJNZ R4,D2

RET

;实验板上的7段数码管0~9数字的共阴显示代码

NUMTAB:DB 0CFH,03H,5DH,5BH,93H,0DAH,0DEH,43H,0DFH,0DBH

end

因为周期为10毫秒,定时器中断方式,所以初值应该为:65536-(10/2)1000=65536-5000\x0d\TH0=(65536-5000)/256\x0d\TL0=(65536-5000)%256\x0d\程序如下:\x0d\ORG 0000H\x0d\LJMP MAIN\x0d\ORG 000BH\x0d\LJMP T0ISR\x0d\ORG 0030H\x0d\MAIN:\x0d\ MOV TMOD,#01H\x0d\\x0d\ MOV TH0,#HIGH(65536-5000)\x0d\\x0d\ MOV TL0,#LOW(65536-5000)\x0d\\x0d\ SETB TR0\x0d\\x0d\ SETB ET0\x0d\\x0d\ SETB EA\x0d\\x0d\ SJMP $\x0d\\x0d\T0ISR:\x0d\ CLR TR0\x0d\\x0d\ MOV TH0,#HIGH(65536-5000)\x0d\\x0d\ MOV TL0,#LOW(65536-5000)\x0d\\x0d\ SETB TR0\x0d\\x0d\ CPL P10\x0d\\x0d\ RETI\x0d\\x0d\ END

说实在的,没有太明确你到底是什么目的,但是就你这个函数而言你的TACCR1<TACCR0,所以等计数器达到TACCR1时,TACCR1 CCIFG被置位,但是由于没有相应的中断允许就不会进入到TIMERA1中断,由于也没有进行软件清零,所以该标志一直是置位状态。直到计数到TACCR0,这时进入中断 TIMERA0,打开了TACCR1的中断允许,这时由于TACCR1 CCIFG处于置位状态,加上TIMERA1中断优先级低于中断 TIMERA0,所以在中断 TIMERA0结束后立刻进入到TIMERA1中断,这段时间很短,可以忽略不计。重新计数后就是一直先进入TIMERA1中断,然后关闭了中断 TIMERA0,也就不能进入中断 TIMERA0,也就没有了高电平,所以看到的效果就是一直是低电平。(有一点你可能不知道就是如果不进入中断,中断标志是不自动清零的)。

我也不知道你要产生什么样的波,真是不好说啊,如果只是产生一个时间脉冲,那么可以在打开TACCTL1中断前先将TACCR1 CCIFG清零。应该就可以出现一个05ms 的高电平脉冲。

纯理论分析,不知道正确与否,但你可以参考看看。

不用中断的话:

TMOD=0x10;

TH1=(65536-50000)/256;//定时50ms

TL1=(65536-50000)%256;

TR1=1;a=20;

while(a>0)//溢出20次是1秒

{if(TF1==1)

{TF1=0;

TH0=……

TL0=……

a--;}

}

TR1=0;

可以用 两个中断控制位来实现 一个上升沿中断 一个下降沿有效 同时赋给他 ECHO,在中断中控制 定时器使能 TAR寄存器中的值就是你要的数值 但是是有范围的 最大 0xffff。。。

以上就是关于请帮我用8951做个定时器,用C语言写,做好注释全部的内容,包括:请帮我用8951做个定时器,用C语言写,做好注释、定时器的计算方式是什么、MSP430 定时器A中断问题,我想用TACCR0和TACCR1中断来实现产生一个时间脉冲,编译能通过,但是无法产生波等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9438273.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存