HOW TO PROGRAM 24 BIT ADC CS5532/34 with PIC 18f4550 MCU C18


In some particular application regular ADC units will not be enough. Because of the relativly small resolution (e.g. 10 or 8 bit) regular ADCs will not satisfy your demand. In this situation I am using CS5532/34 from Cirrus Logic. It has a stunning resolution of 24 bit. The problem is to program this unit is hard. There is not any example code for Microchip MPLAB C18. I have written an example code for Pic MCUs. Here I am sharing this codes for your help. 
Let's began with assigning the prototypes:

/**PROTOTYPES*******************************************************************************/
void csadc_init(void);//16/24bit adc başlat
void csadc_set(void);//6/24bit adc kanal ayarları
void csadc_read(char channel);//6/24bit adc okuma

The function called csadc_init() is the code that makes first initialization of the ADC IC.
void csadc_init(void)
{
    int i;
    ADC_CS=0;   

    OpenSPI(SPI_FOSC_64 ,MODE_00,SMPMID);//set the SPI module to communicate with the ADC.
     for(i=0; i<15 i="" span="" style="color: #666666;">//according to the data sheet the first thing you need to do is sending 15 sync1 code which is 0xFF.
     {
        //SPI başlatılmalı. Kontrol et.
        GonderAlSpi(0xFF);
    }
        GonderAlSpi(0xFE);//now you need to send sync1 code which is 0xFE.
//Now we will write 1 to the reset bit of the configuration register. This is going to reset the ADC.
//we need to write whole 32 bit of the configuration register.

       GonderAlSpi(0x03);//Write configuration register command 
    GonderAlSpi(0x20);//set the 29th bit (RS bit) ofthe configuration register.
       GonderAlSpi(0x00);
       GonderAlSpi(0x00);
       GonderAlSpi(0x00);

Delay10TCYx (25);
//wait for 20us. I am running the MCU at 48MHz 
//Now we need to make RS bit 0 again.
    GonderAlSpi(0x03);
//Write configuration register command         GonderAlSpi(0x00);//reset the 29th bit (RS bit) of the configuration register.    
    GonderAlSpi(0x00);
    GonderAlSpi(0x00);
    GonderAlSpi(0x00);
ADC_CS=1;
csadc_set();//I call this funtion to setup the channel setup register 1 for the next step.
The function called csadc_set() is the function that set the channel setup registers. Here I am leaving the whole setting as default. 

void csadc_set(void)//Setting the channel setup register.
{
    ADC_CS=0;
    GonderAlSpi(0x05);//Channel setup1 command
    GonderAlSpi(0x04);//Channel1
    GonderAlSpi(0xC0);
    GonderAlSpi(0x44);//channel2
    GonderAlSpi(0xC0);
    ADC_CS=1;
Now is the time to write the reading code. The function below select the phyisical channel 1 for channel=1 and physical channel 2 for the channel=2.
void csadc_read(char channel)
{

    ADC_CS=0;
if(
channel==1)
{
    GonderAlSpi(0x80);//select channel 1
}
else
{
    GonderAlSpi(0x88);//select channel 2
}

Delay100TCYx (250);
Delay100TCYx (250);
    GonderAlSpi(0x00);//clear the SDO flag
    v1=GonderAlSpi(0x00);//MSB of the ADC data
    v2=GonderAlSpi(0x00);
    v3=GonderAlSpi(0x00);//LSB of the ADC data
    v4=GonderAlSpi(0x00);//here there is some information. don't use them.
    ADC_CS=1;
   ToSendDataBuffer[adcrmsreg] = v1;//Your data now in the data buffer to be sent via USB.
    ToSendDataBuffer[adcrmsreg+1] =v2;
    ToSendDataBuffer[adcrmsreg+2] =v3;
    ToSendDataBuffer[adcrmsreg+3] =v4;
//bundan sonra veriyi göndereceğim
}
The function below is the function that send and get data via SPI
unsigned char GonderAlSpi(unsigned char data)
{
SSPBUF=data;
while(!SSPSTATbits.BF);
return SSPBUF;
Now we will call the functions in the main function
void main(void)
#else
int main(void)
#endif
{
   InitializeSystem();    
   Delay100TCYx (250);//wait for a little time to make sure the MCU stabilized.
    csadc_init();//İnitialize the ADC
    #if defined(USB_INTERRUPT)
        USBDeviceAttach();
    #endif

    while(1)
    {
        #if defined(USB_POLLING)
        // Check bus status and service USB interrupts.
        USBDeviceTasks(); // Interrupt or polling method.  If using polling, must call
                          // this function periodically.  This function will take care
                          // of processing and responding to SETUP transactions
                          // (such as during the enumeration process when you first
                          // plug in).  USB hosts require that USB devices should accept
                          // and process SETUP packets in a timely fashion.  Therefore,
                          // when using polling, this function should be called
                          // frequently (such as once about every 100 microseconds) at any
                          // time that a SETUP packet might reasonably be expected to
                          // be sent by the host to your device.  In most cases, the
                          // USBDeviceTasks() function does not take very long to
                          // execute (~50 instruction cycles) before it returns.

        #endif
                    

        // Application-specific tasks.
        // Application related code may be added here, or in the
ProcessIO() function.
         
          
         ProcessIO();      
    }//end while
}//end main 
Now you are ready to make conversion. I have used the case 0x37 in the ProcessIO() function.
case 0x37:   
{       
if(!HIDTxHandleBusy(USBInHandle))
{
 csadc_read(1);//read channel 1
ToSendDataBuffer[5] = v4;      //Measured analog voltage LSB
ToSendDataBuffer[6] = v3;      //
ToSendDataBuffer[7] = v2;      //
ToSendDataBuffer[8] = v1;      //Measured analog voltage MSB
csadc_read2);//read channel 2
ToSendDataBuffer[1] = v4;      //Measured analog voltage LSB
ToSendDataBuffer[2] = v3;      //
ToSendDataBuffer[3] = v2;      //
ToSendDataBuffer[4] = v1;      //Measured analog voltage MSB
                    
USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
}                    
}
Now your converted data is in the ToSendDataBuffer array and ready to be sent via USB.     

Yorumlar

  1. Yanıtlar
    1. You can try to understand how the code works. It is written in C. You can modify for any platform. But you can not use it directly.

      Sil

Yorum Gönder