14
Μια πολύ γρήγορη και μικρή κατασκευή βολτόμετρου με ένδειξη 3 ψηφίων LED display και τον PIC18F1320,
http://ww1.microchip.com/downloads/e...Doc/39605F.pdf
μετρά τάσεις DC 0-30V. Κατασκευασμένο σε διάτρητη πλακέτα σε ένα απόγευμα
για χάρη ενός φίλου που ήθελε μια πρόχειρη ένδειξη τάσης τροφοδοσίας μιας συσκευής. Τίποτα
περίπλοκο, ακολουθεί τις βασικές αρχές σχεδιασμού τέτοιων εφαρμογών: ένας ρυθμιζόμενος
διαιρέτης τάσης με προστασία υπέρτασης άνω των 5V για μια αναλογική είσοδο του μ/Ε, 3 πολυπλεγμένα
LED displays κοινής ανόδου, ένα πολύ απλό τροφοδοτικό 5V, λίγες γραμμές κώδικα HI-TECH PICC18 και έτοιμο.
Σκοπός δεν είναι η καθεαυτού παρουσίαση σαν κατασκευή, αλλά η χρήση του σαν αναφορά για κάποιους φίλους
που μπαίνουν στον υπέροχο κόσμο των ψηφιακών ηλεκτρονικών. Απλή κατασκευή χωρίς εξωτικά υλικά
και με αρκετές χρήσεις. Επίσης, δέχεται και πολλούς πειραματισμούς σε ό,τι αφορά το εύρος τάσης εισόδου,
την πολυπλεξία των ενδείξεων και βέβαια τη λογική του προγράμματος.
Ακολουθούν φωτογραφίες της μικρής αυτής κατασκευής (οι οποίες λόγω βραδυκαυστότητας του περιβόητου
99,9% κάλυψης δικτύου φίλης μας κινητής τηλεφωνίας (!), θα αργήσουν να ανέβουν...)
Η κατασκευή αποτελείται απο 2 τμήματα, ένα του κυκλώματος ελέγχου και μέτρησης και ένα του κυκλώματος
ένδειξης. Μεταξύ τους ενώνονται με ένα header σε ορθή γωνία. Όταν τοποθετηθεί στο κουτάκι του, θα μπούν και
οι ανάλογες φωτογραφίες.
Ο κώδικας είναι γραμμένος σε περιβάλλον HI-TECH PICC18 compiler, ενσωματωμένου στο MPLAB και είναι
πάρα πολύ απλός. Οι χαρακτήρες 0-9 διαβάζονται απο μια ταμπέλα και εμφανίζονται με τη σειρά (κυκλικά 1-2-3)
ξεχωριστά σε κάθε ψηφίο σε γρήγορο καρρέ με τη βοήθεια μιας διακοπής του TMR0, ώστε το μάτι λόγω
μεταισθήματος να διαβάζει έναν τριψήφιο αριθμό κανονικά. Έτσι επιτυγχάνεται η πολυπλεξία της ένδειξης.
Το κύκλωμα χρονίζεται απο έναν κρύσταλλο 8MHz αλλά με μια μικρή αλλαγή στα configuration registers
μπορεί να δουλέψει με τον εσωτερικό ταλαντωτή για περισσότερη οικονομία στα υλικά.
Η μετατροπή της δεκαεξαδικής τιμής του ADRES καταχωρητή "κομματιάζεται" σε τρείς βοηθητικούς καταχωρητές
δεκάδων, μονάδων και δεκάτων (μετά την υποδιαστολή) και διαβιβάζεται στην ένδειξη με την προαναφερθείσα
σειρά (MSB--->LSB). H υποδιαστολή ανάβει μόνιμα μιας και το οργανάκι έχει (θεωρητική ένδειξη) απο 0-99.9
Η κύρια ρουτίνα προγράμματος:
Οι ρουτίνες αρχικοποίησης και μέτρησης του ADC:Κώδικας:1. MAIN.C //****************************************************************** // main.C // 17 OCTOBER 2014 // // Author: Manos Mar // // Started: 10 OCTOBER 2014 //*****************************************************************/* #include <pic18.h> //ΗΤ-PICC include file #include <stdio.h> //ΗΤ-PICC include file #include <string.h> //ΗΤ-PICC include file #include <stddef.h> //ΗΤ-PICC include file #include <htc.h> //ΗΤ-PICC include file #include "defs.h" //Local include file #include "delay.h" //HT-PICC modified local file #include "adc.h" //HT-PICC modified local file #define _XTAL_FREQ 8000000 const char SegCode[11] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xFF}; // 0 1 2 3 4 5 6 7 8 9 const char Column[3] = {0x06,0x0A,0x0C}; static char Segment[3] = {0x06,0x0A,0x0C}; static char ColCount=0x00; int hundrends = 0; int tenths = 0; int units = 0; int decUnits = 0; float result; unsigned int i; __CONFIG(1, XT ); __CONFIG(2, BOREN & WDTDIS & PWRTEN); //BORDIS=brown out reset disabled, WDTDIS=watch dog timer disabled __CONFIG(3, MCLREN); __CONFIG(4, DEBUGEN & LVPDIS & STVRDIS); //DEBUGEN=debug enabled, LVPDIS=low voltage programmin disabled __CONFIG(5, UNPROTECT); //unprotected __CONFIG(6, WRTEN); //flash write enabled //****************************************************************** void main(void) //Έναρξη κύριας ρουτίνας προγράμματος { Init(); Adc_Init(); Init_TMR0(); while(1) { result=0; for (i=0;i<100;i++) { result=result+Adc_Read(); DelayMs(1); } result= ((result/1023)*11.4*10)/100; disassembly(result); PORTB=0b11111111; PORTA=0b01111110; DelayMs(200); } } //******************************************************************* //Initialize Registers //******************************************************************* void Init() { OSCTUNE=0x1F; OSCCON=0x72; TRISA=0b00000001; TRISB=0b00000000; } //******************************************************************* //Timer1 //******************************************************************* void Init_TMR0() { T0PS0=0; //Prescaler is divide by 16 T0PS1=1; T0PS2=1; PSA=0; //Timer Clock Source is from Prescaler T0CS=0; //Prescaler gets clock from FCPU (5MHz) T08BIT=1; //8 BIT MODE TMR0IE=1; //Enable TIMER0 Interrupt PEIE=1; //Enable Peripheral Interrupt GIE=1; //Enable INTs globally TMR0ON=1; //Now start the timer! } //******************************************************************* // //******************************************************************* void interrupt ISR() { if(TMR0IE && TMR0IF) { Display(); TMR0IF=0; TMR0H=0; TMR0L=250; } } //******************************************************************* void Display() { PORTB=0B11111111; if (ColCount>=3) ColCount=0; PORTA = Column[ColCount]; DelayUs(900); PORTB=0B11111111; DelayUs(600); PORTB = 0b11111111; // off segment a-f Segment[0]=SegCode[tenths]; Segment[1]=SegCode[units]; Segment[2]=SegCode[decUnits]; PORTB = Segment[ColCount]; DelayUs(600); PORTB = 0b01111111; ColCount++; } //******************************************************************* void disassembly(float var) { int res; tenths = 40*var/1023; res=var; res = 40*res%1023; units = 10*res/1023; res = 10*res%1023; decUnits=10*res/1023; } //*******************************************************************
Κώδικας:2. ADC.C //****************************************************************** // ADC.C // 17 OCTOBER 2014 // // Author: Manos Mar // // Started: 10 OCTOBER 2014 //****************************************************************** #include <pic18.h> #include "adc.h" void Adc_Init() { ADCON0=0b00000000; ADCON1=0b01111110; ADCON2=0b10100001; ADON=1; //switch on the adc module GODONE=1; //Start conversion } unsigned int Adc_Read() { GODONE=1; while(GODONE) { return ADRES; } }