我是一个单片机初学者,刚刚学了七八天,试着写了一个小程序,翻了一些资料,头都大了,好不容易挤出了一些代码,但是出现了一个莫名其妙的现象,希望哪位弟兄百忙之中抽空看看,这里先谢过。 这是一个电话遥控电器的试验,2051的p1.7接光耦,检测振铃,来振铃将p1.7拉低,p1.1到p1.5接cm8870的std,D,C,B,A,用来检测摘机后拨进来的双音码,如果依次是*,0两个码,就向电话线送【嘀嘀声】然后打开电器,这里我做了两个定时中断都是十秒左右的,在检测振铃时用一个,两次振铃间隔超过十秒就回到开始【start】;另一个是摘机后十秒内不输完密码就回到开始【start】。开机从头到尾执行起来都正常,出现了这样的问题: 如果从开机复位,振铃6次到摘机后,不输密码,等待定时中断超时回到开始挂断电话,再重新送振铃6次摘机,摘机后定时中断不起作用了,多少秒钟以后也不挂断,这时输入密码也可以向下执行。硬件复位后第一次超时挂机正常。 我已经黔驴技穷了,呵呵。弄了两整天,改代码,写片子,2051都写了100多次了,还是不行。我想可能是中断响应之后半路跳到【start】,还有什么东西没有复位造成的,请各位弟兄指点指点。
代码如下,第一次写程序,有点乱-------那位老弟又说了:岂止乱,那是真乱呀
;单片机是89c2051,晶振是4Mhz org 0000h ajmp start org 000bh ;定时器0的中断向量地址 ajmp time0 ;跳转到真正的定时器程序处 org 0030h start: mov p1,#0ffh ;将p1口全置高,作为输入端 mov p3,#00h ;将p3口全置低,作为输出端 clr a ;累加器a清零 mov sp, #5fh ;堆栈起始设置 mov 30h, #00h ;软件计数器清零 mov tmod, #00000001b ;定时/计数器0工作于方式1 mov th0, #3ch ;装入预置数高位 mov tl0, #0b0h ;装入预置数低位 总数是15536,即计数到50000 setb ea ;开总中断 setb et0 ;开定时/计数器0允许 l1:jnb p1.7,d2 ;p1.7为高则向下执行,为低即跳至d2 ljmp l1 ;跳回l1 d2:setb tr0 ;定时/计数器0开始运行 mov 30h, #00h ;软件计数器清零 lcall delay ;调用2秒延时 inc a ;累加器a加1 cjne a, #6, l1 ;判断累加器a里面的数字为6否,是6,向下,不是6,回l1 clr tr0 ; 定时/计数器停止运行 setb p3.7 ;现在摘机, 推动一个继电器,将一个300欧姆电阻并到电话线上 lcall delay ;调用2秒延时,这时将有一个音乐片说一声【请输入密码】 clr a ;累加器a清零mov 30h, #00h ;软件计数器清零 mov th0, #3ch ;重置定时器,装入预置数高位 mov tl0, #0b0h ;装入预置数低位 setb tr0 ;定时/计数器0开始运行 mima:jnb p1.1, mima ;检测8870的15脚,低电平循环,高电平向下执行 jnb p1.2, start ;d位电平高继续 jb p1.3, start ;c位电平低继续 jnb p1.4, start ;b位电平高继续 jnb p1.5, start ;a位电平高继续,这四个是第一位密码 【*】 mima2:jb p1.1, mima2 ;检测8870的15脚,高电平循环,低电平向下执行 mima3:jnb p1.1, mima3 ;检测8870的15脚,低电平循环,高电平向下执行 jnb p1.2, start ;d位电平高继续 jb p1.3, start ;c位电平低继续 jnb p1.4, start ;b位电平高继续 jb p1.5, start ;a位电平低继续,这四个是第二位密码 【0】 lcall didixiang ;以下重复嘀嘀响十次 nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop lcall didixiang nop kaiguan:setb p3.4 ljmp kaiguan ;p3.4推动一个继电器,打开被控制的电器开关 ;未完待续------挂机电路还没想起来,写到这里卡壳了
;-----------------以下为嘀嘀响程序---------------------- didixiang: mov r7, #100 didi1: mov r6, #200 setb p3.5 ;p3.5推动一个三极管,去调制电话线,送出断续方波 didi2: djnz r6, didi2 clr p3.5 djnz r7, didi1 mov r7, #100 didi3: mov r6, #200 didi4: djnz r6, didi4 djnz r7, didi3 ret ;-----------------;以下为2秒延时----------------------- delay: mov r7, #250 y1: mov r6, #200 y2: mov r5, #5 y3: djnz r5, y3 djnz r6, y2 djnz r7, y1 ret ;---------------------------------------------------------- time0: ;定时器0的中断处理程序 push acc inc 30h ;软件定时器加1 mov a, 30h ;软件定时器送累加器a cjne a, #65, tret ;到65了吗?到了向下执行,未到65转到tret ljmp start ;回到开始,挂掉电话,重来。 tret: mov th0, #3ch ;重置定时器,装入预置数高位 mov tl0, #0b0h ;装入预置数低位 pop acc reti
end
|