在一个小项目里面,用PIC16F913来主控,用来记录N个脉冲的时间,时间精确到10us,看了下资料,晶振可以最高20M 20M/4分频可以到5M。但是看了下第定时器的中断,软件模拟了下,进中断和出中断就要3.XX个US,如果加上脉冲捕获进中断的时间,一起的误差会不会超出10US的范畴???(思路是:一边捕获脉冲。一边开个5US的定时器片,一直累加。当脉冲捕获到N值时,关定时器。看定时了多少个5US) 刚接错PIC,不知道这样可行不?高手路过,喵喵。。。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
现在根据上面思路设计了下程序:
装载 CCPR1L,CCPR1H
时钟为外部引脚时钟(实际用信号发生器输入100hz)当TMR1H,TMR1L和CCPR1L,CCPR1H匹配时,产生中断关闭定时器TMR0。获取TMR0的值
TMR0从00-FF,溢出中断加一。
定时器1程序:
/*********************************************************************************************************
** Function name: Timer1_Init()
** Descriptions: 定时器1初始化
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void Timer1_Init() //定时器1初始化
{
TMR1CS =1; //定时器1时钟来源选择,此处设置为1,选着T1CKL1引脚,作为计数器,上升沿促发
T1SYNC =0 ; //定时器1外部时钟同部位,在计数定模式下,于系统时钟同步
T1OSCEN=0; //定时器1震荡有效位此处为1,即此处设置为有效
T1CKPS1=0; //T1CKPS0都是0,则分频比为0
T1CKPS0=0;
T1GE=0; //不使用门控位
LCDEN=0;
SE10=0;
TMR1H = 0x00;
TMR1L = 0x00;
TMR1ON=0;//关闭定时器1
//设置 比较 模块下
CCP1M3=1;//设置在比较模式下 及00001010
CCP1M2=0;
CCP1M1=1;
CCP1M0=0;
CCP1IF=0;//中断源复位
}
中断处理程序
void interrupt ISR(void) //中断服务程序
{
if ( T0IF ) //2.5us//判TMR0 中断 =2.5us
{
T0IF = 0; //清除TMR0 中断标志
TIME_CONT++;
//在此加入TMR0 中断服务
}
else if ( CCP1IF ) //=1us //判CCPX 中断
{
TMR1ON=0;//0.5us //关闭
CCP1IF= 0; //0.5us //清除TMR1 中断标志
if(START_FLAG==0xAA ) //2.5 //N个脉冲计算时间
{
T0IE = 0;//0.5us //关闭定时器
Copy_TMER0=TMR0;//备份TMR0值
Copy_TIME_CONT=TIME_CONT;//备份
TMR1ON=0;//关闭定时器1
CCP1IE=0;//关闭
nop();
}
else//开始计数器计数以及记录时间
{
TMR0 = 0x00; // 256us
T0IF = 0; //清除TMR0 中断标志
T0IE = 1;//打开定时器0
TIME_CONT=0;
START_FLAG=0xAA;//标志位置位
CCPR1L=0xFF;//装载脉冲个数 <65536
CCPR1H=0x00;//
TMR1L = 0x00;
TMR1H = 0x00; //计数器复位
TMR1ON=1;//开启计数器
}
//在此加入TMR1 中断服务
}
}
主函数:
/*********************************************************************************************************
** Function name: mainS
** Descriptions: 系统主函数
** input parameters:
** output parameters:
** Returned value: 无
*********************************************************************************************************/
void main()
{
uchar i,j;
Sys_initial(); //MCU参数初始化
TMR1ON=0;//关闭定时器1
TMR1H = 0x00; //计数器复位
TMR1L = 0x00;
TMR0=0;
T0IE = 0;//关闭定时器
T0IF = 0; //清除TMR0 中断标志
CCP1IF= 0; //清除TMR1 中断标志
TIME_CONT=0; //复位记录器
START_FLAG=0;//复位转换开始标志位
Copy_TMER0=0;
Timer0_Init(); //定时器0初始化
Timer1_Init();
CCPR1L=0x1E;//装载脉冲个数 30
CCPR1H=0x00;//
TMR1H = 0x00; //0。25S
TMR1L = 0x00;
TMR1ON=1;//开启定时器1
CCP1IE=1;//开启比较
while(1)
{
delay10ms(100);
}
} //end main
说明下
主函数中第一次装载
CCPR1L=0x1E;//装载脉冲个数 <65536
CCPR1H=0x00;//
是为了脉冲和定时器0开始同步,同步处理程序在中断的
else//开始计数器计数以及记录时间
{
TMR0 = 0x00; // 256us
T0IF = 0; //清除TMR0 中断标志
T0IE = 1;//打开定时器0
TIME_CONT=0;
START_FLAG=0xAA;//标志位置位
CCPR1L=0xFF;//装载脉冲个数 需要计数的真实脉冲个数
CCPR1H=0x00;//
TMR1L = 0x00;
TMR1H = 0x00; //计数器复位
TMR1ON=1;//开启计数器
}
出现问题: 发现随着 CCPR1L CCPR1H装载的值不同,测出时间会不稳定,测定方法为((256*N+ TTimer0模块寄存器值)*FOSC/4)N为定时器溢出次数) 随着CCPR1L CCPR1H装载值的增大,计算出来的时间也随着增大,如装载的值为10个脉冲,有可能误差为+12us,但装载的值为1000个脉冲,有可能误差为+60us 误差都是超一个方向递增。 调了一个早上,理了理思路,就是找不出来误差产生的原因?PIC用的不多,DX路过看下,我是用ICD2+MPLAB-IDE+HI-TECH PICC .
一周热门 更多>