We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have a problem about reading data from MCP3204 12 bit ADC with AT89S8252. I am reading data but data range is from 800 to BFF. I tried to use V(ref) 4.096V and 5V, freq=11.0592. I can read data but from 800 to BFF. I can not read all 12 bit from serial port, but i dont know...Please help me about this problem.
800 to BFF
That might be a problem with the SPI settings (clock phase and polarity). There are four possible combinations, which are also called SPI modes. Make sure you use the SPI mode that the ADC expects.
Firstly, Thanks for your reply. Yes can be.. But I don't know so much about spi comm. If you explain much more to solve the problem I will be pleased for your help. I also written the program code in C below.
#include<at898252.h> #include<stdio.h>
sbit ADC_CS = P3^4; sbit ADC_CLK = P1^7; sbit ADC_DO = P1^6; sbit ADC_DI = P1^5;
void InitSerial(void); void write_adc_byte(char data_byte); unsigned int ReadADC(unsigned char channel); void DelayMs(unsigned int count);
//--------------------------------------- // Main program //--------------------------------------- void main(void) { InitSerial(); // Initialize serial port while(1) { putchar(0x0C); // clear Hyper terminal printf("Ch 0 : %03X\n\r",ReadADC(0)); printf("Ch 1 : %03X\n\r",ReadADC(1)); DelayMs(1000); // Delay about 100 mS } }
//--------------------------------------- // Initialize serial port //--------------------------------------- void InitSerial(void) { SCON = 0x52; // setup serial port control TMOD = 0x20; // hardware (9600 BAUD @11.05592MHZ) TH1 = 0xFD; // TH1 TR1 = 1; // Timer 1 on }
//--------------------------------------- // read analog from ADC // Single end mode(2 channel) //--------------------------------------- unsigned int ReadADC(unsigned char channel) { unsigned char i,k; unsigned int AdcResult; // 12 bit
ADC_CS=0; // Active chip select k++; // Delay about 1 uS ADC_CLK=0; // make clock low first k++;k++; channel = channel? 0xF0 : 0xE0; k++;k++; // delay about 2 uS //--- write command 4 bit ---------- for(i=0; i< 4;i++) { ADC_DI = (channel & 0x80) != 0; channel<<=1; ADC_CLK=1; k++;k++; // delay about 2 uS ADC_CLK=0; }
k++;k++; // delay about 2 uS ADC_CLK=1; k++;k++; // delay about 2 uS ADC_CLK=0; k++;k++; // delay about 2 uS
//--- read ADC result 12 bit -------- AdcResult=0; for(i=0;i<12;i++) { ADC_CLK=1; k++;k++; // delay about 2 uS AdcResult<<=1; AdcResult=AdcResult | (ADC_DO & 0x01); ADC_CLK=0; k++;k++; // delay about 2 uS } ADC_CS=1; return(AdcResult); }
//--------------------------------------- // Delay mS function //--------------------------------------- void DelayMs(unsigned int count) { // mSec Delay 11.0592 Mhz unsigned int i; // Keil v7.5a while(count) { i = 115; while(i>0) i--; count--; } }