搜索
bottom↓
回复: 21

关于TIMER0的问题.

[复制链接]

出0入0汤圆

发表于 2008-6-16 02:59:22 | 显示全部楼层 |阅读模式
系统时钟设置。烧录录:内部时钟,8M。osccal为0xff,分频CLKPR为0,
   初始化完成后,接一人LED翻转闪烁。
   问题就出来了,结果加电启动时,有时候TIMER0正常,但有时候却比正常要慢N倍,不知是什么原因。
  个人分析,可能系统时钟不对,可能TIMER0初始化不对,还有一种可能硬件引起工作不正常。现将部分程序列出,各位请多多指教,先谢谢了。

;---------------------------------
;选用内部时钟,下载时设置,8MHz;
SYS_CLK_INIT:
        ldi  r16,0xff
        sts  OSCCAL,r16
        ldi  r16,0x80
        sts  CLKPR,r16                                ;INCLK 8M,Prescale = 0xff
        ldi  r16,0x00
        sts  CLKPR,r16
        ret

   TIMER0初始化程序:
    TIMER0_INIT_PROC:
        ldi  r16,0x00                       ;不与OCR0A,OCR0B相接
        out  TCCR0A,r16                    

    ldi  r16,0x04                                ;0x04:256分频        0x05:1024分频                 
        out  TCCR0B,r16                    
                                       
        ldi  r16,0x00                       ;清零计数器
        out  TCNT0,r16                     
                                
        ldi  r16,0x00                                ;清零TIMER0中断标志位
        out  TIFR0,r16                     
                                       
        ldi  r16,0xff                      
        out  OCR0A,r16                      ;初始化比较计存器A
        out  OCR0B,r16                                ;初始化比较计存器B       

        ldi  r16,0x01                                ;使能TIMER0溢出中断
        sts  TIMSK0,r16   
       
        ret

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2008-6-16 03:03:51 | 显示全部楼层
在程序过程中应该不会更改此两项时钟设置,还有点疑问,在规格书中(M48),关于有些寄存器地址如PORTB:0x05(0x25). TCCR0B: 0x25(0x45)是什么意思。

出0入0汤圆

发表于 2008-6-16 11:58:36 | 显示全部楼层
PORTB:0x05(0x25).
PORTB寄存器在I/O空间的地址为0X05,使用I/O操作指令对PORTB操作时使用此地址,时间1个CLK.
PORTB寄存器影射在RAM空间的地址是0x25,因此也可以使用对RAM操作的指令对PORTB操作,但要使用其在RAM空间的地址,另外需要2个CLK时间.


建议你将SYS_CLK_INIT部分先去掉,就写个T0定时中断,控制一个LED的代码进行测试.

出0入0汤圆

 楼主| 发表于 2008-6-16 12:11:39 | 显示全部楼层
呵呵,马老师,谢谢,我昨天晚上也想了一下,有这么做的必要.

出0入0汤圆

 楼主| 发表于 2008-6-17 00:43:22 | 显示全部楼层
将SYS_CLK_INIT去掉了,还是不行,EMC的还没这么难用啊

出0入0汤圆

 楼主| 发表于 2008-6-17 01:08:59 | 显示全部楼层
晕死,终于可以了,去掉sys_clk_init可以解决此问题,时钟变得很慢了,将系统时钟osccal不设置为0xff就可以了,不知是为什么?是超过了时钟极限吗?

出0入0汤圆

 楼主| 发表于 2008-6-17 02:54:57 | 显示全部楼层
TIMER0是可以了,但当我打开TIMER1时,TIMER1又出了同样的问题,这次与TIMER0有点不同。当我设置TIMER1的初始值不同,它产生的中断在每次加电启动时,产生的中断频率不一样,有时会比较慢,而且会影响到TIMER0定时.不知什么原因。TIMER1中断初始化程序如下:

    由于TIMER0与TIMER1共用一人预分频器,而可以设置不同的分频,请教一下在使用过程中应注意什么事项?

         
   系统时钟设置。烧录录:内部时钟,8M。osccal为0xff,分频CLKPR为0,
   初始化完成后,接一人LED翻转闪烁。
   问题就出来了,结果加电启动时,有时候TIMER0正常,但有时候却比正常要慢N倍,不知是什么原因。
  个人分析,可能系统时钟不对,可能TIMER0初始化不对,还有一种可能硬件引起工作不正常。现将部分程序列出,各位请多多指教,先谢谢了。

