有关PIC TMIER0 为何计算的初值和实测的时间不准?

2020-02-08 09:20发布

芯片 PIC16F877A  晶振4M  程序如下:

void timer0_init() //
{
//TMR0=61;的前提下:
        OPTION=0x00;//不同的分频用示波器实测时间  00:410us  01:800us  02:1.58ms  03:3.16ms  04:6.24ms
                //05:12.6ms 06:25ms   07:50ms
        INTCON=0xa0;
        TMR0=61;
}

中断如下:

void interrupt ISR()
{
/*******timer0********/
        if(T0IE&&T0IF)//T0IE:timer0溢出中断使能位/T0IF:溢出标志位.要软件清零
        {
        T0IF=0;
        TMR0=61;//初值61 50ms溢出一次
        RD0=!RD0;   //测RD0引脚的电平变化时间  
        }
}

当2分频的时候 初值61  定时的时间应该是  (256-61)*2=390us 实测有410us  这个误差很大,是怎么出现的?

是实测的准还是要看理论上算出来的?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
millwood0
1楼-- · 2020-02-09 06:44
"理论算起来的是不准的"

that's true only because your "theory / calculation" is flawed.

here is an example:

==========code==============

#include <htc.h>
#include "gpio.h"
#include "config.h"

//hardware configuration
#define OUT_PORT                GPIO
#define OUT_DDR                        TRISIO
#define OUT                                (1<<2)                        //output on gpio.2

#define TMR_PERIOD                100                                //tmr period, 100 ticks
#define TMR_ERROR                2                                //tmr error term
//end hardware configuration

unsigned char _tmr0_period=0;

void interrupt isr(void) {
        T0IF = 0;
        TMR0 += _tmr0_period;                                //reload the offset
        IO_FLP(OUT_PORT, OUT);                                //flip out
}

void tmr0_init(unsigned char period) {
        T0CS = 0;                                                        //use internal clock = Fosc / 4
        PSA = 1;                                                        //prescaler assigned to wdt
        _tmr0_period = -period + TMR_ERROR;
        TMR0 = _tmr0_period;                                //set the period
        T0IE = 1;                                                        //turn on tmr0 interrupt
}

void mcu_init(void) {
        ANSEL = 0x00;                                                //porta are digital io
        //ANSELH = 0x00;                                        //all portB is digital io
        CMCON = 0x07;                                                //analog comparators off
        //IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
       
        IO_CLR(OUT_PORT, OUT);                                //clear out
        IO_OUT(OUT_DDR, OUT);                                //out as output
}

void main(void) {
        mcu_init();                                                        //reset the mcu
        tmr0_init(TMR_PERIOD);                                //reset the tmr
        ei();                                                                //enable interrupt
        while (1){
                //TODO Auto-generated main function
        }
}
===========================

the above code flips GPIO2 every 100us, using tmr0.

here is its execution.



(原文件名:675f tmr0 isr.PNG)

it looks to me to be exactly 100us (or 200us = 5Khz period).

even without the error term, it will be far more accurate than 99% of the tasks need.

your mistake is in your own ability to understand how the timer works.
cumtgao
2楼-- · 2020-02-09 11:57
 精彩回答 2  元偷偷看……
ckshum
3楼-- · 2020-02-09 12:28
C語言編程器會在進入中斷程序時加上保存暫存器的源碼,看看.LST檔吧! 要這麼準便要用MPASM。

一周热门 更多>