AD-Wandler bei PIC16F87X
Der PIC16F87x
hat einen 10 Bit AD-Wandler
PIC16F871, PIC16F877 haben 8 Kanäle, andere nur 5 Kanäle
Unten vorgestellte Programm läuft auf allen PIC16F87x -Typen.
Funktion ADC() startet
eine AD-Wandlung
benötigt als Parameter der Kanalnummer,
und liefert gemessenen Wert.
Kanalnummer kann 0...8 sein.
Ausgabewert der ADC()-Funktion ist 10 Bit groß und kann zwischen 0...1024 liegen.
Am Anfang des Main-Programms
wird AD-Wandler konfiguriert:
Es werden alle Kanäle benutzt.
Referenzspannung ist Versorgungsspannung (in unserem Fahl: 5V ).
Daten werden rechtsbündig ausgegeben (bei hochwertigen Byte wird nur Bit0, Bit1
benutzt )
Um Ergebnisse sichtbar zu machen, werden die seriell zum Rechner übertragen.
Um dieses Ziel zu erreichen, bekommt PIC ein TTL => RS232 Pegelwandler und
wird über Nullmodemkabel mit serieller Schnittstelle des Rechners verbunden.
Schaltplan - Im Schaltplan habe ich zum Eingängen des ADC 8 Fadern (bzw. Potentiometern ) angeschlossen. Somit lassen sich Spannungen von 0V bis 5V einstellen. Nach der AD-Wandlung dass sind Werte: 0 - Fader am Anschlag unten, 1024 - Fader am Anschlag oben.
Im Unterprogramm InitUSART()
wird serielle Schnittstelle des PICs konfiguriert:
Asynchrone Modus wird eingestellt.
Baudrate wird auf 9600 Baud eingestellt.
Kommunikationsprotokoll
mit dem PC ist ganz einfach.
PC sendet Kanalnummer, daraufhin PIC macht eine Messung und sendet gemessenen
Wert als 2 Bits
(zuerst niedere Datenbyte, danach obere Datenbyte).
Danach wartet PIC wieder auf eine Kanalnummer.
Kanalnummer wird als Zahl
(Binärwert) erwartet, nicht als String (ACSII ).
Zum Testen empfehle ich COM-Terminal, damit kann
man einfache Zahlen und Strings über Serielle Schnittstelle senden und empfangen.
// Testprogramm: AD-Wandler auslesen und Werte zum PC übertagen
// Serielle Kommunikation mit (9600,N,8,1) TX==>RC6, RX==>RC7 TTL-RS232-Conwerter
// 20 MHz
#include <D:\cc5\16F871.H>
// Speicherschutz12,13,4,5=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,
// NiedervoltProgr7=aus, NiederVoltReset6=an,EinschaltTimer3=an,
// WachDogTimer2=aus,Oszillator0,1=XC
#pragma config |= 0b.11.111101.11.00.10
#pragma origin 100 // Adresse des Programms
//******************************************************************************
void InitUSART()
{
BRGH=1;
SPBRG=129; // (9600 baud @ 20MHz input clock)
SPEN = 1; // Set_Serial_Pins;
SYNC = 0; // Set_Async_Mode;
TX9 = 0; // Set_8bit_Tx;
RX9 = 0; // Set_8bit_Rx;
CREN = 1; // Enable_Rx;
TXEN = 1; // Enable_Tx;
RCIE=0; // Rx Interrupt aus
}
//******* Zeitverzögerung-Fnktion *************************************************
void delay_mks( char mikro)
{
#asm
wdh9 nop
nop
decfsz mikro,f
goto wdh9
#endasm
}
//******* AD-Wandler-Fnktion ***************************************************
uns16 ADC(char kanal)
{
uns16 Antwort;
ADCON0 &= 0b.1100.0111; // 3 Bits, die KanalNummer angeben, reseten
kanal= kanal << 3 ; // Kanalnummer auf richtige Position rotieren
ADCON0 |= kanal; // und durch ODER-Funktion in Register übertragen
delay_mks(50); // Warten, damit interne Meßkondensator geladen wird.
GO=1; // Starten der Wandlung
while(GO); // Solange warten bis Wandlung abgeschlossen ist
Antwort.low8=ADRESL; // Ergebnisse in Variable speichern
Antwort.high8=ADRESH;
return Antwort;
}
//*************************************************************************************
void main(void)
{
uns16 a; // Variablen
char n;
//++ Einstellungen des AD-Wandlers ++++++++++++++++++++++++++++
ADCON1=0; // Ganzer PortA als Analog Vdd Vss
ADON=1; // ADC-Einschalten
ADCS1=1 ; // Geschwingigkeit der ADC
ADCS0=0 ;
ADFM=1; // Rechts Ausrichtung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TRISC=0b.1011.1100; // RC6>TX, RC7>RX
InitUSART(); // Hardwareschnittstelle des PICs einstellen
while(1) // Ganzes Programm ist Endlosschleife
{
while(!RCIF); // Warte auf Empfang
n=RCREG; // Empfange Kanalnummer
a=ADC(n); // AD-Wandlung
while(!TXIF); // Prüfen, ob Sender frei ist
TXREG = a.low8; // Niederes Datenbyte senden
while(!TXIF); // Prüfen, ob Sender frei ist
TXREG = a.high8; // Oberes Datenbyte senden
} // Ende der Schleife
} // Ende des Hauptprogramms
Um das ganze zu visualisieren, habe ich ein Programm in Visual Basic geschrieben, das die Messwerte als Zahl und Schieberposition darstellt.
![]() |
Programm zum Auslesen der 8-Kanaläle des AD- Wandlers bei einem PIC16F877 / PIC16F871 über serielle Schnittstelle. |
| Ausführbare Programm herunterladen | |
| Quellcode in VB herunterladen | |
Datenübertragung erfolgt
mit 9600 Baud, keine Paritätsbit, ein Stoppbit.
Datenaktualisierung erfolgt 10 mal pro Sekunde.
Rechner sendet Nummer des Kanals (0, 1, 2, 3, ...) und empfängt 2 Byte: erstes
ist niederes Datenbyte , zweites ist oberes Datenbyte.
Auflösung des AD- Wandlers bei PIC ist 10Bit. Also werden Zahlenwerte von 0
bis 1024 übertragen.
Programm benutzt eine DLL -Datei mit Namen "Port.DLL".
Diese Datei muss entweder in gleichem Verzeichnis mit der "AD.exe"
sein
oder im Verzeichnis C:\WINDOWS\SYSTEM sein.
Mit dem Drücken der Schaltfläche
"Start" wird serieller Port geöffnet und kontinuierliche Auslesen
des AD -Wandlers angefangen.
In oberen Textfeldern tragen Sie maximalen Wert Ihres Messsignals ein. Unter
den Schiebern erhalten Sie umgerechnete Messwerte angezeigt. Mit dem Schliessen
des Fensters wird serieller Port geschlossen und Programm beendet.
|
Es ist cool. Man schiebt Fadern und gleichzeitig bewegen sich Schiebern auf dem Bildschirm. Mit dieser Hardware kann man zum Beispiel RGB - Farben mischen (kann ich realisieren). Wer sich mit dem WinAmp versteht könnte damit Equalizer steuern.
|
![]() |