Friday, May 29, 2020

Reading multiple analog voltage inputs in the ADC module

As we can see in the previous post, the analog input channels could be selected by the CHS bits of the ADCON0 register.


In this example I use the ADC module to read four input analog pins RA0, RA1, RA2 and RA3. The selection is made by A 2 positions DIP switch. This DIP switch could make four values. This value make the selection of analog channel.


The overall process is 80 percents similar to the previous one.

Reading multiple analog voltage inputs
Schematic diagram. Four Potentiometers fed their analog input voltage to
RA0 to RA3. DSW1 is DIP switch make the analog channel selection
for the ADC module conversion. A four-digit multiplexed SSD displays
a decimal representation of each 10-bit analog resolution.

Source code is here.

#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*_XTAL_FREQ use for __delay*/
#define _XTAL_FREQ 4000000

void driveDisplays(unsigned int cnt){
 unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 //Digit 4 1000's
 PORTD=0x00;
 PORTC=ssd[cnt/1000];
 PORTD=0x01;
 __delay_ms(10);
 //Digit 3 100's
 PORTD=0x00;
 PORTC=ssd[(cnt%1000)/100];
 PORTD=0x02;
 __delay_ms(10);
 //Digit 2 10's
 PORTD=0x00;
 PORTC=ssd[(cnt%100)/10];
 PORTD=0x04;
 __delay_ms(10);
 //Digit 1 1's
 PORTD=0x00;
 PORTC=ssd[cnt%10];
 PORTD=0x08;
 __delay_ms(10);
}
unsigned int readADC(void){
    ADCON0bits.CHS=PORTB;
    GO=1;
    while(GO);
    __delay_ms(10);
    return (ADRESH<<8)+ADRESL;
}
void main(void){
    unsigned int adcResult;
    /*Analog and digital Port
     Configuration*/
    PORTB=0x00;
    PORTC=0x00;
    PORTD=0x00;
    TRISB=0x03; 
    TRISC=0x00;
    TRISD=0x00;
    /*PORTB has no analog inputs*/
    ANSELH=0x00;
    /*Enable Weak Pull ups*/
    nRBPU=0;
    /*Turn on RB0 and RB1
     Weak Pull Up resistor*/
    WPUB=0x03;
    /*Result is right justify*/
    ADFM=1;
    /*Set some analog pins of PORTA*/
    ANSEL=0x0F;
    /*Select FRC Clock of ADC module*/
    ADCON0bits.ADCS=0x03;
    /*Turn on ADC Module*/
    ADON=1;
    /*By default select AN0*/
    ADCON0bits.CHS=0b0000;
    /*initiate a conversion*/
    GO=1;
    /*Wait until GO=0 "done"*/
    while(GO);
    while(1){
        adcResult=readADC();
        driveDisplays(adcResult);
    }
}

Reading multiple analog voltage inputs
A simulation screen shot. The ADC module is reading the analog voltage
input fed from RA3. The result is 2.5 V which is 511 in digital representation. 



No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)