Sunteți pe pagina 1din 5

Lucrarea nr.

7
Conversia Analog Numerică
Modulul ANALOG TO DIGITAL CONVERTER (A/D)
Acest modul permite conversia unui semnal de intrare analogic într-un număr pe 10 biți. Modulul este controlat
prin intermediul a 5 regiștrii:
• Registrul rezultat conversie A/D (ADRESH)
• Registrul rezultat conversie A/D (ADRESL)
• Registrul de control 0 (ADCON0)
• Registrul de control 1 (ADCON1)
• Registrul de control 2 (ADCON2)
Registrul ADCON0 controlează modul de operare al modulului.

REGISTRUL ADCON0

bit 7-6 Unimplemented: Read as ‘0’


bit 5-2 CHS<3:0> Analog Channel Select bits(1)
0000 = Channel 0 (AN0)
0001 = Channel 1 (AN1)
0010 = Channel 2 (AN2)
0011 = Channel 3 (AN3)
0100 = Channel 4 (AN4)
0101 = Channel 5 (AN5)
0110 = Channel 6 (AN6)
0111 = Channel 7 (AN7)
1000 = Channel 8 (AN8)
1001 = Channel 9 (AN9)
1010 = Channel 10 (AN10)
1011 = Channel 11 (AN11)
1100 = Channel 12 (AN12))
1101 = Channel 13 (AN13)
1110 = Channel 14 (AN14)
1111 = Channel 15 (AN15)
bit 1 GO/DONE: A/D Conversion Status bit
When ADON = 1:
1 = A/D conversion in progress
0 = A/D Idle
bit 0 ADON: A/D On bit
1 = A/D converter module is enabled
0 = A/D converter module is disabled

Registrul ADCON1 configurează pinii porturilor utilizate pentru conversia A/D.

REGISTER 21-2: ADCON1: A/D CONTROL REGISTER 1

bit 7-6 Unimplemented: Read as ‘0’


bit 5-4 VCFG<1:0>: Voltage Reference Configuration bits

1
bit 3-0 PCFG<3:0>: A/D Port Configuration Control bits:

A = Analog input D = Digital I/O

REGISTER ADCON2:

bit 7 ADFM: A/D Result Format Select bit


1 = Right justified
0 = Left justified
bit 6 Unimplemented: Read as ‘0’
bit 5-3 ACQT<2:0>: A/D Acquisition Time Select bits
111 = 20 TAD
110 = 16 TAD
101 = 12 TAD
100 = 8 TAD
011 = 6 TAD
010 = 4 TAD
001 = 2 TAD
000 = 0 TAD(1)

bit 2-0 ADCS<2:0>: A/D Conversion Clock Select bits


111 = FRC (clock derived from A/D RC oscillator)(1)
110 = FOSC/64
101 = FOSC/16
100 = FOSC/4
011 = FRC (clock derived from A/D RC oscillator)(1)
010 = FOSC/32
001 = FOSC/8
000 = FOSC/2

Tensiunea de referință poate fi aleasă prin program și poate fi diferența de tensiune între sursă (V DD ) și masă (V SS )
sau diferența de tensiune între pinii RA3/AN3/VREF+ și RA2/AN2/VREF- pins.

Pentru realizarea unei conversii analog numerice trebuie urmați pașii următori:
1. Configurarea modului A/D:
- Se configurează pinii analogici și tensiunea de referință (folosnd registrul ADCON1);

2
- Se selectează canalul de intrare (ADCON0);
- Se selectează timpul necesar pentru achiziție (ADCON2)
- Se selectează ceasul ce controlează conversia (ADCON2)
- Se activează modulul A/D (ADCON0)
2. Configurarea întreruperii A/D (dacă se dorește):
- Se resetează bitul ADIF;
- Se setează bitul ADIE;
- Se setează bitul GIE;
3. Se așteaptă timpul necesar pentru achiziție;
4. Se startează conversia:
- Se setează bitul GO/DONE (din registrul ADCON0);
5. Se așteaptă terminarea conversiei:
- Se verifică dacă bitul GO/DONE a fost resetat sau
- Se așteaptă întreruperea A/D;
6. Se citește rezultatul conversiei din registrul ADRESH:ADRESL;
7. Pentru următoarea conversie se merge la pasul 1 sau la pasul 2. Se definește timpul T AD ca timpul de conversie
pe bit. Pentru startarea următoarei achiziții trebuie așteptat minim 2T AD .

Principiul conversiei analog numerice este prezentat în figura următoare (pentru cazul unui convertor pe 3
biți).

În acest caz ave, 8 =23 nivelele de tensiune sunt reprezentate prin 8 valori (000, 001,...,111).
Pentru o tensiune de referință de 5V și o rezoluție de 10 biți a convertorului, calculul valorii care va fi
memorată în regiștrii ADRESH:ADRESL se realizează cu regula de trei simplă. Pentru o tensiune de 3.65 Volți
avem următorul număr:

Deci o tensiune de intrare de 3.65 V va fi reprezentată prin numărul zecimal 748 sau prin numărul binar
1011101100. În mod asemănător se poate determina orice nivel de tensiune. Numărul memorat în regiștrii
ADRESH:ADRESL poate fi plasat de la dreapta la stânga (cei mai semnificativi 6 biți din ADRESH nu sunt luați
în considerare) sau de la stânga la dreapta (cei mai puțin semnificativi 6 biți din ADRESL nu sunt luați în
considerare).

