Hallo zusammen
Ich habe immer noch massive Probleme mit dem PIC12F683. Langsam frage ich mich echt, ob dieser Chip irgend einen Defekt hat.
Ich möchte ein sehr simples Programm darauf laufen lassen, welches folgende Teilaufgaben beinhaltet:
1: Dem Chip wird ein Status von einem externen Gerät gegeben. Ist dieser Status=0 so soll eine LED im Halbsekundentakt blinken, ist der Status=1 so bleibt die LED dunkel.
2. Über ein TouchSensitive-IC wird dem PIC ein Befehl erteilt. Steht dieser Befehl 3 Sekunden an, so erhält ein externes Gerät einen einmaligen Impuls.
(Das externe Gerät schaltet so den Status um).
Eigentlich wollte ich dieses Problem mit einer ISR lösen, welche einen Timer hochzählt. Aber diese ISR arbeitet nicht richtig.
Ich habe testmässig die Software umgeschrieben. In der Testsoftware soll der TouchSensitive-Befehl den Status nach 3 Sekunden wechseln (ohne externes Gerät).
///////////////////////////////////////////////////////////////
// Device und Konfiguration ///////////////////////////////////
///////////////////////////////////////////////////////////////
#include <12F683.H>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOFCMEN,NOIESO,NOPUT,NOBROWNOUT
#use delay(clock=8000000)
#use fast_io (a)
///////////////////////////////////////////////////////////////
// Variablendeklaration ///////////////////////////////////////
///////////////////////////////////////////////////////////////
int Merker1, LED_Timer, Touch_Timer;
#bit MESSAGE_SENT = Merker1.0
#bit LED_STATUS = Merker1.1
#bit Touch_Timer_Reset = Merker1.2
#bit TEST = Merker1.3
///////////////////////////////////////////////////////////////
// E/A-Namen //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
#define FROM_QUANTUM PIN_A0 // Eingang Ansteuerung von QT310
#define KALIB PIN_A1 // Ausgang zur Kalibrierung
#define TO_SECURITOUCH PIN_A2 // Ausgang zum Hauptbedienteil
#define LED PIN_A4 // Ausgang LED-Anzeige
#define STATUS PIN_A5 // Eingang von Hauptbedienteil
///////////////////////////////////////////////////////////////
// Timer Subroutine ///////////////////////////////////////////
///////////////////////////////////////////////////////////////
#int_ccp1
void ccp1_isr (void){ // Bei Interrupt Timer 1 inkrementieren
++LED_Timer;
++Touch_Timer;
}
///////////////////////////////////////////////////////////////
// Start Hauptprogramm ////////////////////////////////////////
///////////////////////////////////////////////////////////////
void main(void) { // Hauptprogramm
///////////////////////////////////////////////////////////////
// E/A-Definition / CCP-Konfiguration /////////////////////////
///////////////////////////////////////////////////////////////
Setup_Timer_1(T1_INTERNAL | T1_DIV_BY_1); // Interner Takt, 1:1
Setup_CCP1 (CCP_COMPARE_RESET_TIMER); // Intgerupt Timer reset
ENABLE_INTERRUPTS (GLOBAL); // Interrupts global aktivieren
ENABLE_INTERRUPTS(INT_CCP1);
CCP_1=5000; // ca.30ms
SETUP_ADC_PORTS(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC);
set_tris_a(0b11101001);
///////////////////////////////////////////////////////////////
// Grundkonfiguration /////////////////////////////////////////
///////////////////////////////////////////////////////////////
Merker1=0;
Touch_Timer=0;
LED_Timer=0;
output_low(LED);
output_low(TO_SECURITOUCH);
output_low(KALIB);
delay_us(5);
output_high(KALIB);
delay_ms(20);
///////////////////////////////////////////////////////////////
// Endlosschleife /////////////////////////////////////////////
///////////////////////////////////////////////////////////////
while (1){ // Hauptschleife
output_high(KALIB);
///////////////////////////////////////////////////////////////
// Status-Anzeige /////////////////////////////////////////////
///////////////////////////////////////////////////////////////
if (TEST==0){
if (LED_STATUS==0){
output_high(LED);
if (LED_Timer>=17){
LED_STATUS=1;
LED_Timer=0;
}
}
if (LED_STATUS==1){
output_low(LED);
if (LED_Timer>=17){
LED_STATUS=0;
LED_Timer=0;
}
}
}
if (TEST==1){
output_low(LED);
LED_STATUS=0;
LED_Timer=0;
}
///////////////////////////////////////////////////////////////
// Verarbeitung TouchSensitive ////////////////////////////////
///////////////////////////////////////////////////////////////
if ((input(FROM_QUANTUM)==0)&(MESSAGE_SENT==0)){
if (Touch_Timer_Reset==0){
Touch_Timer=0;
Touch_Timer_Reset=1;
}
if (Touch_Timer>=100){
if (TEST==0){
TEST=1;
}
else{TEST=0;}
MESSAGE_SENT=1;
}
}
if (input(FROM_QUANTUM)==1){
Touch_Timer_Reset=0;
MESSAGE_SENT=0;
}
} //endwhile
} //endmain
Im Code ist auch der Eintrag "output_high(KALIB);" in der Endlosschleife zu sehen. Wird dieser Eintrag nicht in die Endlose übernommen, nimmt er den Zustand "low" ein ?!?
Im obigen Code sieht man im letzten Befehl den Eintrag "Touch_Timer_Reset=0;".
Wenn ich diesen entferne, so lässt sich der Test-Status umschalten. Ist der Eintrag drin, so bleibt der Test-Status auf 0 und die LED blinkt im Halbsekundentakt. Der TouchSensitive-Eingang hat so keine Wirkung.
Was für mich auch unerklärlich ist, sind die Einstellungen des CCP.
Bei anderen Anwendungen habe ich einen 4MHz Quarz verwendet, den CCP auf 10000 konfiguriert, dies entspicht somit 10ms. Ich konnte in der ISR auf 100 zählen lassen und hatte eine exakte Sekunde.
Bei dieser Anwendung verwende ich den internen Oszi auf 8MHz, stelle den CCP auf 5000 und erhalte ca. 30ms?! Gebe ich dem CCP einen anderen Wert (z.B. 1000) so läuft gar nichts mehr.
Löse ich die Aufgabe mit delays (was die Funktion ziemlich beeinträchtigt, da ich je nach Einstiegspunkt des Befehls bis zu 4 Sekunden warten muss bis der Externbefehl gegeben wird) so funktioniert die Anwendung.
///////////////////////////////////////////////////////////////
// Device und Konfiguration ///////////////////////////////////
///////////////////////////////////////////////////////////////
#include <12F683.H>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOFCMEN,NOIESO,NOPUT,NOBROWNOUT
#use delay(clock=8000000)
#use fast_io (a)
///////////////////////////////////////////////////////////////
// Variablendeklaration ///////////////////////////////////////
///////////////////////////////////////////////////////////////
int Merker1, Touch_Timer, Recalibration_Timer;
#bit MESSAGE_SENT = Merker1.0
///////////////////////////////////////////////////////////////
// E/A-Namen //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
#define FROM_QUANTUM PIN_A0 // Eingang Ansteuerung von QT310
#define KALIB PIN_A1 // Ausgang zur Kalibrierung
#define TO_SECURITOUCH PIN_A2 // Ausgang zum Hauptbedienteil
#define LED PIN_A4 // Ausgang LED-Anzeige
#define STATUS PIN_A5 // Eingang von Hauptbedienteil
///////////////////////////////////////////////////////////////
// Timer Subroutine ///////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Start Hauptprogramm ////////////////////////////////////////
///////////////////////////////////////////////////////////////
void main(void) { // Hauptprogramm
///////////////////////////////////////////////////////////////
// E/A-Definition /////////////////////////////////////////////
///////////////////////////////////////////////////////////////
SETUP_ADC_PORTS(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC);
set_tris_a(0b11101001);
///////////////////////////////////////////////////////////////
// Grundkonfiguration /////////////////////////////////////////
///////////////////////////////////////////////////////////////
Merker1=0;
Recalibration_Timer=0;
Touch_Timer=0;
output_low(LED);
output_low(TO_SECURITOUCH);
while (1){ // Hauptschleife
output_high(KALIB);
delay_ms(500);
output_low(LED);
delay_ms(500);
if ((input(FROM_QUANTUM)==0)&(MESSAGE_SENT==0)){
++Touch_Timer;
if (Touch_Timer>=3){
Touch_Timer=0;
output_high(TO_SECURITOUCH);
delay_ms(200);
output_low(TO_SECURITOUCH);
MESSAGE_SENT=1;
}
}
if (input(STATUS)==0){
output_high(LED);
}
if ((input(FROM_QUANTUM)==1)&(MESSAGE_SENT==1)){
MESSAGE_SENT=0;
}
if (input(FROM_QUANTUM)==1){
Touch_Timer=0;
}
++Recalibration_Timer;
if (Recalibration_Timer>=180){
output_low(KALIB);
delay_us(5);
output_high(KALIB);
delay_ms(20);
Recalibration_Timer=0;
}
} //endwhile
} //endmain
Danke für die Antworten
Gruss
Ronny