我是用PIC16F1937,功能上基本是AD采集数据然后处理并段码液晶显示,另外还要检测两个按键。
程序中是使用2个内部时钟,一个4M的HF,一个31K的LF,想法是根据LF来设定定时器0为20ms中断,中断函数中检测按键并计数25次(即定时500ms),500ms到了之后把标志位display_flag置1,然后禁止定时器0中断。
主函数中一直在检测display_flag是否为1,如果为1则切换时钟到4M,然后AD检测并处理然后显示,然后切换到低速时钟并把display_flag清零并允许定时器0中断,然后继续循环检测display_flag为1。
实际在中断服务函数中设置端口翻转并示波器检测发现有时候是20ms,有时候确是160us。而且us级的波形每次都出现十几次翻转,表明是在4M时钟的情况下多次进入中断。。。。
以下附上相关代码:
1.初始化
void Timer0Init(void)//内部时钟定时方式
{
OPTION_REG = (OPTION_REG & 0xC0) | 0x10; // Fosc/4时钟,分频器 1/2
TMR0 = 0xB2;// 178;
timer0ReloadVal= 178;//定时时间=19.97ms
INTCONbits.TMR0IF = 0;//清除中断标志位
}
2.主函数中
while(1)
{
CLRWDT(); //看门狗复位(喂狗)
if((WorkOnFlag)&&(display_flag==1)) //延时结束,WorkOnFlag一般为1
{
display_flag=0;
LED2_SetHigh();
SystemCrystalSet_H_Speed(); //切换到高速时钟
AD_deal_AND_Display();
Key_Deal();
Display(); //显示程序
SystemCrystalSet_L_Speed(); //切换到低速时钟
LED2_SetLow();
INTCONbits.TMR0IE=1;//开启TIM0中断
}
}
3.时钟切换函数
void SystemCrystalSet_H_Speed(void)
{
OSCCON = 0b01101000;// 禁止 4x PLL; 0111 =500KHz HF;内部振荡器模块;//0x63;//2M 01011010 1101为4M
OSCTUNE = 0x00;// 振荡器调节寄存器TUN<5:0>=00000:振荡器模块以厂家校准后的频率运行;
while(!HFIOFR); //中频内部振荡器就绪位
}
void SystemCrystalSet_L_Speed(void)
{
OSCCON = 0b00000000;// 禁止 4x PLL; 0111 =500KHz HF;内部振荡器模块;//0x63;//2M 01011010 1101为4M
while(HFIOFR); //中频内部振荡器就绪位
}
4.定时器0服务函数
void TMR0_ISR(void)
{
INTCONbits.TMR0IF = 0; //clear the TMR0 interrupt flag
TMR0 += timer0ReloadVal; //中断一次20MS
//LED2_Toggle(); //端口翻转
++AlarmNum; //报警灯闪烁时间
if(AlarmNum>=252)
{AlarmNum = 0;}
if((WorkOnFlag) && (!CheckStFlag)) //延时结束
{KeyScan(); }
if(++T0_Count > 25) //中断次数 0.5s执行一次
{
T0_Count = 0;
display_flag=1;
if((WorkOnFlag) && (!CheckStFlag)) //延时结束
{INTCONbits.TMR0IE=0;}//关闭TIM0中断
}
}
5.端口控制相关代码
#define LED2_SetHigh() do { LATD2 = 1; } while(0)
#define LED2_SetLow() do { LATD2 = 0; } while(0)
#define LED2_Toggle() do { LATD2 = ~LATD2; } while(0)
理论应该是一个高电平脉冲紧跟着500ms左右的低电平,然后再来一个高电平脉冲,然后再是500ms低电平才对。
下图是看不懂的示波器图像,在密集的脉冲之间的低电平大概是20ms左右,猜测应该是4M主频下中断25次的时间。。。
请各位帮忙看看哪里不对的啊?
此帖出自
小平头技术问答
从LF切换到HF时,是要等振荡器就绪的,但是从HF切换到LF的,应该不需要等振荡器就绪的.
另外OSCCON=0b01101000是4 MHz HF
OSCCON = 0b00000000是时钟由配置字寄存器 1 中的 FOSC<2:0> 决定的时钟.
一周热门 更多>