Documente Academic
Documente Profesional
Documente Cultură
Modulul ANALOG TO DIGITAL CONVERTER (A/D)
Modulul ANALOG TO DIGITAL CONVERTER (A/D)
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
1
bit 3-0 PCFG<3:0>: A/D Port Configuration Control bits:
REGISTER ADCON2:
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
#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);
while (ADCON0bits.GO);
ADCResult = (unsigned int) ReadADC();
voltage = (ADCResult*5.0)/1024; // conversia numărului în tensiune
CloseADC(); // închiderea modulului A/D
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:
2. Să se realizeze un program în care o nouă conversie analog numerică să se realizeze la apăsarea butonului S1.