ADC Prevodnik PIC24FJ64GB/GA002

Všetko čo sa týka mikropočítačov + Sekcia Arduino

Moderátori: psichac, Moderátori

Diallix

ADC Prevodnik PIC24FJ64GB/GA002

Príspevok od používateľa Diallix » 30 Júl 2018, 12:13

Tato tema je v tom specificka, ze mi dala dost zabrat. Preto sa chcem podelit o kodmi s vami.

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 */
}
Pre dvojkanalovy 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]; 
   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; 
      } 
}

Používateľov profilový obrázok
Tribec Zacks
Pokročilý člen
Pokročilý člen
Príspevky: 709
Dátum registrácie: 26 Jún 2010, 00:00
Bydlisko: Levice / Cork IRL
Vek: 41
Kontaktovať používateľa:

Re: ADC Prevodnik PIC24FJ64GB/GA002

Príspevok od používateľa Tribec Zacks » 30 Júl 2018, 13:01

Ide o navod, alebo reklamu na svoj web?
0
Kreativita a motivacia je to, co prinasa originalne napady a myslienky, disciplina je to, co ich dokaze zrealizovat.

Diallix

Re: ADC Prevodnik PIC24FJ64GB/GA002

Príspevok od používateľa Diallix » 30 Júl 2018, 13:21

Navod.

Headere su na mojom webu, s tym nic urobit neviem.

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok