打印

请教一下 16f723 timer1定时问题,定时不准

[复制链接]
4668|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhaosr19|  楼主 | 2011-9-4 18:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhaosr19 于 2011-9-5 20:02 编辑

请教一下 16f723 timer2定时问题,内部时钟,16Mhz,按照下面计算是16Mhz/(4*16*16)= 15625,但我在程序中对Timer2定时3ms,PR2 = 0.003*15625=47
我在main函数中有如下操作,但通过管脚输出发现这个定时不对,至少差2倍,能帮忙看看是我算错了?
另外,Timer1,Timer0我都是用了,这个有影响?谢谢
                    TMR2 = 0;
                    PR2 = 47;
                   TMR2ON = 1;


#include <htc.h>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 16000000/* 内部晶振16MHz */
#endif
#define _XTAL_FREQ_1_16 1000000/* 1/16 * _XTAL_FREQ */
#define _TIMER1_FREQ    500000 /* 1/4 Focs,8分频 */
#define _TIMER2_FREQ    15625  /* 1/4 Focs,16,16分频 */
//大4倍
#define NORMAL_OUT  3.0 /* ms */
#define NORMAL_OUT_NUM 47/* NORMAL_OUT * _TIMER2_FREQ */
#define HIGH_OUT    2.5 /* ms */
#define HIGH_OUT_NUM 39/* HIGH_OUT * _TIMER2_FREQ */
typedef union {
    struct {
        unsigned bFlag_RB5           : 1;
        unsigned ucTimer1Flag        : 1;
        unsigned bFlag               : 1;
        unsigned ucTimer2Flag        : 1;
        unsigned ucFlagNorOrHigh     : 2;/* 1 Normal,2 High */
        unsigned uOutFlag            : 1;
        unsigned    uClose              : 1;
    };
    unsigned char ucFlag;
}FlagBit;
volatile FlagBit ubFlagBit;
volatile unsigned short g_uslT3=0;
unsigned char ucFlagTemp1 =0, ucFlagTemp2 =0, g_fFreq = 0;//,temp[10];
volatile unsigned char ucTimer1RollOver = 0;
volatile unsigned short usTimer2_NUM = 0,usTimer2_NUMPre = 0;
unsigned char ucAngle = 0;
union tag_TimerValue
{
    struct
    {
        unsigned L:8;
        unsigned H:8;
    }Value;
    unsigned short Timer;
};
volatile union tag_TimerValue g_uslT1,g_uslT2;
void Init(void)
{
    INTCON  = 0x00;
    PIE1    = 0x00;
    PIR1    = 0x00;
   
    TRISA   = 0b00000100; /* 0输出,1 input, AN2 */
    ANSELA  = 0b00000100; /* 1 Analog input */
    TRISB   = 0b00100001; /* RB5,RB0;RB3 ccp */
    ANSELB  = 0x00;       /* 0 IO, 1  Analog input */
    WPUB    = 0x00100001; /* 1 pull-up enabled, RB5,RB0,与OPTION_REG有关 */
    IOCB    = 0b00100000; /* 1 Interrupt-on-change enabled, RB5 */
    TRISC   = 0x00;
#if 0
    CCP2SEL = 1;         /*  CCP2 function is on RB3/CCP2 */
    CCP2CON = 0x00;      /* reset ccp */
    CCP2CON = 0x00000100;/*  Capture mode, every falling edge */
    CCP2IE  = 1;
    CCP2IF  = 0;
#endif
    /* AD */
    ADCON1  = 0b00000011;/* Fosc/2, Vref  internal Fixed Voltage Reference */
    ADCON0  = 0b00001001;
    FVRCON  = 0b11000011;/* 4.096 */
    ADON    = 1;
    /* timer1 */
    T1CON   = 0b00110101;/* 1/4 *Fosc ,预分频8*/
    //T1CON  = 0x01;//ccp
    T1GCON  = 0x00;
    TMR1IE  = 1;
   
    /* timer0 */
    CPSCON0     = 0x00;     /* Timer0 clock source is Fosc/4 */
    OPTION_REG   = 0b00000001;/* portb上拉,独立控制;INT脚下降沿中断,预分频 4,内部 Fosc/4 */
   
    /* timer2 */
    T2CON  = 0b01111011;/* postscaler 16,prescaler 16, timer off 4MHz/16/16 = 15,625*/
    TMR2IE = 1;
    TMR2IF = 0;
   
    /* interrupt */
    INTE   = 1;
    INTF   = 0;
    T0IE   = 0;
    T0IF   = 0;
    TMR1IF = 0;
    RBIE   = 1;/* portb change interrupt enable */
    RBIF   = 0;
    PEIE   = 1;
    GIE    = 1;
    __delay_us(1000);/*1000us*/
}
/* Ad采集 */
unsigned int ReadAD(int iNum)
{
    unsigned int uiAdValue = 0;
    unsigned char j = iNum;
    unsigned char uiAdMax  = 0,uiAdMin = 255;
    unsigned char ucAdValue;
   
    for (; j > 0; j--)
    {
        GO    = 1;
        while(GO)
        {
            continue;
        }
        ucAdValue = ADRES;
        if (ucAdValue > uiAdMax)
        {
            uiAdMax = ucAdValue;
        }
        
        if (ucAdValue < uiAdMin)
        {
            uiAdMin = ucAdValue;
        }
        
        uiAdValue += ucAdValue;
        
        /* 如果不准可以考虑加入nop(); */
    }
   
    uiAdValue = (uiAdValue - uiAdMax - uiAdMin)/(iNum -2);
   
    return uiAdValue;
}
void  interrupt  my_isr(void)
{
    unsigned char ucTemp = 0;
   
    if (1 == TMR2IE && 1 == TMR2IF)
    {
        TMR2IF = 0;
        if (1 == RA0)
        {
            RA0 = 0;
        }
        else
        {
            RA0 = 1;
        }
        return;
    }
#if 0
    if (1 == CCP2IF)
    {
        CCP2IF = 0;
        ucFlagTemp1 =CCPR2H;
        ucFlagTemp2 =CCPR2L;         
    }
#endif   
}

