原创 射频项目困难之定时器设置篇

2009-5-29 22:42 2616 10 10 分类: MCU/ 嵌入式

射频项目困难之定时器设置篇<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


    刚解决了一个问题,就想迫不及待的把他写下来。


在写程序的过程中,碰到了定时器设置的问题,困扰了我将近两个礼拜!也许在高手那里,这点问题,不足挂齿!但是这确实是一个小小的失误!有时候你一直没有注意过啊!


      我就那修改了和未修改的程序做比较来说明问题,主要的问题就在定时器0的中断处理那块(定时器设置的教科书上有详细的说明,跟着做就是了)。


      修改过的中断处理函数:/***************************************************


* Function Name  : Timer0Interrupt ()


* Description    : 定时器0中断函数


* Input          : None


* Output         : None


* Return         : None


***************************************************/


void Timer0Interrupt () interrupt 1  using 1


{  


        TH0    =   0xFC;      //每次中断1ms时间


     TL0    =   0x66; 


      TR0=1; //正确时的位置


     SystemMs     ++;           //每次中断为1ms时间


      if(SystemMs>=250)


           {


                 SystemMs     =   0;


           }


}


未修改过的中断处理函数:


/***************************************************


* Function Name  : Timer0Interrupt ()


* Description    : 定时器0中断函数


* Input          : None


* Output         : None


* Return         : None


***************************************************/


void Timer0Interrupt () interrupt 1  using 1


{  


        TH0    =   0xFC;      //每次中断1ms时间


     TL0    =   0x66; 


     


     SystemMs     ++;           //每次中断为1ms时间


      if(SystemMs>=250)


           {


                 SystemMs     =   0;


           }


      TR0=1; //在这里时,调试能通过,但写到板子上,无法运行


}


