Dominic Suter
10.06.2002, 08:20
Der PIC Mikroprozessor von Microchip freut sich immer grösserer Beliebtheit in seiner Verwendung, da er gleich mehrere Vorteile bieten kann. Er ist einerseits sehr kostengünstig, andererseits ist die Entwicklungssoftware als Freeware zu beziehen. Auch die Programmer sind sehr einfach aufgebaut und sollten in den meisten Fällen funktionieren.
Ich habe nun ein kleines Demo Programm geschrieben, welches die Typischen Anwendungen des PIC 16F84A aufzeigt. Das Programm liest 4 Schalter, die an RB4..7 sind ein (high-active) und zeigt den Zustand der Schalter an RA0..3 an. Die Anzeige kommt 1sekunde verzögert, damit die einfache Implementierung von Zeitschleifen aufgezeigt werden kann. Das Auslesen der Schalter wird gepollt, die Daten werden über das interne EEPROM an die LED bzw. RA0..3 gegeben.
Soblad länger als ca. 5s keine Aktivität am PIC wargenommen wurde, wird er in den Sleep-Mode versetzt. Das bedeuted, dass die bestehenden Ausgänge den Zustand beibehalten, den sie vor der Sleep Instruction inne hatten, jedoch sämtliche Oszillatoren verstummen (auch der externe RC Oszillator). Geweckt wird der PIC über einen Interrupt an einem der Kanäle RB4..7. Anschliessend steht das Programm wieder solange zur Verfügung, bis wieder 5s keine Aktivität beobachted wurde. Dieser Mode ist auch zum Stromsparen sehr geeignet.
Grundsätzlich kann der PIC auch in ASM programmiert werden. Das Instruction-Set ist meiner Erachtens aber sehr umständlich, da es einen sehr kleinen Sprachumfang hat. Desshalb empfehle ich allen, den PIC in C zu programmieren.
Hier folgt nun der Quelltext des PIC Programmes. Ich weise ausdrücklich darauf hin, dass das Programm bei mir funktioniert, aber sehr stark von der externen Beschaltung abhängig ist. Jedigliche Haftung bei einer Zerstörung des PIC, externen Elektronik, des Programmers usw. lehne ich ab. Auch die Funktionalität der Software kann nicht garantiert werden!
//+------------------------------------------------------+
//¦ :: PIC16F84A :: ¦
//¦ Demo Software for the Special Functions @ PIC 16F84A ¦
//+------------------------------------------------------+
//Programmed by SD14, May 2002,
//Header
#include <16F84A.H>
#USE DELAY (CLOCK=1420000) //1.42MHz Clock
#FUSES RC,NOWDT,NOPROTECT,NOPUT //Use XT mode, No Watch Dog, No Code Protect, No Power-up Timer
#id 0x1022 //CFD102 Software Version 2
#INT_RB //The Ports RB4..7 are enabled as Interrupt Sources
RB_ISR() //ISR for an Interrupt Event on RB4..7
{
#asm
nop
#endasm
}
//Equals
#byte port_a = 5 //defines the location of register port_a
#byte port_b = 6 //defines the location of register port_b
int x;
int y;
int activity;
main()
{
unsigned long i=0;
while (true) //Software endless loop (RB0..3 Polling)
{
enable_interrupts(global); //If a ststus @ RB4..7 changes -> Interrupt
set_tris_a(0x00); //All pins are outputs
set_tris_b(0xF0); //RB0..3 outputs, RB4..7 Inputs
while (i<5000)
{
x = port_b;
write_eeprom(0, x); //Write @ Adress Data x
y = read_eeprom(0); //pass Data @Adress 0 to y
switch (y)
{
case 0b11100000: //Conditions on Port A if the specified Pulse-Switch is set
port_a = 1;
i = 0; //Activity dedected, reset SLEEP Condition
delay_ms(1000); //Port condition is delayed for 1 second
break;
case 0b11010000:
port_a = 2;
i = 0;
delay_ms(1000);
break;
case 0b10110000:
port_a = 4;
i = 0;
delay_ms(1000);
break;
case 0b01110000:
port_a = 8;
i = 0;
delay_ms(1000);
break;
default:
port_a = 15;
++i; //no activity dedected, timer++ until SLEEP
delay_ms(1); //in fact, there should be a break for 5 seconds, (in while construct)
} //but it takes much longer.
}
enable_interrupts(RB_CHANGE); //Needed for PIC Weakup
port_a = 5; //Condition, that PIC is in SLEEP Mode
i = 0; //Counter Reset
sleep();
disable_interrupts(RB_CHANGE);
}
}
Ich habe nun ein kleines Demo Programm geschrieben, welches die Typischen Anwendungen des PIC 16F84A aufzeigt. Das Programm liest 4 Schalter, die an RB4..7 sind ein (high-active) und zeigt den Zustand der Schalter an RA0..3 an. Die Anzeige kommt 1sekunde verzögert, damit die einfache Implementierung von Zeitschleifen aufgezeigt werden kann. Das Auslesen der Schalter wird gepollt, die Daten werden über das interne EEPROM an die LED bzw. RA0..3 gegeben.
Soblad länger als ca. 5s keine Aktivität am PIC wargenommen wurde, wird er in den Sleep-Mode versetzt. Das bedeuted, dass die bestehenden Ausgänge den Zustand beibehalten, den sie vor der Sleep Instruction inne hatten, jedoch sämtliche Oszillatoren verstummen (auch der externe RC Oszillator). Geweckt wird der PIC über einen Interrupt an einem der Kanäle RB4..7. Anschliessend steht das Programm wieder solange zur Verfügung, bis wieder 5s keine Aktivität beobachted wurde. Dieser Mode ist auch zum Stromsparen sehr geeignet.
Grundsätzlich kann der PIC auch in ASM programmiert werden. Das Instruction-Set ist meiner Erachtens aber sehr umständlich, da es einen sehr kleinen Sprachumfang hat. Desshalb empfehle ich allen, den PIC in C zu programmieren.
Hier folgt nun der Quelltext des PIC Programmes. Ich weise ausdrücklich darauf hin, dass das Programm bei mir funktioniert, aber sehr stark von der externen Beschaltung abhängig ist. Jedigliche Haftung bei einer Zerstörung des PIC, externen Elektronik, des Programmers usw. lehne ich ab. Auch die Funktionalität der Software kann nicht garantiert werden!
//+------------------------------------------------------+
//¦ :: PIC16F84A :: ¦
//¦ Demo Software for the Special Functions @ PIC 16F84A ¦
//+------------------------------------------------------+
//Programmed by SD14, May 2002,
//Header
#include <16F84A.H>
#USE DELAY (CLOCK=1420000) //1.42MHz Clock
#FUSES RC,NOWDT,NOPROTECT,NOPUT //Use XT mode, No Watch Dog, No Code Protect, No Power-up Timer
#id 0x1022 //CFD102 Software Version 2
#INT_RB //The Ports RB4..7 are enabled as Interrupt Sources
RB_ISR() //ISR for an Interrupt Event on RB4..7
{
#asm
nop
#endasm
}
//Equals
#byte port_a = 5 //defines the location of register port_a
#byte port_b = 6 //defines the location of register port_b
int x;
int y;
int activity;
main()
{
unsigned long i=0;
while (true) //Software endless loop (RB0..3 Polling)
{
enable_interrupts(global); //If a ststus @ RB4..7 changes -> Interrupt
set_tris_a(0x00); //All pins are outputs
set_tris_b(0xF0); //RB0..3 outputs, RB4..7 Inputs
while (i<5000)
{
x = port_b;
write_eeprom(0, x); //Write @ Adress Data x
y = read_eeprom(0); //pass Data @Adress 0 to y
switch (y)
{
case 0b11100000: //Conditions on Port A if the specified Pulse-Switch is set
port_a = 1;
i = 0; //Activity dedected, reset SLEEP Condition
delay_ms(1000); //Port condition is delayed for 1 second
break;
case 0b11010000:
port_a = 2;
i = 0;
delay_ms(1000);
break;
case 0b10110000:
port_a = 4;
i = 0;
delay_ms(1000);
break;
case 0b01110000:
port_a = 8;
i = 0;
delay_ms(1000);
break;
default:
port_a = 15;
++i; //no activity dedected, timer++ until SLEEP
delay_ms(1); //in fact, there should be a break for 5 seconds, (in while construct)
} //but it takes much longer.
}
enable_interrupts(RB_CHANGE); //Needed for PIC Weakup
port_a = 5; //Condition, that PIC is in SLEEP Mode
i = 0; //Counter Reset
sleep();
disable_interrupts(RB_CHANGE);
}
}