16 Aralık 2018 Pazar
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
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.
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.15>
{
//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
//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
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(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.
}
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;
}
{
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
}
{
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;
}
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
#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
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[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.
Etiketler: 18f4550, 24 bit ADC, C18, CS5532, CS5532/34, CS5534, interfacing, MCU, MPLAB, PIC, SPI
Kaydol: Yorumlar [Atom]
