Themabewertung:
  • 1 Bewertung(en) - 5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Ampelsteuerung mit PIC18F45K20
#1
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

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
{
 {
010010010},      //Ampelphase 0
 
{000000010},      //Ampelphase 1
 
{001001010},      //Ampelphase 2
 
{011001010},      //Ampelphase 3
 
{100001010},      //Ampelphase 4
 
{010011010},      //Ampelphase 5
 
{001100101},      //Ampelphase 6
 
{001100100},      //Ampelphase 7
 
{011010010},      //Ampelphase 8
 
   {001100010      //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 *inportint pin)
{
 
   static int edgedetectkeystatkeyread;
 
   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 =0phase =0Anforderung =0Regelbetrieb =0;
 
   
    while
(1)
 
     
        if 
(AnforderungLATC |= (1<<1);    // "Signal kommt" schalten
 
       else LATC &= ~(1<<1); 
 
       
        if 
(Regelbetrieb                  // Bei Regelbetrieb Taster abfragen
 
       {
 
       if (getkey(&SwitchportSwitch_Pin)) 
 
       {
 
           Anforderung =1;
 
       }
 
   }
 
       switch (phase                     //Ampelphasen schalten
 
       {
 
       case 0:
 
           PhaseSchalten(ampelphasentabelle[0]);          
            if 
(timestamp ==0timestamp =millis;
 
           if (millis >(timestamp +1000))
 
           {
 
               PhaseSchalten(ampelphasentabelle[1]);
 
               phase =1;
 
               timestamp =0;
 
            
            break
;
 
       case 1:
 
           if (timestamp ==0timestamp =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 ==0timestamp =millis;
 
           if (millis >(timestamp +10000))
 
           {
 
               PhaseSchalten(ampelphasentabelle[3]);
 
               phase =3;
 
               timestamp =0;
 
               Regelbetrieb =1;
 
           }
 
           break;
 
       case 3 
            if 
(timestamp ==0timestamp =millis;
 
           if (millis >(timestamp +(gelbphase *1000)))
 
           {
 
               PhaseSchalten(ampelphasentabelle[4]);
 
               phase =4;
 
               timestamp =0;
 
           }
 
           break;
 
       case 4   
            if 
(timestamp ==0timestamp =millis;
 
           if (millis >(timestamp +(gruephase_1 *1000)))
 
           {
 
               PhaseSchalten(ampelphasentabelle[5]);
 
               phase =5;
 
               timestamp =0;
 
           }
 
           break;
 
       case 5:
 
           if (timestamp ==0timestamp =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 ==0timestamp =millis;
 
           if (millis >(timestamp +1000))
 
           {
 
               PhaseSchalten(ampelphasentabelle[7]);
 
               phase =7;
 
               timestamp =0;
 
           }
 
           break;
 
       case 7:
 
           if (timestamp ==0timestamp =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 ==0timestamp =millis;
 
           if (millis >(timestamp +(gelbphase *1000)))
 
           {
 
               PhaseSchalten(ampelphasentabelle[4]);
 
               phase =4;
 
               timestamp =0;
 
           }
 
           break;
 
       case 9:
 
           if (timestamp ==0timestamp =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_prioritylowPrio (void)
{
 
   if (INTCONbits.TMR0IF
 
   {
 
       INTCONbits.TMR0IF =0;
 
       millis ++ ;
 
       TMR0H 0           //Timer0 preload        
 
       TMR0L 6;
 
   }
 
   return;

Zitieren


Gehe zu: