单片机高手们请给我指点指点吧!

用T0定时 从p1.0口输出周期为一秒 宽度为2ms的脉冲!
帮我看看错在那,怎运行不出来呀!
org 0000h
ljmp main
main:
org 0100h
mov tmod ,#01h
clr P1.0
loop:
mov th0 ,#0ffh
mov tl0 ,#0ffh
setb tr0
jnb tf0 ,$
clr tf0
clr tr0
mov th0 ,#003dh
mov tl0 ,#0e0h
setb tr0
jnb tf0 ,$
cpl P1.0
clr tr0
clr tf0
mov th0 ,#0b1h
mov tl0 ,#0e0h
setb tr0
jnb tf0 ,$
cpl P1.0
clr tr0
clr tf0
sjmp loop
end

你的程序我怎么看不懂,而且我无法确定软件清除T0中断标志能不能使内部逻辑正常复位,通常应该由硬件自动复位中断标志的

mov th0 ,#0ffh
mov tl0 ,#0ffh
setb tr0
jnb tf0 ,$
这一段定时了一个机器周期,如果你是用的12MHz晶振,这里产生的效果就是延时了1us,实际上还不如一行nop精确,因为你的判断开始前中断标志就形成了

mov th0 ,#003dh
mov tl0 ,#0e0h
setb tr0
jnb tf0 ,$
cpl P1.0
这一段定时了大约49.2ms,然后P1.0进行了一个正跳变

mov th0 ,#0b1h
mov tl0 ,#0e0h
setb tr0
jnb tf0 ,$
cpl P1.0
这一段定时了大约20ms,然后P1.0进行了一个负跳变,之后就是循环

整个程序的效果大致上应该是在P1.0引脚发生一个周期70ms,宽度20ms的正脉冲,不知道跟你的试验结果是不是吻合

我建议你开定时器中断,你这样的用法实际上还不如用寄存器循环做延时。

假设你的晶振是12MHz,定时器初值设为F830(63536),这样每次中断的时间是2ms,在中断服务程序中先重载初值,然后用一个寄存器作计数,每次中断加1,到50就回复成0,当这个寄存器等于0时就发高电平,不等于0就发低电平,这是比较通常的方案。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-12-02
程序不对,没有开中断或者中断来了没地方去,用定时器了就不要这么写吧,另外写汇编尽量用大写好些,舒服,呵呵。要精确的话还是用定时器,用语句做的延时都是有一定的偏差的。

MS_20 EQU 40H;20ms定时
SEC_1 EQU 41H;秒定时
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0INTERRUPT

MAIN:
MOV MS_20,#10;2ms*10=20ms
MOV SEC_1,#50;20ms*50=1000ms=1sec
MOV TMOD,#01H
SETB EX0
SETB IT0
SETB ET0
CLR TR0
MOV TH0,#0F8H
MOV TL0,#30H
SETB TR0
SETB EA
LOOP:
AJMP LOOP

T0INTERRUPT:
CLR TR0
DJNZ MS_20,Exit0
MOV MS_20,#10
DJNZ SEC_1,Exit0
MOV SEC_1,#50
SET P1.0
AJMP Exit1
Exit0:
CLR P1.0
Exit1:
MOV TH0,#0F8H
MOV TL0,#30H
SETB TR0
RETI

END