6 Συνημμένο(α)
Mini Voltmeter με τον PIC18F1320
Μια πολύ γρήγορη και μικρή κατασκευή βολτόμετρου με ένδειξη 3 ψηφίων LED display και τον PIC18F1320,
http://ww1.microchip.com/downloads/e...Doc/39605F.pdf
μετρά τάσεις DC 0-30V. Κατασκευασμένο σε διάτρητη πλακέτα σε ένα απόγευμα
για χάρη ενός φίλου που ήθελε μια πρόχειρη ένδειξη τάσης τροφοδοσίας μιας συσκευής. Τίποτα
περίπλοκο, ακολουθεί τις βασικές αρχές σχεδιασμού τέτοιων εφαρμογών: ένας ρυθμιζόμενος
διαιρέτης τάσης με προστασία υπέρτασης άνω των 5V για μια αναλογική είσοδο του μ/Ε, 3 πολυπλεγμένα
LED displays κοινής ανόδου, ένα πολύ απλό τροφοδοτικό 5V, λίγες γραμμές κώδικα HI-TECH PICC18 και έτοιμο.
Σκοπός δεν είναι η καθεαυτού παρουσίαση σαν κατασκευή, αλλά η χρήση του σαν αναφορά για κάποιους φίλους
που μπαίνουν στον υπέροχο κόσμο των ψηφιακών ηλεκτρονικών. Απλή κατασκευή χωρίς εξωτικά υλικά
και με αρκετές χρήσεις. Επίσης, δέχεται και πολλούς πειραματισμούς σε ό,τι αφορά το εύρος τάσης εισόδου,
την πολυπλεξία των ενδείξεων και βέβαια τη λογική του προγράμματος.
Συνημμένο Αρχείο 53177
Ακολουθούν φωτογραφίες της μικρής αυτής κατασκευής (οι οποίες λόγω βραδυκαυστότητας του περιβόητου
99,9% κάλυψης δικτύου φίλης μας κινητής τηλεφωνίας (!), θα αργήσουν να ανέβουν...)
Συνημμένο Αρχείο 53180Συνημμένο Αρχείο 53181Συνημμένο Αρχείο 53182
Η κατασκευή αποτελείται απο 2 τμήματα, ένα του κυκλώματος ελέγχου και μέτρησης και ένα του κυκλώματος
ένδειξης. Μεταξύ τους ενώνονται με ένα header σε ορθή γωνία. Όταν τοποθετηθεί στο κουτάκι του, θα μπούν και
οι ανάλογες φωτογραφίες.
Συνημμένο Αρχείο 53183
Ο κώδικας είναι γραμμένος σε περιβάλλον HI-TECH PICC18 compiler, ενσωματωμένου στο MPLAB και είναι
πάρα πολύ απλός. Οι χαρακτήρες 0-9 διαβάζονται απο μια ταμπέλα και εμφανίζονται με τη σειρά (κυκλικά 1-2-3)
ξεχωριστά σε κάθε ψηφίο σε γρήγορο καρρέ με τη βοήθεια μιας διακοπής του TMR0, ώστε το μάτι λόγω
μεταισθήματος να διαβάζει έναν τριψήφιο αριθμό κανονικά. Έτσι επιτυγχάνεται η πολυπλεξία της ένδειξης.
Το κύκλωμα χρονίζεται απο έναν κρύσταλλο 8MHz αλλά με μια μικρή αλλαγή στα configuration registers
μπορεί να δουλέψει με τον εσωτερικό ταλαντωτή για περισσότερη οικονομία στα υλικά.
Η μετατροπή της δεκαεξαδικής τιμής του ADRES καταχωρητή "κομματιάζεται" σε τρείς βοηθητικούς καταχωρητές
δεκάδων, μονάδων και δεκάτων (μετά την υποδιαστολή) και διαβιβάζεται στην ένδειξη με την προαναφερθείσα
σειρά (MSB--->LSB). H υποδιαστολή ανάβει μόνιμα μιας και το οργανάκι έχει (θεωρητική ένδειξη) απο 0-99.9
Η κύρια ρουτίνα προγράμματος:
Κώδικας:
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;
}
//*******************************************************************
Οι ρουτίνες αρχικοποίησης και μέτρησης του ADC:
Κώδικας:
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;
}
}