02.02.2020, 20:43
Hallo Forum,
ich konnte einen gebrauchten PICkit3 mit 44-Pin Demo Board (PIC18F45K20) erwerben
und habe mal eine "PIC-Version" der Ampelsteuerung aus Berhard's Lektion 3 gebastelt.
Holger
ich konnte einen gebrauchten PICkit3 mit 44-Pin Demo Board (PIC18F45K20) erwerben
und habe mal eine "PIC-Version" der Ampelsteuerung aus Berhard's Lektion 3 gebastelt.
Holger
PHP-Code:
/*
* File: Ampelsteuerung.c
* Author: Holger
*
* Traget: PIC18F45K20
*
* Created on 1. Februar 2020
*/
//Pin RD0 Ampelgruppe_1_gruen
//Pin RD1 Ampelgruppe_1_gelb
//Pin RD2 Ampelgruppe_1_rot
//Pin RD3 Ampelgruppe_2_gruen
//Pin RD4 Ampelgruppe_2_gelb
//Pin RD5 Ampelgruppe_2_rot
//Pin RD6 Ampel_Fussgaenger_gruen
//Pin RD7 Ampel_Fussgaenger_rot
//Pin RC0 Ampel_Fussgaenger_Warnung
//Pin RC1 "Signal kommt" Anzeige
/** C O N F I G U R A T I O N B I T S ******************************/
#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30 // CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768 // CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // CONFIG5L
#pragma config CPB = OFF, CPD = OFF // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // CONFIG7L
#pragma config EBTRB = OFF // CONFIG7H
/** I N C L U D E S **************************************************/
#include <xc.h>
//#define _XTAL_FREQ 1000000 // Quarzfrequenz 1 MHz
#define debouncetime 10 // Entprellzeit(ms)
#define gruephase_1 20 //Grünphase Ampelgruppe_1 in Sekunden
#define gruephase_2 20 //Grünphase Ampelgruppe_2 in Sekunden
#define gelbphase 2 //Gelbphase in Sekunden
#define Switchport PORTB
#define Switch_Pin 0
#define DetectsInARow 5
/** V A R I A B L E S *************************************************/
volatile unsigned long millis =0;
char ampelphasentabelle[10][9]= //Ampelphasentabelle
{
{0, 1, 0, 0, 1, 0, 0, 1, 0}, //Ampelphase 0
{0, 0, 0, 0, 0, 0, 0, 1, 0}, //Ampelphase 1
{0, 0, 1, 0, 0, 1, 0, 1, 0}, //Ampelphase 2
{0, 1, 1, 0, 0, 1, 0, 1, 0}, //Ampelphase 3
{1, 0, 0, 0, 0, 1, 0, 1, 0}, //Ampelphase 4
{0, 1, 0, 0, 1, 1, 0, 1, 0}, //Ampelphase 5
{0, 0, 1, 1, 0, 0, 1, 0, 1}, //Ampelphase 6
{0, 0, 1, 1, 0, 0, 1, 0, 0}, //Ampelphase 7
{0, 1, 1, 0, 1, 0, 0, 1, 0}, //Ampelphase 8
{0, 0, 1, 1, 0, 0, 0, 1, 0} //Ampelphase 9
};
//Ampelphase an Latch ausgeben
void PhaseSchalten(char ampelphasentabelle[])
{
for(int i=0;i<8;i++)
{
if (ampelphasentabelle[i]) LATD |=(1<<i);
else LATD &= ~(1<<i);
}
if (ampelphasentabelle[8]) LATC |=(1<<0);
else LATC &= ~(1<<0);
}
//Tatenstatus abfragen
int getkey (volatile unsigned char *inport, int pin)
{
static int edgedetect, keystat, keyread;
static unsigned long debouncetimestamp;
keystat =keyread;
keyread = (*inport &(1<<pin));
if (!keyread &&keystat)
{
edgedetect =1;
debouncetimestamp =millis;
}
if (edgedetect &&(millis >(debouncetimestamp +debouncetime)))
{
edgedetect =0;
return 1;
}
return 0;
}
void main(void)
{
//Takt
//OSCCON = 0x70; // 16MHz
//OSCCON = 0x50; // 4MHz
OSCCON = 0x30; // 1MHz
OSCTUNEbits.PLLEN = 0; // x4 PLL disabled
//Interrupt Initialisierung
RCONbits.IPEN = 1; // Enable priority levels on interrupts
INTCONbits.PEIE = 1; // Low priority interrupts allowed
INTCONbits.GIE = 1; // High priority interrupts allowed
INTCONbits.TMR0IF = 0; // clear roll-over interrupt flag
INTCON2bits.TMR0IP = 0; // Timer0 is low priority interrupt
INTCONbits.TMR0IE = 1; // enable the Timer0 interrupt.
//Timer0 Initialisierung (1ms@Fosc1MHz)
T0CONbits.TMR0ON =0; // Timer0 On/Off Control bit
T0CONbits.T08BIT =1; // Timer0 8-bit/16-bit Control bit
T0CONbits.T0CS =0; // Timer0 Clock Source Select bit
T0CONbits.T0SE =0; // Timer0 Source Edge Select bit
T0CONbits.PSA =1; // Timer0 Prescaler Assignment bit
T0CONbits.T0PS0 =0; // Timer0 Prescaler Select bit0
T0CONbits.T0PS1 =0; // Timer0 Prescaler Select bit1
T0CONbits.T0PS2 =0; // Timer0 Prescaler Select bit2
TMR0H = 0; // clear timer - always write upper byte first
TMR0L = 0;
T0CONbits.TMR0ON = 1; // start timer
//Port Initialisierung
ANSELH =0x00; // AN8-12 are digital inputs (AN12 on RB0)
TRISD =0x00; // PORTD bits 7:0 are outputs
TRISC =0x0C; // PORTC bits 1:0 are outputs
INTCON2bits.RBPU = 0; // enable PORTB internal pullups
WPUBbits.WPUB0 = 1; // enable pull up on RB0
TRISBbits.TRISB0 = 1; // PORTB bit 0 is input (Switch))
unsigned long timestamp =millis;
char count =0, phase =0, Anforderung =0, Regelbetrieb =0;
while(1)
{
if (Anforderung) LATC |= (1<<1); // "Signal kommt" schalten
else LATC &= ~(1<<1);
if (Regelbetrieb) // Bei Regelbetrieb Taster abfragen
{
if (getkey(&Switchport, Switch_Pin))
{
Anforderung =1;
}
}
switch (phase) //Ampelphasen schalten
{
case 0:
PhaseSchalten(ampelphasentabelle[0]);
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +1000))
{
PhaseSchalten(ampelphasentabelle[1]);
phase =1;
timestamp =0;
}
break;
case 1:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +1000))
{
timestamp =0;
if (count >4)
{
PhaseSchalten(ampelphasentabelle[2]);
phase =2;
count =0;
}
else
{
PhaseSchalten(ampelphasentabelle[0]);
phase =0;
count ++;
}
}
break;
case 2:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +10000))
{
PhaseSchalten(ampelphasentabelle[3]);
phase =3;
timestamp =0;
Regelbetrieb =1;
}
break;
case 3:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +(gelbphase *1000)))
{
PhaseSchalten(ampelphasentabelle[4]);
phase =4;
timestamp =0;
}
break;
case 4:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +(gruephase_1 *1000)))
{
PhaseSchalten(ampelphasentabelle[5]);
phase =5;
timestamp =0;
}
break;
case 5:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +(gelbphase *1000)))
{
if (Anforderung)
{
PhaseSchalten(ampelphasentabelle[6]);
phase =6;
Anforderung =0;
}
else
{
PhaseSchalten(ampelphasentabelle[9]);
phase =9;
}
timestamp =0;
}
break;
case 6:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +1000))
{
PhaseSchalten(ampelphasentabelle[7]);
phase =7;
timestamp =0;
}
break;
case 7:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +1000))
{
timestamp =0;
if (count >10)
{
PhaseSchalten(ampelphasentabelle[8]);
phase =8;
count =0;
}
else
{
PhaseSchalten(ampelphasentabelle[6]);
phase =6;
count ++;
}
}
break;
case 8:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +(gelbphase *1000)))
{
PhaseSchalten(ampelphasentabelle[4]);
phase =4;
timestamp =0;
}
break;
case 9:
if (timestamp ==0) timestamp =millis;
if (millis >(timestamp +(gruephase_1 *1000)))
{
PhaseSchalten(ampelphasentabelle[8]);
phase =8;
timestamp =0;
}
break;
}
}
return;
}
/*
void __interrupt() highPrio (void)
{
if (INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF =0;
}
return;
}
*/
// millis hochzählen
void __interrupt(low_priority) lowPrio (void)
{
if (INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF =0;
millis ++ ;
TMR0H = 0; //Timer0 preload
TMR0L = 6;
}
return;
}