;---------------------------------
;选用内部时钟,下载时设置,8MHz;
SYS_CLK_INIT:
        ldi  r16,0xf8
        sts  OSCCAL,r16
        ldi  r16,0x80
        sts  CLKPR,r16                                ;INCLK 8M,Prescale = 0xf8
        ldi  r16,0x00
        sts  CLKPR,r16
        ret

TIMER1_INIT:
TIMER1_INIT_PROC:
        ldi  r16,0x00                 ;不与OCR1A和OCR1B连接
        sts  TCCR1A,r16              
                                 
        ldi  r16,0x02                 ;8分频
        sts  TCCR1B,r16

        ldi  r16,0x00                        ;用PWM强制比较,清零
        sts  TCCR1C,r16

        ldi  r16,0x67                    ;计数器赋初值,(0xFFFF-0xC567)*8/(8*1000)=15ms
        ldi  r17,0xc5
        sts  TCNT1H,r17
        sts  TCNT1L,r16

        ldi  r16,0x00               ;清零所有TIMER1中断标志
        out  TIFR1,r16
       

        ldi  r16,0x01                        ;使能TIMER1溢出中断
        sts  TIMSK1,r16
               
        ret

出0入0汤圆

发表于 2008-6-17 15:25:46 | 显示全部楼层
为什么要将osccal设置为0xff?

出0入0汤圆

 楼主| 发表于 2008-6-18 00:24:37 | 显示全部楼层
它是内部时钟校准用的呀,规格书上也没说不能设成其它值,调整此寄存器可以更改系统时钟,7.3~8.1MHz之间。

出0入0汤圆

发表于 2008-6-18 10:55:08 | 显示全部楼层
先把SYS_CLK_INIT这部分去掉,专门测试T0和T1.

如果不正常,说明你T0和T1设置使用有问题.
如果正常,那么就是SYS_CLK_INIT出现问题.

出0入0汤圆

 楼主| 发表于 2008-6-20 01:46:21 | 显示全部楼层
无语中... 去掉SYS_CLK_INIT.还是不行和加上SYS_CLL_INIT(不对OSCCAL控制).
单独测试TIMER0,是没问题的,

当未设置TIMER0,只设置TIMER1时,TIMER1根本不工作,当开启TIMER0时,TIMER1也开始工作,但是其已经影响到了TIMER0工作,而其自身的定时也不正确。
  真的晕了,我看了一遍又一遍规格书啊,就是这么几个相关的寄存器。怎么会搞成这样呢?!不明白。

SYS_CLK_INIT:
   LDI R16,0X80
   STS CLKPR,R16
   LDI  R16,0X00
   STS CLKPR,R16
   RET


设置如下:
TIMER1_INIT_PROC:
        ldi  r16,0x00                 ;不与OCR1A和OCR1B连接
        sts  TCCR1A,r16              
                                 
        ldi  r16,0x01                ;8分频
        sts  TCCR1B,r16

        ldi  r16,0x00                        ;用PWM强制比较,清零
        sts  TCCR1C,r16

       
        ldi  r17,0xc5                    ;计数器赋初值,(0xFFFF-0xC567)*8/(8*1000)=15ms
        ldi  r16,0x67
        sts  TCNT1H,r17
        sts  TCNT1L,r16
       
        ldi  r16,0x01                        ;使能TIMER1溢出中断
        sts  TIMSK1,r16
               
        ret


