微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 小弟写了一段热敏电阻查表转换程序,有点不是预期的效果!

小弟写了一段热敏电阻查表转换程序,有点不是预期的效果!

时间:10-02 整理:3721RD 点击:
恳请各位大佬帮忙改正一下!由于昨天晚上发的帖子需要下载,所以今天重新发一贴,代码附上!恳请各位老哥帮忙指教一下,能让小弟有所进步!
问题如下: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进去,把顺序这块给忽略了!在次感谢老哥!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top