void main(void)
{
    unsigned char ucAdValInit = 0;
    volatile unsigned char ucAdVal     = 0,ucAdValCurrent = 0;
    unsigned char ucTemp = 0;
    unsigned char i  = 0 ,j = 0,k=0;
    Init();
   
    ubFlagBit.ucFlag = 0;
   
    g_uslT2.Timer = 0;
    g_uslT1.Timer = 0;
    PORTB         = PORTB;
    ucAdValInit = ReadAD(5);
    //temp
    TMR2ON = 1;
    TMR2 = 0;
    PR2 = 255;//NORMAL_OUT_NUM;// 255; 32.5ms
   
    while(1)
    {
        ;      
    }
   
    return;
}


         
            
               
          _________
         |________|               |_________
沙发
兰天白云| | 2011-9-5 18:27 | 只看该作者
定时后从哪个脚输出?是CCP2吗?如果是则CCP2配置错误

使用特权

评论回复
板凳
zhaosr19|  楼主 | 2011-9-5 19:55 | 只看该作者
2# 兰天白云

不是,就是普通IO脚输出的

使用特权

评论回复
地板
zhaosr19|  楼主 | 2011-9-5 20:04 | 只看该作者
___                          ———————————————————
      |————————————————|                           |————————
高电平部分32.5ms
另外把#if 0去掉,ccp2怎么进不了中断?

使用特权

评论回复
5
virtualtryon| | 2011-9-5 23:30 | 只看该作者
一看就是新手写的代码
if (1 == RA0)
        {
            RA0 = 0;
        }
        else
        {
            RA0 = 1;
        }
这个可以写成RA0 = !RA0;
另外AD采样程序死等的不对的,效率太低了,用状态表示,主程序运行一次进来切换状态.
while循环一定要有其它退出机制.当然主程序的死循环除外.

使用特权

评论回复
6
zhaosr19|  楼主 | 2011-9-6 08:55 | 只看该作者
谢谢,的确应该写成RA0 = !RA0;
但我这个是测试程序,所以没有仔细想;
“另外AD采样程序死等的不对的,效率太低了,用状态表示,主程序运行一次进来切换状态.”还能举个例子?谢谢
目前定时器定时多一倍的问题,我估计是使用内部晶振错误,不是16M的,是8M,这个有办法确认一下?

使用特权

评论回复
7
XIEYUANBIN| | 2011-9-6 09:05 | 只看该作者
你可以选择内部晶振、CLKOUT,OSC2脚会有内部振荡的输出

使用特权

评论回复
8
longzixin168| | 2011-9-6 09:12 | 只看该作者
没可能吧,我一般也是用内部晶振来的,如TIMER1  3mS   =>X=3mS*(16M/4 /pre_scale)  =>TMR1=(65536-X) ;  你是在置初值时错了吧,然后用TMR1ON即可。

使用特权

评论回复
9
asspeed| | 2011-9-6 09:32 | 只看该作者
PLLEN=1时,缺省频率为8mhz,你要通过设置OSCCON的IRCF位为11,才能得到16MHZ,
很显然,LZ 完全没有仔细阅读数据手册。

使用特权

评论回复
10
zhaosr19|  楼主 | 2011-9-6 18:54 | 只看该作者
谢谢,在MPLAB中设置了PLLEN=1,但OSCCON这个没有设置,默认是10,所以8M

没有使用过内部时钟,以为一配置就是8M的
谢谢
另外,OSCCON的ICSL、ICSS 该怎么设置?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

59

帖子

0

粉丝