ADC- co to vlastne je?
Ide o prevod Analogoveho signalu na signal Digitalny. Ide o prememenu signalu prostrednictvom samplovania. Na input procesora mozete pripojit potenciometer, mikrofon, atd. a dostanete vysledne hodnoty, ktore dalej mozete spracovat.
Kod pre jednokanalovy ADC je:
Kód: Vybrať všetko
#include "config_diall.h" // http://www.diallix.net/headers
#include "config_words.h" // http://www.diallix.net/headers
#include "LCD_D.h" // http://www.diallix.net/el/145-lcdcontroll
char *PageSys(void)
{
return "0x21";
}
struct __attribute__ ((packed)) {
float voltage;
float number;
char results_voltage[32];
char results_number[32];
}ADC_Results;
unsigned long ADCValue = 0;
void ADC_Init(void)
{
CLKDIV = 0;
//Init_Port2(PORTA, 1, "analog"); /* Set AN1 as analog */
AD_Set_Analog(AN1); /* Set AN1 as analog */
Set_ADC_port(AN1); /* Set AN1 port for scanning */
Config_OUT(TRISA,0); /* Set RA0 for detect LED */
T3CON=0b1000000000110000; /* 50msec, 1/256,FOSC=16MH, Current time clock */
PR3 = 3124; /* 50000 ·((1/16) —256)-1 = 3124 */
AD1CON1 = 0x8044; /* AD1CON1:A/D1 Configure sample clock source
and conversion trigger mode.
Unsigned Fraction format (FORM<1:0>=10),
Manual conversion trigger (SSRC<3:0>=000),
Manual start of sampling (ASAM=0),
No operation in Idle mode (ADSIDL=1) */
AD1CON2 = 0x0400; /* AD1CON2:A/D2; 31Tad 3.0Tcy
Configure A/D voltage reference
and buffer fill modes.Vr+ and Vr- from
AVdd and AVss (VCFG<2:0>=000),
Inputs are not scanned,
Interrupt after every sample */
AD1CON3 = 0x0000; /* AD1CON3:A/D3; MUX A
Configure A/D conversion clock as Tcy/2 */
AD1CHS = 0x0000; /* AD1CHS:A/D
Configure input channels */
IEC0bits.AD1IE = 1; /* Enable A/D conversion interrupt */
AD1CON1bits.ADON = 1; /* Turn on A/D */
AD1CON1bits.ASAM = 1; /* Sampling begins immediately after the last conversion */
AD1CON1bits.SAMP = 1; /* Start sampling the input */
}
void Display_Init(void)
{
OSCTUN = 0;
RCONbits.SWDTEN = 0;
This.Detect.Debug = FALSE;
LCD.Direct.Port = uintptr &PORTA;
LCD.Data.Port = uintptr &PORTB;
LCD.Direct.RS = 2;
LCD.Direct.RW = 3;
LCD.Direct.EN = 4;
//LedStatus.Port = uintptr &PORTB;
//LedStatus.Led = 0;
LCD_Init();
}
int main(void)
{
ADC_Init();
Display_Init();
Delay_us(50);
while(1)
{
//Delay_ms(ADCValue);
//Bit_Toogle(LATA, 0);
ADC_Results.voltage = ((float)ADC1BUF0 * 3.3f)/1024.0f;
sprintf(ADC_Results.results_voltage, "Voltage: %3.2f ",ADC_Results.voltage);
ADC_Results.number = ((float)ADC1BUF0);
sprintf(ADC_Results.results_number, "Number: %3.2f ",ADC_Results.number);
LCD_Send_(1,LCD.position_1,null);
LCD_Send_(0,null, ADC_Results.results_voltage);
LCD_Send_(1,LCD.position_2,null);
LCD_Send_(0,null, ADC_Results.results_number);
}
return 0;
}
void __attribute__((interrupt,auto_psv)) _ADC1Interrupt(void) /* interrupt thread */
{
ADCValue = ADC1BUF0; /* Get data from buffer0 */
IFS0bits.AD1IF = 0; /* ADC flag set 0 */
}
Kód: Vybrať všetko
#include "config_diall.h" // http://www.diallix.net/headers
#include "config_words.h" // http://www.diallix.net/headers
#include "LCD_D.h" // http://www.diallix.net/el/145-lcdcontroll
char *PageSys(void)
{
return "0x21";
}
struct __attribute__ ((packed)) {
float voltage;
float number;
char results_voltage[32];
char results_number[32];
unsigned long ADCValue1, ADCValue2;
}ADC_Results;
char* GetBufferData(unsigned long input_buffer_value, char * type);
void ADC_Init(void)
{
ADC_Results.ADCValue1=0;
ADC_Results.ADCValue2=0;
CLKDIV = 0;
//Init_Port2(&PORTA, 0, "analog"); /* Set AN0 as analog */
//Init_Port2(&PORTA, 1, "analog"); /* Set AN1 as analog */
AD_Set_Analog(AN0); /* Set AN0 as analog */
AD_Set_Analog(AN1); /* Set AN1 as analog */
Set_ADC_port(AN0); /* Set AN0 as input */
Set_ADC_port(AN1); /* Set AN1 as input */
Scan_ADC_port(AN0); /* Set AN0 for scanning */
Scan_ADC_port(AN1); /* Set AN1 for scanning */
//Config_OUT(TRISA,0); /* Set RA0 for detect LED */
T3CON=0b1000000000110000; /* 50msec, 1/256,FOSC=16MH, Current time clock */
PR3 = 3124; /* 50000 ·((1/16) —256)-1 = 3124 */
AD1CON1 = 0x8044; /* AD1CON1:A/D1 Configure sample clock source
and conversion trigger mode.
Unsigned Fraction format (FORM<1:0>=10),
Manual conversion trigger (SSRC<3:0>=000),
Manual start of sampling (ASAM=0),
No operation in Idle mode (ADSIDL=1) */
AD1CON2 = 0x0400; /* AD1CON2:A/D2; 31Tad 3.0Tcy
Configure A/D voltage reference
and buffer fill modes.Vr+ and Vr- from
AVdd and AVss (VCFG<2:0>=000),
Inputs are not scanned,
Interrupt after every sample */
AD1CON3 = 0x0000; /* AD1CON3:A/D3; MUX A
Configure A/D conversion clock as Tcy/2 */
AD1CHS = 0x0000; /* AD1CHS:A/D
Configure input channels */
//AD1CON2bits.CSCNA = 1; /* Scan inputs */
AD1CON2bits.SMPI0 = 1; /* Interrupt after 2 sequences */
//AD1CSSLbits.CSSL0 = 1; /* Scan 2 channels */
IEC0bits.AD1IE = 1; /* Enable A/D conversion interrupt */
AD1CON1bits.ADON = 1; /* Turn on A/D */
AD1CON1bits.ASAM = 1; /* Sampling begins immediately after the last conversion */
AD1CON1bits.SAMP = 1; /* Start sampling the input */
}
void Display_Init(void)
{
OSCTUN = 0;
RCONbits.SWDTEN = 0;
This.Detect.Debug = FALSE;
LCD.Direct.Port = uintptr &PORTA;
LCD.Data.Port = uintptr &PORTB;
LCD.Direct.RS = 2;
LCD.Direct.RW = 3;
LCD.Direct.EN = 4;
//LedStatus.Port = uintptr &PORTB;
//LedStatus.Led = 0;
LCD_Init();
}
int main(void)
{
ADC_Init();
Display_Init();
Delay_us(50);
while(1)
{
LCD_Send_(1,LCD.position_1,null);
LCD_Send_(0,null, GetBufferData(ADC_Results.ADCValue1, "number"));
//LCD_Send_(0,null, GetBufferData(ADC_Results.ADCValue1, "voltage"));
LCD_Send_(1,LCD.position_2,null);
//LCD_Send_(0,null, GetBufferData(ADC_Results.ADCValue2, "number"));
LCD_Send_(0,null, GetBufferData(ADC_Results.ADCValue2, "voltage"));
}
return 0;
}
void __attribute__((interrupt,auto_psv)) _ADC1Interrupt(void) /* interrupt thread */
{
AD1CON1bits.ASAM = 1; // Start automatic sampling and conversion
while (IFS0bits.AD1IF == 0);
ADC_Results.ADCValue1 = ADC1BUF0; /* Get data from buffer0 */
ADC_Results.ADCValue2 = ADC1BUF1; /* Get data from buffer1 */
IFS0bits.AD1IF = 0; /* ADC flag set 0 */
}
char * GetBufferData(unsigned long input_buffer_value, char * type)
{
if(type == "voltage")
{
ADC_Results.voltage = ((float)input_buffer_value * 3.3f)/1024.0f;
sprintf(ADC_Results.results_voltage, "Voltage: %3.2f ",ADC_Results.voltage);
return ADC_Results.results_voltage;
}
else if(type == "number")
{
ADC_Results.number = ((float)input_buffer_value);
sprintf(ADC_Results.results_number, "Number: %3.2f ",ADC_Results.number);
return ADC_Results.results_number;
}
}