• 1
  • 2

ADC prevodník, zobrazujeme napätie na LCD #2

. .

ADC prevodník, zisťujeme napätie na LCD.

 


V tomto článku si navrhneme kód pre zistenie napätia cez trimer zobrazeného na LCD displeji.

Okrem napätia budeme zobrazovať hodnotu ADC1BUF0, čo sa nám bude hodiť pri neskorších článkoch riadenia krokového motoru pomocou analógového joisticku.

Schéma zapojenia: SCHÉMA

Kód:

main.c


#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 */
}

 

 

 

 

Video: