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.
Cam It be used um arduíno?
YanıtlaSilYou 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