#include<pic.h>__CONFIG(0x3B31);
void initial();
void main()
{
unsigned char count;
initial();
while(1)
{
if(T0IF==1) //T0IF为TMR0的溢出中断申请标志位,T0IF=1时申请中断
{
T0IF=0; //T0IF必须软件清零
TMR0=61;
count++;
if(count==20) //count=20时,一共计数时钟脉冲=256*195*20=998400,4分频后的时钟频率为1MHz,即耗时0.9984s≈1s
{
RD0=!RD0; //控制LED灯亮暗变化
count=0;
}
}
}
}
void initial()
{
TRISD=0;
PORTD=0; //设置RD口为输出,且一开始输出低电平
OPTION=0x07; //设置定时器0定时方式,TMR0分频比为1:256
TMR0=61; //设置TMR0初始值为61,即每次计数195次便发出中断信号
}
上面已经对程序注释了,计算过程也注明了,用proteus仿真时结果并不是1秒亮,1秒灭,大概是1.5秒亮,1.5秒灭,望proteus高手指导!
那应该怎么写?我上面的程序其实是从郭天祥的视频里学的,我记得他的单片机的定时是比较正常,就是不知道为什么一到proteus就出问题了。
追答如果要用定时器0实现比较精确的定时,如你这个程序
#include__CONFIG(0x3B31);
unsigned long Timer0Count;
void initial();
void main()
{
initial();
while(1)
{
if(T0IF==1) //T0IF为TMR0的溢出中断申请标志位,T0IF=1时申请中断
{
T0IF=0; //T0IF必须软件清零
Timer0Count += 65536;
if(Timer0Count > 1000000)
{
Timer0Count -= 1000000; //每次到达1s后,累积的误差均在该变量中
RD0=!RD0; //控制LED灯亮暗变化
}
}
}
}
void initial()
{
TRISD=0;
PORTD=0; //设置RD口为输出,且一开始输出低电平
OPTION=0x07; //设置定时器0定时方式,TMR0分频比为1:256
TMR0=0; //因为TMR0没有禁止/使能位,所以这里要赋初值,每65536us溢出一次(FOSC = 4MHz)
Timer0Count = 0;
}
谢谢你的程序,其实我已经找到原因了,原因是proteus的时间跟电脑的时间不一致,我在proteus的仿真时间里认真对照过,LED灯确实是1秒亮,一秒灭。上网查过怎么调这个时间变成正常时间,但网上的都说调步长,我怎么调都调不到,你知道怎么调吗?
追答我第一次回答的时候,就说过仿真的时间不一定准确。我没用过PROTEUS