Exemplu: Programul următor afișează pe display tensiunea achiziționată de la bornele potențiometrului R3.
Această tensiune poate fi variată între 0 și 5V.

#include <xc.h>
#include <spi.h>
#include <delays.h>
#include <stdlib.h>
#include <math.h>
#include <adc.h>

3
// CONFIGURARE Microcontroller

#pragma config OSC = HSPLL


#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOREN = OFF
#pragma config WDT = OFF
#pragma config MCLRE = ON
#pragma config LVP = OFF
#pragma config XINST = OFF

#define CS PORTAbits.RA2
// addresele registrilor circuitului MCP23S17
#define IODIRA_ADDRESS 0x00
#define IODIRB_ADDRESS 0x01
#define GPIOA_ADDRESS 0x12
#define GPIOB_ADDRESS 0x13

// Prototipuri functii
void setIODIR(char, char);
void setGPIO(char, char);
void lcdCommand(char);
void lcdChar(unsigned char);
void lcdGoTo(char);
void lcdWriteString(unsigned char*);

int i;
unsigned int ADCResult=0;
float voltage=0;
char buf1[8];buf2[8];

void main(void)
{
while(1){
for(i=0;i<10;i++)
_delay(50000);

TRISAbits.RA2=0; // pe portul RA2 se face activarea circuitului Slave


CS=1; // setarea CS la high, pentru transmitere informatii la MCP23S17
OpenSPI1(SPI_FOSC_64, MODE_10, SMPEND); // configurare SPI
setIODIR(IODIRB_ADDRESS,0x00); // setare pini DB0-DB7 ca iesiri
setIODIR(IODIRA_ADDRESS,0x00); // set RS si E LCD ca iesiri

lcdCommand(0b00111111); // Functie setare display: 8 biti, 2 linii


lcdCommand(0b00001111); // Cursor
lcdCommand(0b00000001); // clear display
lcdCommand(0b00000110); // entry mode
lcdWriteString("Voltmetru:"); // scrierea unui sir de caractere
lcdGoTo(0x40); // salt la linia 2

// Conversie analog numerica


CloseADC();
ADCON0=0;
ADCON0bits.ADON = 1; // Activare modul A/D

ADCON1=0b00001110; // RA0 = analog input


ADCON2=0b10111010; // right Justified Fosc/32
ADCON0bits.GO=1; // start conversie

while (ADCON0bits.GO);
ADCResult = (unsigned int) ReadADC();
voltage = (ADCResult*5.0)/1024; // conversia numărului în tensiune
CloseADC(); // închiderea modulului A/D

double i_val, f_val, val,i_val1, f_val1;


f_val = modf( voltage, &i_val);

4
itoa(buf1, i_val, 10);
lcdWriteString(buf1);
lcdChar('.');
val=f_val*100;
f_val1 = modf( val, &i_val1);
itoa(buf2, i_val1, 10);
lcdWriteString(buf2);
lcdChar('V');
CloseSPI1();
}
}
// functie utilizata pentru scrierea valorilor in porturile MCP23S17
void setGPIO(char address, char value){
CS=0; // inceputul transmisiei
WriteSPI1(0x40);
WriteSPI1(address);
WriteSPI1(value);
CS=1; // sfarsitul transmisiei
}
/* funcție utilizata pentru setarea directiei porturilor circuitului MCP23S17 */
void setIODIR(char address, char dir){
CS=0;
WriteSPI1(0x40);
WriteSPI1(address); // selectare IODIRB
WriteSPI1(dir); // setare directie
CS=1;
}
// functie pentru transmitere comenzi către display
void lcdCommand(char command){
setGPIO(GPIOA_ADDRESS,0x00); // E=0
Delay10TCYx(0);
setGPIO(GPIOB_ADDRESS, command); // transmitere date
Delay10TCYx(0);
setGPIO(GPIOA_ADDRESS,0x40); // E=1
Delay10TCYx(0);
setGPIO(GPIOA_ADDRESS,0x00); // E=0
Delay10TCYx(0);
}
// Functia pentru afisarea unui caracter pe display
void lcdChar(unsigned char letter){
setGPIO(GPIOA_ADDRESS,0x80); // RS=1
Delay10TCYx(0);
setGPIO(GPIOB_ADDRESS,letter); // transmitere caracter pentru afisare
setGPIO(GPIOA_ADDRESS, 0xc0); // RS=1, EN=1
Delay10TCYx(0);
setGPIO(GPIOA_ADDRESS,0x00); // RS=0, EN=0
Delay10TCYx(0);
}
//* pozitionare cursor
void lcdGoTo(char pos){
lcdCommand(0x80+pos);
}
void lcdWriteString(unsigned char *s){
while(*s)
lcdChar(*s++);
}

TEME:

1. Să se implementeze programul din exemplu pe un microcontroller PIC18F8722.

2. Să se realizeze un program în care o nouă conversie analog numerică să se realizeze la apăsarea butonului S1.

S-ar putea să vă placă și