小弟写了一段热敏电阻查表转换程序,有点不是预期的效果!
问题如下:AD采样然后执行算法,但是查表时候一直循环,查不出来!是不是算法没有执行啊,小弟用的是飞思卡尔XEP100的板子! 程序在下边,#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define BUS_CLOCK 32000000
#define OSC_CLOCK 16000000
#define FAN1 PORTB_PB2
#define FAN1_dir DDRB_DDRB2
#define FAN2 PORTA_PA3
#define FAN2_dir DDRA_DDRA3
#define FAN3 PORTA_PA4
#define FAN3_dir DDRA_DDRA4
#define FAN4 PORTA_PA5
#define FAN4_dir DDRA_DDRA5
#define FAN5 PORTD_PD7
#define FAN5_dir DDRD_DDRD7
#define FAN6 PORTD_PD6
#define FAN6_dir DDRD_DDRD6
#define FAN7 PORTD_PD5
#define FAN7_dir DDRD_DDRD5
#define FAN8 PORTD_PD4
#define FAN8_dir DDRD_DDRD4
#define FAN9 PORTA_PA7
#define FAN9_dir DDRA_DDRA7
#define FAN10 PORTA_PA6
#define FAN10_dir DDRA_DDRA6
const unsigned int oumu[]={
10450,10000,9574,9166,8778,8480,8058,7724,7404,7098,6808,6532,6268,6015,5776,5546,5326,5118,4918,4726,4544,4368,4202
};
const unsigned int temp[]={
24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46
};
unsigned char chanel;
unsigned int AD_in0,AD_in1,AD_in2,AD_in3,AD_in4,AD_in8,AD_in9,AD_in10,AD_in11,AD_in12;
unsigned int y=0;
unsigned char h=0;
float a,b;
void INIT_PLL(){ //初始化锁相环
CLKSEL &=0x7f;
PLLCTL &=0x8F;
CRGINT &=0xDF;
#if (BUS_CLOCK == 40000000)
SYNR=0x44;
#elif (BUS_CLOCK ==32000000)
SYNR=0x43;
#elif (BUS_CLOCK == 24000000)
SYNR=0x42;
#endif
REFDV=0x81;
PLLCTL |=0x70;
asm NOP;
asm NOP;
while(!(CRGFLG&0x08));
CLKSEL=0x80;
}
void INIT_AD(){ //初始化AD转换
ATD0CTL2=0x40; //启动A/D模块,快速清零,禁止中断
ATD0CTL1_SRES=2;//选用12位模数转换
ATD0CTL3=0x88; //每次只转换一个通道
ATD0CTL4=0x01; //AD模块时钟频率为8MHz
}
unsigned int AD_capture(chanel) //启动AD转换
{
unsigned int AD_data;
switch(chanel)
{
case 0:
ATD0CTL5 = 0x00; //转换AD00
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 1:
ATD0CTL5 = 0x01; //转换AD01
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 2:
ATD0CTL5 = 0x02; //转换AD02
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 3:
ATD0CTL5 = 0x03; //转换AD03
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 4:
ATD0CTL5 = 0x04; //转换AD04
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 8:
ATD0CTL5 = 0x08; //转换AD08
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 9:
ATD0CTL5 = 0x09; //转换AD09
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 10:
ATD0CTL5 = 0x0a; //转换AD10
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 11:
ATD0CTL5 = 0x0b; //转换AD11
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 12:
ATD0CTL5 = 0x0c; //转换AD12
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
}
return(AD_data);
}
void hanshu() { //电阻值算法
a=10*AD_capture(chanel)/(4.4-AD_capture(chanel));
b=a*1000;
y=(int)b;
}
void main(void) {
/* put your own code here */
DisableInterrupts;
INIT_PLL();
INIT_AD();
FAN1_dir=1;
FAN2_dir=1;
FAN3_dir=1;
FAN4_dir=1;
FAN5_dir=1;
FAN6_dir=1;
FAN7_dir=1;
FAN8_dir=1;
FAN9_dir=1;
FAN10_dir=1;
FAN1=1;
EnableInterrupts;
for(;;){
while(1){
hanshu();
while(!(y<=oumu[h]&&y>=oumu[h+1])) //将阻止与已知阻止表比较
{
h++;
if (h==24){
h=0;
}
}
AD_in0=temp[h];
}
if (AD_in0>45)
FAN1=0;
else if (AD_in0<25)
FAN1=1;
if (AD_in1>45)
FAN2=0;
else if (AD_in1<25)
FAN2=1;
if (AD_in2>45)
FAN3=0;
else if (AD_in2<25)
FAN3=1;
if (AD_in3>45)
FAN4=0;
else if (AD_in3<25)
FAN4=1;
if (AD_in4>45)
FAN5=0;
else if (AD_in4<25)
FAN5=1;
if (AD_in8>45)
FAN6=0;
else if (AD_in8<25)
FAN6=1;
if (AD_in9>45)
FAN7=0;
else if (AD_in9<25)
FAN7=1;
if (AD_in10>45)
FAN8=0;
else if (AD_in10<25)
FAN8=1;
if (AD_in11>45)
FAN9=0;
else if (AD_in11<25)
FAN9=1;
if (AD_in12>45)
FAN10=0;
else if (AD_in12<25)
FAN10=1;
}
}
/* loop forever */
/* please make sure that you never leave main */
while(!(y<=oumu[h]&&y>=oumu[h+1])) //将阻止与已知阻止表比较
{
h++;
if (h==24){
h=0;
}
这里的h最好在while前赋初值
已经好了,谢谢老哥!
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define BUS_CLOCK 32000000
#define OSC_CLOCK 16000000
#define FAN1 PORTB_PB2
#define FAN1_dir DDRB_DDRB2
#define FAN2 PORTA_PA3
#define FAN2_dir DDRA_DDRA3
#define FAN3 PORTA_PA4
#define FAN3_dir DDRA_DDRA4
#define FAN4 PORTA_PA5
#define FAN4_dir DDRA_DDRA5
#define FAN5 PORTD_PD7
#define FAN5_dir DDRD_DDRD7
#define FAN6 PORTD_PD6
#define FAN6_dir DDRD_DDRD6
#define FAN7 PORTD_PD5
#define FAN7_dir DDRD_DDRD5
#define FAN8 PORTD_PD4
#define FAN8_dir DDRD_DDRD4
#define FAN9 PORTA_PA7
#define FAN9_dir DDRA_DDRA7
#define FAN10 PORTA_PA6
#define FAN10_dir DDRA_DDRA6
const unsigned int oumu[]={
10450,10000,9574,9166,8778,8480,8058,7724,0,7404,7098,6808,6532,6268,6015,5776,5546,5326,5118,4918,4726,4544,4368,4202
};
const unsigned int temp[]={
24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47
};
unsigned char chanel;
unsigned int AD_in0,AD_in1,AD_in2,AD_in3,AD_in4,AD_in8,AD_in9,AD_in10,AD_in11,AD_in12;
unsigned int y=0;
unsigned char h;
float a,b;
void INIT_PLL(){ //初始化锁相环
CLKSEL &=0x7f;
PLLCTL &=0x8F;
CRGINT &=0xDF;
#if (BUS_CLOCK == 40000000)
SYNR=0x44;
#elif (BUS_CLOCK ==32000000)
SYNR=0x43;
#elif (BUS_CLOCK == 24000000)
SYNR=0x42;
#endif
REFDV=0x81;
PLLCTL |=0x70;
asm NOP;
asm NOP;
while(!(CRGFLG&0x08));
CLKSEL=0x80;
}
void INIT_AD(){ //初始化AD转换
ATD0CTL2=0x40; //启动A/D模块,快速清零,禁止中断
ATD0CTL1_SRES=2;//选用12位模数转换
ATD0CTL3=0x88; //每次只转换一个通道
ATD0CTL4=0x07; //AD模块时钟频率为2MHz
}
unsigned int AD_capture(chanel) //启动AD转换
{
unsigned int AD_data;
switch(chanel)
{
case 0:
ATD0CTL5 = 0x00; //转换AD00
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 1:
ATD0CTL5 = 0x01; //转换AD01
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 2:
ATD0CTL5 = 0x02; //转换AD02
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 3:
ATD0CTL5 = 0x03; //转换AD03
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 4:
ATD0CTL5 = 0x04; //转换AD04
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 8:
ATD0CTL5 = 0x08; //转换AD08
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 9:
ATD0CTL5 = 0x09; //转换AD09
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 10:
ATD0CTL5 = 0x0a; //转换AD10
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 11:
ATD0CTL5 = 0x0b; //转换AD11
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
case 12:
ATD0CTL5 = 0x0c; //转换AD12
while(!ATD0STAT0_SCF);
AD_data = ATD0DR0;
break;
}
return(AD_data);
}
void hanshu() { //电阻值算法
a=10*AD_capture(chanel)/(4.4-AD_capture(chanel));
b=a*1000;
y=(int)b;
}
void main(void) {
/* put your own code here */
DisableInterrupts;
INIT_PLL();
INIT_AD();
FAN1_dir=1;
FAN2_dir=1;
FAN3_dir=1;
FAN4_dir=1;
FAN5_dir=1;
FAN6_dir=1;
FAN7_dir=1;
FAN8_dir=1;
FAN9_dir=1;
FAN10_dir=1;
FAN1=1;
h=0;
EnableInterrupts;
for(;;){
hanshu();
while(!(y<=oumu[h]&&y>=oumu[h+1])) //将阻止与已知阻止表比较
{
h++;
if (h==24){
h=0;
}
}
AD_in0=temp[h];
if (AD_in0>45)
FAN1=0;
else if (AD_in0<25)
FAN1=1;
if (AD_in1>45)
FAN2=0;
else if (AD_in1<25)
FAN2=1;
if (AD_in2>45)
FAN3=0;
else if (AD_in2<25)
FAN3=1;
if (AD_in3>45)
FAN4=0;
else if (AD_in3<25)
FAN4=1;
if (AD_in4>45)
FAN5=0;
else if (AD_in4<25)
FAN5=1;
if (AD_in8>45)
FAN6=0;
else if (AD_in8<25)
FAN6=1;
if (AD_in9>45)
FAN7=0;
else if (AD_in9<25)
FAN7=1;
if (AD_in10>45)
FAN8=0;
else if (AD_in10<25)
FAN8=1;
if (AD_in11>45)
FAN9=0;
else if (AD_in11<25)
FAN9=1;
if (AD_in12>45)
FAN10=0;
else if (AD_in12<25)
FAN10=1;
}
}
/* loop forever */
/* please make sure that you never leave main */
老哥我这个改过的查表之后0的时候h=7是怎么回事呢?不应该是8或者9吗?
之前没注意,为什么表里会有0,最好能按升序或降序的方式排列,你用的判断方法应该是只适用于顺序排列的列表。
你的判断依据是y<=oumu[h]&&y>=oumu[h+1],0位于h=8的位置,从表来看y不会小于0,除非y等于0,不然h不会大于8,当y不等于0时,h=7时,y>=oumu[h+1]成立,所以只有y=0时,h=8,其他情况都会是h=7。
表里h>8的数据有可能会查不到。
原来如此,因为我现在没板子,AD数值是0,所以我就写了个0进去,把顺序这块给忽略了!在次感谢老哥!