当时,我在刚开始并没有在中断处理函数中写上TR0=1(因为以前写小程序的时候,自己并没有写也在运行!为啥,自己没明白),后来没有通过的时候,就加上这句,但是还是没办法运行,查来查去,就是找不到真正的问题所在,现象是执行几行程序就停止了。


      没办法,天天就在那里找问题,就到论坛里问。终于有网友说把TR0=1;提到给定时器赋值的后面,我就尝试了一下,结果真的运行通过了。我问他是啥原因,他告诉我是经验。并让我看看汇编的代码,也许能从那里找到问题,汇编我只会一点点,下面我把两个位置的汇编程序贴出来看看  


 49: void Timer0Interrupt () interrupt 1  using 1


    50: {   


C:0x<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />003A    C0E0     PUSH     ACC(0xE0)


C:0x003C    C0D0     PUSH     PSW(0xD0)


    51:         TH0  = 0xFC;        //每次中断1ms时间


C:0x003E    758CFC   MOV      TH0(0x8C),#0xFC


    52:         TL0    =   0x66;      


C:0x0041    758A66   MOV      TL0(0x8A),#0x66


    53:         TR0=1; 


C:0x0044    D28C     SETB     TR0(0x88.4)


    54:         SystemMs       ++;        //每次中断为1ms时间


C:0x0046    050C     INC      0x0C


C:0x0048    E50C     MOV      A,0x0C


C:0x004A    7002     JNZ      C:004E


C:0x004C    050B     INC      SystemMs(0x0B)


    55:         if(SystemMs>=250)


C:0x004E    C3       CLR      C


C:0x004F    94FA     SUBB     A,#0xFA


C:0x0051    E50B     MOV      A,SystemMs(0x0B)


C:0x0053    9400     SUBB     A,#0x00


C:0x0055    4006     JC       C:005D


    56:                 {


    57:                         SystemMs        =       0;


C:0x0057    750B00   MOV      SystemMs(0x0B),#0x00


C:0x005A    750C00   MOV      0x0C,#0x00


    58:                 }


C:0x005D    D0D0     POP      PSW(0xD0)


C:0x005F    D0E0     POP      ACC(0xE0)


C:0x0061    32       RETI    


以上是正常运行是的代码,我就不分析了。


  49: void Timer0Interrupt () interrupt 1  using 1


    50: {   


C:0x003A    C0E0     PUSH     ACC(0xE0)


C:0x003C    C0D0     PUSH     PSW(0xD0)


    51:         TH0  = 0xFC;        //每次中断1ms时间


C:0x003E    758CFC   MOV      TH0(0x8C),#0xFC


    52:         TL0    =   0x66;      


    53:          


C:0x0041    758A66   MOV      TL0(0x8A),#0x66


    54:         SystemMs       ++;        //每次中断为1ms时间


C:0x0044    050C     INC      0x0C


C:0x0046    E50C     MOV      A,0x0C


C:0x0048    7002     JNZ      C:004C


C:0x004A    050B     INC      SystemMs(0x0B)


    55:         if(SystemMs>=250)


C:0x004C    C3       CLR      C


C:0x004D    94FA     SUBB     A,#0xFA


C:0x004F    E50B     MOV      A,SystemMs(0x0B)


C:0x0051    9400     SUBB     A,#0x00


C:0x0053    4006     JC       C:005B


    56:                 {


    57:                         SystemMs        =       0;


C:0x0055    750B00   MOV      SystemMs(0x0B),#0x00


C:0x0058    750C00   MOV      0x0C,#0x00


    58:                 }


    59:          TR0=1; 


    60:           


C:0x005B    D28C     SETB     TR0(0x88.4)


    61: }


C:0x005D    D0D0     POP      PSW(0xD0)


C:0x005F    D0E0     POP      ACC(0xE0)


C:0x0061    32       RETI    


      上面红色所标示出来的是TR0=1放在最后的代码,


部分汇编代码分析:


C:0x003E    758CFC   MOV      TH0(0x8C),#0xFC


//TH0赋值#0xFC


    52:         TL0    =   0x66;      


    53:          


C:0x0041    758A66   MOV      TL0(0x8A),#0x66


//TL0赋值#0x66


    54:         SystemMs       ++;        //每次中断为1ms时间


C:0x0044    050C     INC      0x0C//累加器内容加一


C:0x0046    E50C     MOV      A,0x0C


//0x0C移动到累加器


C:0x0048    7002     JNZ      C:004C


//累加器内容不为0转移到C:004C(由于上行代码的原因,累加器不为0,)


C:0x004A    050B     INC      SystemMs(0x0B)


    55:         if(SystemMs>=250)


C:0x004C    C3       CLR      C//清除进位位C


C:0x004D    94FA     SUBB     A,#0xFA


//累加器内容减#0xFA和进位位内容


C:0x004F    E50B     MOV      A,SystemMs(0x0B)


//0x0B移动到累加器


C:0x0051    9400     SUBB     A,#0x00


//累加器内容减#0x00和进位位内容


C:0x0053    4006     JC       C:005B


//进位位C0的话,转移到C:005B


C:0x0055    750B00   MOV      SystemMs(0x0B),#0x00


C:0x0058    750C00   MOV      0x0C,#0x00


    58:                 }


    59:          TR0=1; 


    60:           


C:0x005B    D28C     SETB     TR0(0x88.4)


    61: }


C:0x005D    D0D0     POP      PSW(0xD0)


C:0x005F    D0E0     POP      ACC(0xE0)


C:0x0061    32       RETI 


所以可以看到,虽然两个不同的程序都能实现TR0=1;但是第二个程序要执行完好几步才要启动定时器,这就可能出现在这段时间里,假如程序调用定时程序时(我的定时器0是用来定时的),就会出现死机!而导致程序不能正常的运行。


      我也不知道我的理解对不,因为我的技术很菜,有错误的话,欢迎大家指出来,我的邮箱是:caoxueliang@yahoo.cn


      在这个程序中,还犯过一个错误,就是启动了串口中断,但是没有写中断处理,没有使用软件对串口中断清0,所以在调试中也给我带了了很多的干扰。


      TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。


RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。


 


2009-5-29


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /3 下一条