[PIC®/AVR®/dsPIC®产品] 时钟配置

[复制链接]
578|16
 楼主| zwll 发表于 2022-7-10 11:22 | 显示全部楼层 |阅读模式
本帖最后由 pzsh 于 2022-7-25 11:32 编辑

PIC18F67K22想使用定时器0中断,并且配置LED2一秒钟变化一次,时钟想配置内部16M,现在的问题是LED2用示波器观测时1.12秒变化一次
supernan 发表于 2022-7-10 11:28 | 显示全部楼层
楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因
 楼主| zwll 发表于 2022-7-10 11:30 | 显示全部楼层

/********************部分配置字

#pragma config RETEN = ON   
#pragma config INTOSCSEL = HIGH
#pragma config SOSCSEL = DIG   
#pragma config XINST = OFF     

// CONFIG1H
#pragma config FOSC = INTIO2   
#pragma config PLLCFG = OFF   
#pragma config FCMEN = OFF   
#pragma config IESO = OFF      

// CONFIG2L
#pragma config PWRTEN = OFF     
#pragma config BOREN = SBORDIS
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)

// CONFIG2H
#pragma config WDTEN = OFF      // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 16  // Watchdog Postscaler (1:1048576)

// CONFIG3L
#pragma config RTCOSC = INTOSCREF // RTCC Clock Select (RTCC uses INTOSCREF)

// CONFIG3H
#pragma config CCP2MX = PORTC   // CCP2 Mux (RC1)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RG5 Disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)

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

/************************时钟配置部分
IRCF2 = 1;
    IRCF1 = 1;
    IRCF0 = 1;                                                                  //内部16M时钟
    SCS1 = 1;
    PLLEN = 0;                                                                  //不4倍频
    SOSCRUN = 0;
    MFIOSEL = 0;
    //OSCTUNE = 0X80;
    while(!HFIOFS);

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

/***********************定时器配置部分
void Time0InitConfig()
{
    T08BIT = 0;                                                                 //16位定时器
    T0CS = 0;                                                                   //内部1/4FOSC时钟
   
    T0PS2 = 0;
    T0PS1 = 0;
    T0PS0 = 1;                                                                  //预分频器1/4分频
   
    PSA = 0;                                                                    //设置使用预分频器的频率
   
    TMR0L = 0x9c;
    TMR0H = 0xff;
    //TMR0 = 156;                                                                 //定时100us
    TMR0IE = 1;                                                                 //启动中断
    TMR0ON = 1;                                                                 //开启定时器中断
    TMR0IF = 0;
}
***********************/
/************定时器中断
void Tmr0Interrupt_ISR()
{
    static uint x;
    if(TMR0IF == 1)
    {        
        TMR0IF = 0;
        TMR0L = 0x9c;
        TMR0H = 0xff;
        BeepWork();
        x++;
        if(x <= 10000)
            LED2 = 0;
        else if(x <= 20000)
            LED2 = 1;
        else
            x = 0;
    }
}
/************
wyjie 发表于 2022-7-10 11:34 | 显示全部楼层

先别累加, 看看一次中断的测量值和理论值各是多少?
juventus9554 发表于 2022-7-10 11:37 | 显示全部楼层
定时器可以0.5s中断一次呀。
dingy 发表于 2022-7-10 11:40 | 显示全部楼层
建议用MCC配置和生成基本的程序,自己再修改。
xxrs 发表于 2022-7-10 11:43 | 显示全部楼层
可能是时钟误差
zhanghqi 发表于 2022-7-10 11:45 | 显示全部楼层
这个原因应该是从中断触发到在中断里面重新赋值TMR0L = 0x9c; TMR0H = 0xff的延迟引起; 这是因为进入中断以及中断中执行到TMR0赋值指令都是需要时间的。
chuxh 发表于 2022-7-10 11:48 | 显示全部楼层
这个延迟时间应该就是112-100=12uS. 你可以将Timer的时基变大,例如256分频。
dingy 发表于 2022-7-10 11:49 | 显示全部楼层
另外尽量将中断周期加长,使TMR0的值尽可能小,这样周期就得到加长,最好是直接1秒中断一次。在256分频时,取TMR0=0xC2F7应该可以了。
dengdc 发表于 2022-7-10 11:52 | 显示全部楼层
我看你用的内部16M啊,外部的4M用了吗?
llljh 发表于 2022-7-10 12:00 | 显示全部楼层
如果是内部的 时钟误差 + 中断延迟 + 指令执行时间 差不多吧
pengf 发表于 2022-7-10 12:03 | 显示全部楼层
为啥不尝试MCC生产代码??
heweibig 发表于 2022-7-10 12:05 | 显示全部楼层
简单又实用~~~还不用你这样来回折腾.....
 楼主| zwll 发表于 2022-7-10 12:08 | 显示全部楼层
这个~没说是要1S延时,要100us,1s我是用来测试的
jlyuan 发表于 2022-7-10 12:10 | 显示全部楼层

楼主还可以提高主频试试,还可以调整编译器的优化等级看看,  没其他太好的办法
 楼主| zwll 发表于 2022-7-10 12:13 | 显示全部楼层
其实还是不大明白,我再琢磨琢磨吧,多谢了哈先
您需要登录后才可以回帖 登录 | 注册

本版积分规则

885

主题

11314

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部