中断程序:
TIMER1_OVF1_PROC:;reti
        push        r16
        push        r17
        push        r18
        in          r18,SREG

        lds  r16,TIMER_INT_FLAG                                 ;设置TIMER1中断发生标志寄存器
        ori  r16,0x30
        sts  TIMER_INT_FLAG,r16                   
                                
        ldi  r17,0xc5                    ;计数器赋初值,(0xFFFF-0xC567)*8/(8*1000)=15ms
        ldi  r16,0x67
        sts  TCNT1H,r17
        sts  TCNT1L,r16

        out   SREG,r18
        pop   r18
        pop   r16
        pop   r17
        reti

出0入0汤圆

 楼主| 发表于 2008-6-20 01:47:40 | 显示全部楼层
真有点怀疑是不是硬件引起的问题了。

出0入0汤圆

 楼主| 发表于 2008-6-20 01:50:57 | 显示全部楼层
从规格书上看起来,TIMER0与TIMER1没什么关联呀,除了个同步,但是跟它们定时没什么联系吧

出0入0汤圆

发表于 2008-6-20 11:07:07 | 显示全部楼层
先改掉几个问题:其它自己仔细点:

TIMER1_OVF1_PROC:;reti
        push        r16
        push        r17
        push        r18
        in          r18,SREG

        lds  r16,TIMER_INT_FLAG                                 ;设置TIMER1中断发生标志寄存器
        ori  r16,0x30
        sts  TIMER_INT_FLAG,r16        =====>为什么要设置TIMER1中断发生标志寄存器?!            
                                 
        ldi  r17,0xc5                    ;计数器赋初值,(0xFFFF-0xC567)*8/(8*1000)=15ms
        ldi  r16,0x67
        sts  TCNT1H,r17
        sts  TCNT1L,r16

        out   SREG,r18
        pop   r18
        pop   r16              =====>这里出栈顺序不对
        pop   r17
        reti

出0入0汤圆

 楼主| 发表于 2008-6-20 13:13:29 | 显示全部楼层
设置TIMER1中断发生标志,主要用于外部LED闪烁(计时).
   出栈不对,谢谢马老师.对于这人问题真得有点疲劳了

出0入0汤圆

发表于 2008-6-20 17:29:21 | 显示全部楼层
我不知道TIMER_INT_FLAG代表什么.如果是T1的中断标志寄存器的话,一般不需要改动,因为进入T1中断后,硬件会将T1的中断标志自动清除的.

由于TIME的中断标志寄存器中可能有其它的中断标志,对其操作不当,会影响到其它的中断.

点LED的话,只要把控制I/O输出寄存器取反即可.

出0入0汤圆

 楼主| 发表于 2008-6-23 13:09:17 | 显示全部楼层
马老师您好,这个标志寄存器为通用寄存器,只是标识该中断产生过的一个标志.由于我没有示波器,所以需要将定时时间延长利于观察进行初步估算.目前我已更改了堆栈,进行了初步测试,TIMER0已不受TIMER1影响了。再次表示感谢.

出0入0汤圆

 楼主| 发表于 2008-6-23 13:12:21 | 显示全部楼层
目前正在调试TIMER1溢出中断触发ADC,进行8路温度监控。希望进展顺利,不用麻烦马老师了.

出0入0汤圆

发表于 2008-6-23 14:36:03 | 显示全部楼层
我明白了,你是用汇编的,初始化时没有正确设置堆栈指针.

在我的教程中,已经非常明确的强调过,用汇编不要忘记正确的设置堆栈指针.用C可以不考虑的,

因为C编译器帮程序考虑了.但在C中,如果芯片型号配置选择不对,也会出现类似的问题.

出0入0汤圆

 楼主| 发表于 2008-6-24 12:45:44 | 显示全部楼层
堆栈其实我已经设置了.仅在出栈时出错了

出0入0汤圆

发表于 2008-6-24 19:56:07 | 显示全部楼层
呵呵,就是我看出的那个出栈问题?

出0入0汤圆

 楼主| 发表于 2008-7-31 00:01:53 | 显示全部楼层
是的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-9 15:33

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表