导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→神啊,救救我吧。(程序很奇怪的问题,恳求高手)[goo]

 *第13221篇: 神啊,救救我吧。(程序很奇怪的问题,恳求高手)

  
楼 主:goo 2003年6月9日09:58
 神啊,救救我吧。(程序很奇怪的问题,恳求高手)
我学着用Keil C,CPU是AT89C52,写的是一个AD转换。
源码如下:
#--------------------------------------------adc0809.h----------------------------------------
#define XBYTE ((unsigned char volatile xdata *)0x0)
#define AdcAddress  XBYTE[0] //ADC0809编在地址0,用P1.4做片选信号。
                                              //中断用IT1

/*typedef struct
{
 unsigned char ADC_DATA_READY;
 unsigned char CHANNEL;
 unsigned char ADC_DATA; 
}ADC_DATA;*/

unsigned char startadc(unsigned char channel);
void init_adc(void);

#-------------------------------------------adc0809.c------------------------------------------
#include "reg591.h"
#include "adc0809.h"
unsigned char adc_data_ready,adc_data;
void init_adc(void)
{
 adc_data_ready=1;
 IT1=1;//下降延触发。
 T2CON_1=0; //以下用T2产生clock信号给ADC0809.//大约700khz.
 T2CON_2=1;
 T2MOD=0x02;
 RCAP2L=0xfa;
 RCAP2H=0xff;
}

unsigned char startadc(unsigned char channel)
{
 if(adc_data_ready==0) return 0;
 EX1=1;//Enable ADC Interrupt;
 P1_4=0;
 adc_data_ready=0; //ADC工作中
 AdcAddress=channel;
 P1_4=1;
 return 1;
}

void interrupt_read_adc(void) interrupt 2
{
// toggle_red_led(1); 我测试用的,亮个灯而已。
 EX1=0; //Disable ADC Interrupt
 P1_4=0;
 adc_data=AdcAddress;
 P1_4=1;
 adc_data_ready=1; //问题就处在这里啊这里啊。
}

#-----------------------------------------------main.c--------------------------------------------
#include "reg591.h"
#include "adc0809.h"

extern unsigned char adc_data_ready,adc_data;
unsigned int timer1tick;//定时器用的。
unsigned int t1reload;

void init_timer1 (unsigned int  reload)
{
    t1reload = reload;
    timer1tick = 0;
    TR1      =  0;                   /* timer 1: stop */
    TMOD     |= 0x10;                /* mode 1 */
    IP1      |= 2;                   /* priority */
    TH1      =  reload / 256;
    TL1      =  reload % 256;
    TR1      =  1;                   /* timer 1: start */
    ET1      =  1;                   /* enable timer 1 int */
    EA        =  1;
}

void t1isr (void) interrupt 3
{
    TR1 =  0;                   /* timer 1: stop */
    TH1 = t1reload / 256;
    TL1 = t1reload % 256;       /* reload value */
    TR1 =  1;                   /* timer 1: restart */
    timer1tick++;
}

void main(void)
{
                init_adc();
 init_timer1(45535); 
                while(1){
  if (timer1tick>  =100)
  {
        if (startadc(0)){
   timer1tick=0;
   while(adc_data_ready==0);//问题是这里永远都是0,郁闷啊。
                                                //adc_data然后我们就可以处理ADC_DATA了。
                                     }
                                }
               }
}

#-----------------------------------reg591.h-------------------------------------------------------
/* (c) Copyright PHYTEC ELEKTRONIK GmbH.  1999, All rights reserved. */
/* 80591 Processor Declarations */
/* PWM names corrected by ESAcademy, June 2000 */

/*  BYTE Registers  */
sfr P0    = 0x80;
sfr P1    = 0x90;
sfr P2    = 0xA0;
sfr P3    = 0xB0;

