我的单片机型号的是PIC16F1947,用的是PICC编译器。我的程序启动不起来,经过排查,应该是电容触摸按键程序中的数组处理不当导致的。其中涉及到两个数组:volatile uint Cap_Avg[]={0,0,0,0,0}; volatile uint Cap_Value[]={0,0,0,0,0};。 出现问题的是这两条语句, percent=((long)Cap_Avg[Index]-(long)Cap_Value[Index]);
Cap_Avg[Index]=Cap_Avg[Index]+((long)Cap_Value[Index]-(long)Cap_Avg[Index])/16;
如果将这两条语句屏蔽,程序可以正常运行。如果将这两条语句其中一条开启,那么程序就会跑飞了。
这个触摸程序是在中断中执行的。以下是我的按键触摸的子程序和中断程序。我是个新手,跪求各位大神指教额。
volatile uint Index=0; //通道
volatile uchar AvgIndex ; //频率计数
volatile uint Cap_Avg[]={0,0,0,0,0}; //平均
volatile uint Cap_Value[]={0,0,0,0,0}; //当前值区
volatile long percent;
/////////按键判断函数//////////////
void cap_ISR() //百分比判断法
{
Cap_Value[Index]=(TMR1H<<8)+TMR1L; //当前值 读取振荡频率TMR1值
percent=((long)Cap_Avg[Index]-(long)Cap_Value[Index]);
if(percent<0)
{
percent=0;
}
else
{
percent=percent*100;
percent=percent/Cap_Avg[Index];
}
if(percent<PCT_OFF) //无键按下
{
switch(Index)
{
case 0:Key.gongneng=0;
Key_confirm.gongneng_l=0;
break;
case 1:Key.timing =0; break;
case 2:Key.saofeng=0; break;
case 3:Key.standby=0;
Key_confirm.standby_l=0;
break;
case 4:Key.zhaoming=0;
Key_confirm.zhaoming_l=0;
break;
default:break;
}
if(AvgIndex<2) AvgIndex++;
else AvgIndex=0;
if(AvgIndex==2)
{
Cap_Avg[Index]=Cap_Avg[Index]+((long)Cap_Value[Index]-(long)Cap_Avg[Index])/16;
}
}
else if(percent>PCT_ON)
{
switch(Index)
{
case 0:Key.gongneng=1; break;
case 1:Key.timing=1; break;
case 2:Key.saofeng=1; break;
case 3:Key.standby=1; break;
case 4:Key.zhaoming=1; break;
default:break;
}
}
}
/////////计数通道//////////////
void SetNext(void)
{
Index++;
Index=Index%5;
CPSCON1=Index; //通道
}
////////TMR1启动函数///////////
void RestartTimers(void)
{
TMR1H=0;
TMR1L=0;
TMR1ON=1; //TRM1使能
TMR0 = TMR0INITIAL; //初值100
TMR0IF = 0;
}
void interrupt ISR(void) //中断处理
{
if(TMR0IF&&TMR0IE)
{
//////////按键检测/////////////////
TMR1ON=0; //TMR1关闭
cap_ISR(); //按键判断函数
SetNext(); //通道设置
RestartTimers(); //重启TMR1
}
if(TMR2IF&&TMR2IE)
{
TMR2IF = 0;
TMR2 = TMR2INITIAL;
/////////时间管理////////////
Time_Management();
//count_500ms ++;
////////定时任务管理/////////
TimeTask_Management();
}
//在中断程序结束时必须确认Timer0在ISR执行期间是否翻转
//如果翻转了,则认为是失败的采样,清除标志位重启定时器
if(TMR0IF&&TMR0IE)
{
TMR1ON=0; //TMR1关闭
RestartTimers(); //重启TMR1
}
}
|