比较难找
有时候运行2个多小时,有时候又能运行10几个小时,总之时间不确定,后就死了。
我的代码中有一段ADC的程序,会不会是ADC引起的。代码如下:
ADC12->CSR&=~ADC12_OR;
ADC12_ConversionStart();
while(ADC12_FlagStatus(ADC12_DA1)==RESET);
while(ADC12_FlagStatus(ADC12_OR));
{
ADC12_Value.i%=6;
ADC12_Value.buff[ADC12_Value.i]=ADC12_ConversionValue(ADC12_CHANNEL1);
ADC12->CSR &= ~ADC12_DA1;
ADC12_Value.i++;
ADC12_ConversionStop();
}
怀疑哪部分就先把哪部分关掉,然后再试
另外,系统不响应有多种情况,有可能是死循环,有可能是程序跑飞(超出预想的范围),也有个能是正在等待什么事件,带操作系统时还有可能是死锁,等等。楼主应该先确定是什么状况,确定了状况再查找原因。
删除了上面的代码,运行了一天没有跑飞
可我要测电池的电量,怎么办。STR710的ADC怎么用?
你的程序有点怪,请确认第4行后面的分号是有意加上的
如果分号是有意加上的,那么后面的两个大括号就是多余的。当然这不是错,我只是提醒,以防一个简单的错误害了大家。
我不会UCOS,没法想象是否与它有关。但我知道与OS扯上关系后,死锁或互斥区的保护是很头疼的问题,搞不好就会发生随机错误的状况。
还是我在4楼说的,你如何能确认是程序跑飞了,而不是操作系统中死锁了。即使是跑飞了也要确定是在哪里飞的,例如在几个关键点分别点亮几个LED,离开时关闭LED,在程序跑飞时看看哪个LED还在亮,大致可确认跑飞的范围。比如在你怀疑的读ADC的程序前点亮LED,读完ADC关闭LED。
刚看到你要测电池的电量,有一个问题,系统隔多长时间读一次ADC?
楼主可以只运行这段ADC的代码,循环运行
借此排除是这段程序的问题。
如果这段程序没有问题,那肯定是其它与这部分相关的程序间的配合有问题。
去掉这段ADC代码程序正常了。
运行了快30个小时了程序没有跑飞。
我的按键检测 20ms 4路AD 没问题
static void AppTaskKbd(void *p_arg)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
volatile int i,k;
int Key_ADValue;
int KeyTempValue[4];
int KeyValue[4];
int KeyDownInterval[4];
(void)p_arg;
KBD_Init();
Kbd_Status.KeyStatus=KeyStatus_Idle;
Kbd_Status.KeyValue=0;
for(i=0;i<4;i++)
{
KeyValue=0;
KeyTempValue=0;
KeyDownInterval=0;
}
while(1)
{
for(i=0;i<4;i++)
{
k=0;
OS_ENTER_CRITICAL();
Key_ADValue=do_ADC(i+4);
OS_EXIT_CRITICAL();
if((Key_ADValue>=AD_K1_Min)&&(Key_ADValue<=AD_K1_Max))
k=i*5+1;
if((Key_ADValue>=AD_K2_Min)&&(Key_ADValue<=AD_K2_Max))
k=i*5+2;
if((Key_ADValue>=AD_K3_Min)&&(Key_ADValue<=AD_K3_Max))
k=i*5+3;
if((Key_ADValue>=AD_K4_Min)&&(Key_ADValue<=AD_K4_Max))
k=i*5+4;
if((Key_ADValue>=AD_K5_Min)&&(Key_ADValue<=AD_K5_Max))
k=i*5+5;
if(k) //有键按下,重复按键的判断
{
if(k==KeyTempValue) //上次的按键
{
KeyDownInterval+=20;
if(KeyValue) //已处于按下状态
{
if(KeyDownInterval>400)
{
KeyDownInterval=0;
Kbd_Status.KeyStatus=KeyStatus_Repeat;
Kbd_Status.KeyValue=KeyValue;
OSMboxPost(MBox_Key,(void*)&Kbd_Status);
//sprintf(TxBuf,"%02x>
",KeyValue);
//AT91F_US_SendFrame(AT91C_BASE_US1,TxBuf,5 ,0,0);
}
}
else //尚没有键按下
{
if(KeyDownInterval>40)
{
KeyValue=KeyTempValue;
KeyDownInterval=0;
Kbd_Status.KeyStatus=KeyStatus_Down;
Kbd_Status.KeyValue=KeyValue;
OSMboxPost(MBox_Key,(void *)&Kbd_Status);
//sprintf(TxBuf,"%02x>
",KeyValue);
//AT91F_US_SendFrame(AT91C_BASE_US1,TxBuf,5 ,0,0);
}
}
}
else //新按键或组合按键(认为错误)
{
if(KeyValue) //已经认定有键按下,新键值不对?
{
KeyTempValue=KeyStatus_Idle;
KeyDownInterval=0;
Kbd_Status.KeyStatus=KeyStatus_Up;
Kbd_Status.KeyValue=KeyValue;
OSMboxPost(MBox_Key,(void *)&Kbd_Status);
KeyValue=KeyStatus_Idle;
}
else //认定新键按下
{
KeyTempValue=k;
KeyValue=KeyStatus_Idle;
KeyDownInterval=0;
//Kbd_Status.KeyStatus=Key_Error;
//Kbd_Status.KeyValue=KeyValue;
//OSMboxPost(MBox_Key,(void *)&Kbd_Status);
}
}
}
else //没有键按下或已抬起
{
if(KeyValue)
{
Kbd_Status.KeyStatus=KeyStatus_Up;
Kbd_Status.KeyValue=KeyValue;
OSMboxPost(MBox_Key,(void *)&Kbd_Status);
}
KeyDownInterval=0;
KeyTempValue=KeyStatus_Idle;
KeyValue=KeyStatus_Idle;
}
}
OSTimeDly(20);
}
}