sfr PSW   = 0xD0;
sfr ACC   = 0xE0;
sfr B     = 0xF0;
sfr SP    = 0x81;
sfr DPL   = 0x82;
sfr DPH   = 0x83;
sfr PCON  = 0x87;
sfr TCON  = 0x88;
sfr TMOD  = 0x89;
sfr TL0   = 0x8A;
sfr TL1   = 0x8B;
sfr TH0   = 0x8C;
sfr TH1   = 0x8D;
sfr IEN0  = 0xA8;
sfr IEN1  = 0xE8;

sfr IP0   = 0xB8;
sfr IP0H  = 0xB7;
sfr IP1   = 0xF8;
sfr IP1H  = 0xF7;

sfr S0CON = 0x98;
sfr S0BUF = 0x99;
sfr S0ADDR= 0xCB;
sfr S0ADEN= 0xF9;
sfr S0PSL = 0xFA;
sfr S0PSH = 0xFB;

sfr S1CON = 0xD8;
sfr S1ADR = 0xDB;
sfr S1DAT = 0xDA;
sfr S1STA = 0xD9;

sfr CML0  = 0xA9;
sfr CML1  = 0xAA;
sfr CML2  = 0xAB;
sfr CTL0  = 0xAC;
sfr CTL1  = 0xAD;
sfr CTL2  = 0xAE;
sfr CTL3  = 0xAF;

sfr ADCON = 0xC5;
sfr ADCH  = 0xC6;
sfr TM2IR = 0xC8;
sfr T2CON = 0xC8;
sfr T2MOD = 0xC9;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sbit T2CON_1 = 0xC9;
sbit T2CON_2 = 0xCA;

sfr CMH0  = 0xC9;
sfr CMH1  = 0xCA;
sfr CMH2  = 0xCB;
sfr CTH0  = 0xCC;
sfr CTH1  = 0xCD;
sfr CTH2  = 0xCE;
sfr CTH3  = 0xCF;

sfr CANSTA= 0xC0;
sfr CANCON= 0xC3;
sfr CANDAT= 0xC2;
sfr CANADR= 0xC1;
sfr CANMOD= 0xC4;

sfr TM2CON= 0xEA;
sfr CTCON = 0xEB;
sfr TML2  = 0xEC;
sfr TMH2  = 0xED;
sfr STE   = 0xEE;
sfr RTE   = 0xEF;
sfr PWM0  = 0xFC;
sfr PWM1  = 0xFD;
sfr PWMP  = 0xFE;
sfr T3    = 0xFF;
sfr AUXR  = 0x8E;
sfr AUXR1 = 0xA2;

sfr P1M1  = 0x92;
sfr P1M2  = 0x93;
sfr P2M1  = 0x94;
sfr P2M2  = 0x95;
sfr P3M1  = 0x9A;
sfr P3M2  = 0x9B;


/*  BIT Registers  */
/*  PSW  */
sbit CY    = 0xD7;
sbit AC    = 0xD6;
sbit F0    = 0xD5;
sbit RS1   = 0xD4;
sbit RS0   = 0xD3;
sbit OV    = 0xD2;
sbit F1    = 0xD1;
sbit P     = 0xD0;

/*  TCON  */
sbit TF1   = 0x8F;
sbit TR1   = 0x8E;
sbit TF0   = 0x8D;
sbit TR0   = 0x8C;
sbit IE1   = 0x8B;
sbit IT1   = 0x8A;
sbit IE0   = 0x89;
sbit IT0   = 0x88;

/*  IEN0  */
sbit EA    = 0xAF;
sbit EAD   = 0xAE;
sbit ES1   = 0xAD;
sbit ES0   = 0xAC;
sbit ET1   = 0xAB;
sbit EX1   = 0xAA;
sbit ET0   = 0xA9;
sbit EX0   = 0xA8;

/*  IEN1  */
sbit ET2   = 0xEF;
sbit ECAN  = 0xEE;
sbit ECM1  = 0xED;
sbit ECM0  = 0xEC;
sbit ECT3  = 0xEB;
sbit ECT2  = 0xEA;
sbit ECT1  = 0xE9;
sbit ECT0  = 0xE8;

