打印

PIC12F509 定时器不准的问题

[复制链接]
3047|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tzsteel|  楼主 | 2014-11-6 17:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include"pic12f509.h"
#include<htc.h>

__CONFIG  (0x0a);//(WDT_OFF & MCLRE_OFF & OSC_IntRC );
/******************引脚***************/
//unsigned char count=0;
#define LED1 GP4
#define LED2 GP2

main()
{   
    OSCCAL=0b00000000;
    TRIS=0b00001000;
    OPTION=0xc8;
     TMR0=0x08;   
        while(1)
        {
      if(TMR0==0xFF)
      {
       TMR0=0x08;
       //LED2 = !LED2;
       LED1=!LED1;
       }
    }
}
上面的软件,是使GP4的I/O口输出250US,翻转一次的PWM信号,实测是275US,误差比较大,因为509没中断,所以有点误差也能理解,但在LED1=!LED1;前加了一条LED2 = !LED2;GP4的输出马上变成了0.82MS的低电+0.82MS的高电,一条语句使PWM变化这么大,真的没法想像,请大家帮忙看看要咋弄啊,谢谢.   
沙发
tzsteel|  楼主 | 2014-11-6 19:09 | 只看该作者
本帖最后由 tzsteel 于 2014-11-6 19:14 编辑

250US测出来275US应该是if(TMR0==0xFF)引起的,有啥好的办法可以减少if判断语句,对TMR0的干扰?因为if里增加一条其它的语句,PWM就会变化很大.这样原先算好的定时时间的值,会因为if里语句的多少而改变,就没办法判别一个确定的时间.哪位高手能不能指点一下,谢谢.

使用特权

评论回复
板凳
wuhenyouyu| | 2014-11-6 19:31 | 只看该作者
在中断里处理GP4,定时器付初值的时候考虑误差,补偿回来!

使用特权

评论回复
地板
tzsteel|  楼主 | 2014-11-6 19:40 | 只看该作者
wuhenyouyu 发表于 2014-11-6 19:31
在中断里处理GP4,定时器付初值的时候考虑误差,补偿回来!

PIC12F509主要是没中断,才出现这问题的

使用特权

评论回复
5
wuhenyouyu| | 2014-11-6 21:16 | 只看该作者
tzsteel 发表于 2014-11-6 19:40
PIC12F509主要是没中断,才出现这问题的

有定时器,没有中断?你用查询的方法,误差也不会这么大啊?

使用特权

评论回复
6
yklstudent| | 2014-11-7 09:29 | 只看该作者
1、精确就直接用汇编写;
2、C语言可以见我写的;
#include <pic.h>

__CONFIG(MCLREN & WDTDIS & UNPROTECT & INTRC);

#define true                                        1
#define false                                        0

#ifndef _XTAL_FREQ
#define _XTAL_FREQ                                4000000ul
#endif

#define _BV(N)                                        (1ul << N)
#define _BIT_SET(val, bitno)        (val |= _BV(bitno))
#define _BIT_CLR(val, bitno)        (val &= ~_BV(bitno))
#define _BIT_TST(val, bitno)        (val & _BV(bitno))
#define _BIT_XOR(val, bitno)        (val ^= _BV(bitno))

typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;

extern void Init_Sys(void);
extern void Init_Cryxtal(void);
extern void Init_Port(void);
extern void Init_Timer0(void);

void main(void)
{
        Init_Sys();
        TMR0 = 0;
        while( true )
        {
                if(TMR0 >= 123)
                {
                        TMR0 = 0;
                        _BIT_XOR(GPIO, 4);
                }
        }
}

void Init_Sys(void)
{
        Init_Cryxtal();
        Init_Port();
        Init_Timer0();       
}

void Init_Cryxtal(void)
{
        OSCCAL = 0x00;
}

void Init_Port(void)
{
        GPIO = 0x00;
        TRIS = 0x00;       
}

void Init_Timer0(void)
{
        OPTION = 0b11000000;
}

软件仿真250us反转一次,实际估计误差会有点大,谁叫你用内部而不用外部的时钟呢

使用特权

评论回复
7
yklstudent| | 2014-11-7 12:56 | 只看该作者
补发一个汇编版本,根据C版本修改而来,仿真可以,实际没有验证过。
见如下所示:
        list        p=12f509
        #include <p12f509.inc>

        __config        _OSC_IntRC & _WDT_OFF & _CP_OFF & _MCLRE_ON

        __idlocs        0x1234

        org                00h
        nop

Init
        bcf                STATUS, 0x5
        clrf        OSCCAL
        ;bcf                STATUS, 0x5
        clrf        GPIO
        movlw        0
        tris        GPIO
        ;bcf                STATUS, 0x5
        movlw        0xc0
        option
        ;bcf                STATUS, 0x5
        clrf        TMR0       

main
        movlw        0x7b
        subwf        TMR0, w
        btfss        STATUS, 0
        goto        main
        clrf        TMR0
        movlw        0x10
        xorwf        GPIO, f
        goto        main
        end

使用特权

评论回复
8
tzsteel|  楼主 | 2014-11-7 17:40 | 只看该作者
yklstudent 发表于 2014-11-7 09:29
1、精确就直接用汇编写;
2、C语言可以见我写的;
#include

谢谢,楼上的回复

使用特权

评论回复
9
ayb_ice| | 2014-11-14 09:43 | 只看该作者
不能判断等于,

使用特权

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

本版积分规则

14

主题

72

帖子

0

粉丝