Hi, everyone: Does anybody has used ST3434E before? The easiset ADC gets me confused. Following is my code:
#include <ST/upsd3400.h> #include "DATATYPES.H" #include "ADC.h" sfr16 ADAT = 0x95; sfr16 P1SFS = 0x8e; #define ADC_ENABLE 0x20 #define ADC_START 0x02 #define ADC_BUSY 0x01 #define ADC_WORK (ADC_ENABLE | ADC_START) VOID ADC_Init(VOID) { P1SFS |= 0x0101; // ADC channel 0 //P1SFS0 = 0x01; //P1SFS1 = 0x01; ACON = ADC_ENABLE;// ADC enable, interrupt disable, channel 0 } WORD ADC_Read(VOID) { ACON = ADC_START; while (!(ACON & ADC_BUSY)); // wait until ADC is not busy //ACON &= ~ADC_ENABLE; return (ADAT); }
The bit 0 of ACON is status flag, when it is set to 1, the AD conversion completed. But it is never set!
Keil 8, JTAG debugger
ADC spec: Table 89. ACON Register (SFR 97h, Reset Value 00h) Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 AINTF AINTEN ADEN ADS2 ADS1 ADS0 ADST ADSF Details Bit Symbol Function 7 AINTF ADC Interrupt flag. This bit must be cleared with software. 0 = No interrupt request 1 = The AINTF flag is set when ADSF goes from '0' to '1.' Interrupts CPU when both AINTF and AINTEN are set to '1.' 6 AINTEN ADC Interrupt Enable 0 = ADC interrupt is disabled 1 = ADC interrupt is enabled 5 ADEN ADC Enable Bit 0 = ADC shut off and consumes no operating current 1 = Enable ADC. After ADC is enabled, 16ms of calibration is needed before ADST Bit is set. 4.. 2 ADS2.. 0 Analog channel Select 000 Select channel 0 (P1.0) 001 Select channel 0 (P1.1) 010 Select channel 0 (P1.2) 011 Select channel 0 (P1.3) 101 Select channel 0 (P1.5) 110 Select channel 0 (P1.6) 111 Select channel 0 (P1.7) 1 ADST ADC Start Bit 0 = Force to zero 1 = Start ADC, then after one cycle, the bit is cleared to '0.' 0 ADSF ADC Status Bit 0 = ADC conversion is not completed 1 = ADC conversion is completed. The bit can also be cleared with software.
I know little about this device, but by simply looking at your code, wouldn't
ACON = ADC_START;
clear ADEN and disable the ADC? I think perhaps better would be:
ACON |= ADC_START;
Also, are you delaying 16ms after first enabling the ADC?
#include <ST/upsd3400.h> #include "DATATYPES.H" #include "ADC.h" sfr16 ADAT = 0x95; sfr16 P1SFS = 0x8e; #define ADC_AINTF 0x80 #define ADC_AINTEN 0x40 #define ADC_ENABLE 0x20 #define ADC_START 0x02 #define ADC_BUSY 0x01 #define ADC_WORK (ADC_ENABLE | ADC_START) VOID ADC_Init(VOID) { P1SFS = 0x0101; // ADC channel 0 //P1SFS0 = 0x01; //P1SFS1 = 0x01; //ACON = ADC_ENABLE;// ADC enable, interrupt disable, channel 0 } WORD ADC_Read(VOID) { DWORD i; ACON &= 0xE3; // choose channel 0 ACON |= ADC_ENABLE; // enable and start ADC for (i = 0; i < 1000000L; i++); ACON |= ADC_START; while (!(ACON & ADC_BUSY)); // wait until ADC is not busy //ACON &= ~ADC_ENABLE; return ADAT; }
But the bit 0 of ACON is never set either.
And you've enabled the conversion clock in ADCPS?
I don't touch the ADCPS. I try it immediately.
OK, it's gonna work! Thank you very much. Stupid me!
Glad to hear it. Then I'm done for the night.
It's so kind of you. Wish you have a good night.