/*  IP0  */
sbit PAD   = 0xBE;
sbit PS1   = 0xBD;
sbit PS0   = 0xBC;
sbit PT1   = 0xBB;
sbit PX1   = 0xBA;
sbit PT0   = 0xB9;
sbit PX0   = 0xB8;

/*  IP1  */
sbit PT2   = 0xFF;
sbit PCAN  = 0xFE;
sbit PCM1  = 0xFD;
sbit PCM0  = 0xFC;
sbit PCT3  = 0xFB;
sbit PCT2  = 0xFA;
sbit PCT1  = 0xF9;
sbit PCT0  = 0xF8;

/*  P0  */
sbit AD7   = 0x87;
sbit AD6   = 0x86;
sbit AD5   = 0x85;
sbit AD4   = 0x84;
sbit AD3   = 0x83;
sbit AD2   = 0x82;
sbit AD1   = 0x81;
sbit AD0   = 0x80;

/*  P1  */
sbit ADC5  = 0x97;
sbit ADC4  = 0x96;
sbit ADC3  = 0x95;
sbit ADC2  = 0x94;
sbit ADC1  = 0x93;
sbit ADC0  = 0x92;

sbit SDA   = 0x97;
sbit SCL   = 0x96;
sbit CT3I  = 0x95;
sbit CT2I  = 0x94;
sbit CT1I  = 0x93;
sbit CT0I  = 0x92;
sbit TXDC  = 0x91;
sbit RXDC  = 0x90;

sbit P1_5  = 0x95;
sbit P1_4  = 0x94;
/*  P2  */
sbit A15   = 0xA7;
sbit A14   = 0xA6;
sbit A13   = 0xA5;
sbit A12   = 0xA4;
sbit A11   = 0xA3;
sbit A10   = 0xA2;
sbit A9    = 0xA1;
sbit A8    = 0xA0;

/*  P3  */
sbit CSMR3 = 0xB5;
sbit CSMR2 = 0xB4;
sbit CSMR1 = 0xB3;
sbit CSMR0 = 0xB2;
sbit RT2   = 0xB1;
sbit T2    = 0xB0;

sbit RD    = 0xB7;
sbit WR    = 0xB6;
sbit T1    = 0xB5;
sbit T0    = 0xB4;
sbit INT1  = 0xB3;
sbit INT0  = 0xB2;
sbit TXD   = 0xB1;
sbit RXD   = 0xB0;

/*  S0CON  */
sbit SM0   = 0x9F;
sbit FE    = 0x9F;
sbit SM1   = 0x9E;
sbit SM2   = 0x9D;
sbit REN   = 0x9C;
sbit TB8   = 0x9B;
sbit RB8   = 0x9A;
sbit TI    = 0x99;
sbit RI    = 0x98;

/*  TM2IR  */
sbit T2OV  = 0xCF;
sbit CMI2  = 0xCE;
sbit CMI1  = 0xCD;
sbit CMI0  = 0xCC;
sbit CTI3  = 0xCB;
sbit CTI2  = 0xCA;
sbit CTI1  = 0xC9;
sbit CTI0  = 0xC8;
sbit CAN   = 0xCE;
#---------------------------------------结束----------------------
问题就是我在主程序里startadc后,ADC中断也产生了。ET1的中断也处理完了,按说adc_data_ready就应该是1了,但主程序中的判断while(adc_data_ready==0);却总是出不来啊,就一直还在等待。


  
2楼:qingtao 2003年6月9日11:54
 将adc_data_ready的类型前面加上volatile定义
由于adc_data_ready在中断中被修改过,因此应该定义成volatile类型的,如果不这么定义,那么程序有可能在编译时进行优化,从而出现你意想不到的情况。

>>>>>>对该主题发表你的看法

本主题贴数2,分页: [第1页]


[上一篇主题]:[求助]ds1305e 的 接的晶振怎么也不起振,跟电源接法有关系么?

[下一篇主题]:关于keil c51的中断仿真问题