PIC18F1823 Programkod (skapad i mplabx)


Source code

/*
Copyright (C) 2014  Johan Svensson

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

emailadress: johan@exclude.se
*/

/*
* File:   w2indicator.c
* Author: johan
* Version: 0.9-RC1
* Created on April 19, 2014, 10:57 PM
*/

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = ON        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

#define _XTAL_FREQ 31000

#include <stdio.h>
#include <stdlib.h>
#include <pic16f1823.h>
#include <xc.h>

/*ENDAST FÖR INSTRUKTIONER, ANVÄNDS EJ
KNAPP ANVÄNDS!!!!!
Detta för att jag fick märkliga resultat.
*/

#define KNAPP RA2 //knapp för allt
#define W1 RC0
#define W2 RC1
#define W3 RC2
#define W4 RC3
#define W5 RC4
#define W6 RC5
#define W7 //ingen plats!
#define LED_WARN RA4
#define LED_CRIT RA5

/*GLOBAL VARIABLES*/
#define delay_sec 2
int weekday = 1;  //denna ska läsas in från ROM senare
int w_delay = 1; //en räknare som räknar ned från delay_sec
short long w_count = 0; //denna räknar upp till weekday (1 = 86400 (24h))
int i = 0;
int sleep_mode = 1;
int overdue = 0;
/*END GLOBAL VARIABLES*/

/*Deklarera samtliga funktioner som används*/
void init();
void lightLED(int weekday);
void darkenLED();
void blink();
/*avslut*/

void interrupt avbrott(){
//om knappen trycks in
if(INTF){
__delay_us(10); //for debouncing
//kolla om select knappen blev intryckt
if(w_delay > 0){
weekday++;
}
if(sleep_mode == 1){blink();}
//om weekday är större än 7, resetta den
if(weekday > 7){weekday=1;}
//starta en timer och räkna ned 3 sek. hmm?

lightLED(weekday); //tänd LED
while(KNAPP == 1){;} //vänta tills att knappen släpps
w_delay = delay_sec; //öka räknaren
__delay_ms(100);
w_count = 0;
darkenLED();
INTF = 0; //NOLLSTÄLL INTERRUPT
sleep_mode = 0;
overdue=0;
}
}

void main() {
init();
while(1){
asm(“clrwdt”);

if(w_delay > -1){
w_delay–; //minska w_delay
}
if(w_delay == 0){
sleep_mode = 1;
w_count = 3; //börja räkna efter 3 sek
//här kan man välja att spara till EEPROM om man vill
}

//VARNA
if((weekday*86400 – w_count) >= 3 && (weekday*86400 – w_count) < 28800 ){
//WARNING
RA5 = 0;
RA4 = 1;
__delay_ms(1000);
RA5 = 0;
RA4 = 0;

}else if((weekday*86400 – w_count) < 3) {
//OVERDUE!
overdue=1;
RA5 = 0;
RA4 = 0;
__delay_ms(1000);
RA5 = 1;
RA4 = 0;
__delay_ms(1000);
RA5 = 0;
RA4 = 0;
__delay_ms(1000);
RA5 = 1;
RA4 = 0;
}
//om enheten ska gå i viloläge
//om inte, resetta WDT
if(sleep_mode == 1){
asm(“sleep”);
asm(“nop”);
if(overdue == 0){
w_count = w_count + 128;
}
}else{
asm(“clrwdt”);
__delay_ms(1000); //vänta 1 sek
}

}
}

void init(){
TRISC = 0x00;
TRISA = 0b00000100; //fixa knapp som ingång
OSCCON = 0b00000010; //set 31kHz
//WDTCON = 0b00100100; //set WDT to 256sec, kolla sista biten
WDTCON = 0b00100010; //set WDT to 128sec, kolla sista biten
INTE = 1;   //tillåt interrupt på RA2
INTF = 0;   //nollställ interrupt flaggan
ANSELA = 0b00011011;
GIE = 1;    //Global interrupt enable bit
//om man vill spara weekday till EEPROM
//fungerar ej i dagsläget
//weekday = EEPROM_READ(0x20);
}
/*sätt 0:or på porta och portc*/
void darkenLED(){
PORTA = 0x00;
PORTC = 0x00;
}
/*blinka*/
void blink(){
for(i=0;i < 3; i++){
lightLED(weekday);
PORTA = 0b00110000;
__delay_ms(100);
darkenLED();
__delay_ms(100);
}
}
/*
tänd rätt diod så att man kan representera
alla veckodagarna
*/
void lightLED(int weekday){
switch(weekday){
case 1:
PORTC = 0b00000001;
break;
case 2:
PORTC = 0b00000011;
break;
case 3:
PORTC = 0b00000111;
break;
case 4:
PORTC = 0b00001111;
break;
case 5:
PORTC = 0b00011111;
break;
case 6:
PORTC = 0b00111111;
break;
case 7:
PORTC = 0b00111111;
PORTA = 0b00000001; //LED 7
break;
}
}


Leave a Reply

Your email address will not be published. Required fields are marked *