|OI am a complete newbie to PIC18's but I am determined to learn all about it. Naturally, my first project would be a simple one to test basic operation, so I wrote the very short code below..but it doesn't quite work.
Does anyone see a problem with my code? I can't seem to find out what is wrong or missing!
I see that TMRx timers are quite complex to setup, perhaps I should have started out with TMR0..there are about a dozen settings to set and possibly set wrong with the 16-bit timers.
//----------------------------------------------
/* Test for PIC18F25K22 2015Jun16
NOTE: Compiled with Hi-Tech P18 PRO 9.80
My First PIC18F25K22 Program:
Should slowly blinks a LED on cbit3 ..it does, no IRQ, used for a blink, just For-Next loop timed.
A test to use low and high priority interrupts. cbit2 lights just for 50uSec when INT0 is triggered!
A test code using INT0 falling edge IRQ to light a LED
A test using the TMR1 overflow interrupt to blink LED on cbit2
I see with my scope about a .1 uSec glitch (lo-->hi-->lo)on cbit3 8uSec before cbit3 0-->1 but cbit3 then keeps LED lit for about a second correctly. This is strange, unexpected and evil, seems like something is clearing PORTC.
It should much faster blink a LED on cbit2 using low priority interrupt and TMR1, it doesn't!
It looks like TMR1 is not running? Why?
So far: cbit3 LED blinks almost perfectly
Alas, cbit2 LED does not respond to IRQ or TMR1 overflow and does not blink.
If I give INT0IF its own private I/O pin and its own LED to light in the high-priority interrupt, the INT0IF interrupt works perfectly.
*/
#include <htc.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <P18f25k22.h>
/*
#pragma config FOSC=0x88; //resets PRICLKEN bit5 of CONFIG1H
#pragma config PRICLKEN=0; //Primary Clock is disabled using Internal clk
#pragma config FOSC=0x5; //Coofig1H Default 0x2500 0001=0x25
#pragma config BORV=0; //Config2L Vdd level for BOREN to reset at
#pragma config BOREN=0; //BOREN Disabled
#pragma config PWRTEN=1; // 0002=0x1F
#pragma config WDTPS=0; //Ratio of Number of Clocks/WDTimerTic
#pragma config WDTEN=0; //WatchDog Enable Disabled 0003=0x3F ater erase
#pragma config MCLRE=1; //Pin 1 is *MCLR reset, not I/O pin
#pragma config PBADEN=0; //PORTB<0:5>are I/O pins not A2d inputs after reset
#pragma config T3CMX=1; //HFINTOSC is not delayed at startup
#pragma config CCP2MX=1; //CCP2 in/out is Mtplxd with RC2
#pragma config DEBUG=1; //Background Debugger is disabled
#pragma config XINST=0; //Extended instruction set DISABLED
#pragma config LVP=0; //LV programming disabled
#pragma config STVREN=1; //Reset on Stack Overflow or Underflow Enabled
Note: above just here for later use in my code instead of Magic Numbers
*/
//IES0 Allows internal/external clock swithover in OSCCON but is not used in program
//CONFIG1 System Clock
//Bit 7 6 5 4 <3:0>
// IESO FCMEM PRICLKEN PLLCFG OSC SELECT
// Int-Ext FailSafe no effect 0010 Xtal
// ClkSwEn Clock Mon HFINTOSC 1000 INTHFOSC
// 1=En 0=off 0=off x 0x1000
//OSCCON SCS=0 else no 64MHz PLL operation
//In this program 64MHz PLL is disabled, only 16MHz INTOSCBlock until things are looking better
__PROG_CONFIG(1,0x8800); //Internal Osc Block at 16MHz
__PROG_CONFIG(2,0x0); //BOREN and WDTEN both disabled
__PROG_CONFIG(3,0xBD00); //PBADEN disabled PORTB<5:0>are I/O, not A2d at reset
__PROG_CONFIG(4,0x85);
__PROG_CONFIG(5,0xC00F); //CONFIG4 to CONFIG7 set Read and Write protects, not used
__PROG_CONFIG(6,0xE00F); //All mem reads and writes are enabled, no protect
__PROG_CONFIG(7,0x400F); / /Default BulkErase settings for CONFIG4--CONFIG7
#pragma config IESO=1; //Needs to be=1 for SCS to work to set clk source
#pragma config PBADEN=0;
#pragma config WDTEN=0; //WatchDog Enable and BOREN Disabled, was 0x3F ater bulkerase
#define Off 0
#define OFF 0
#define off 0
#define On 1
#define ON 1
#define on 1
#define None 0
//Breaks the ports down into their bits
#define PB(port,bit) ((unsigned) & (port)*8 + (bit))
static bit abit0 @ PB(PORTA,0);
static bit abit1 @ PB(PORTA,1);
static bit abit2 @ PB(PORTA,2);
static bit abit3 @ PB(PORTA,3);
static bit abit4 @ PB(PORTA,4);
static bit abit5 @ PB(PORTA,5);
static bit abit6 @ PB(PORTA,6);
static bit abit7 @ PB(PORTA,7);
static bit bbit0 @ PB(PORTB,0);
static bit bbit1 @ PB(PORTB,1);
static bit bbit2 @ PB(PORTB,2);
static bit bbit3 @ PB(PORTB,3);
static bit bbit4 @ PB(PORTB,4);
static bit bbit5 @ PB(PORTB,5);
static bit bbit6 @ PB(PORTB,6);
static bit bbit7 @ PB(PORTB,7);
static bit cbit0 @ PB(PORTC,0);
static bit cbit1 @ PB(PORTC,1);
static bit cbit2 @ PB(PORTC,2);
static bit cbit3 @ PB(PORTC,3);
static bit cbit4 @ PB(PORTC,4);
static bit cbit5 @ PB(PORTC,5);
static bit cbit6 @ PB(PORTC,6);
static bit cbit7 @ PB(PORTC,7);
static double ttemp=0; //one and only var used for brute force timing in main()
void interrupt high_priority(void)
{
if (INT0IF)
{ INT0IF = 0;
cbit2=1;
}
if (TMR1IF)
{
TMR1ON = 0;
TMR1IF = 0;
TMR1H = 0x80;
TMR1L = 0x0;
TMR1ON = 1;
if(cbit2==0)
{ cbit2=1;
}
else cbit2=0;
}
}//End of High-Priority ISR
void interrupt low_priority lp(void)
{
if(INT0IF)
{ INT0IF=0;
cbit2=1;
}
if (TMR1IF)
{
TMR1ON = 0;
TMR1IF = 0;
TMR1H = 0x80;
TMR1L = 0x0;
TMR1ON = 1;
if(cbit2==0)
{ cbit2=1;
}
else cbit2=0;
}
}// end of Low priority interrupt
//____________________________ MAIN ___________________________________
void main(void)
{
OSCCON=0x70; //Selects Int Osc Block Clk as internal clock source
OSCTUNE=0x1F; //Highest Internal OSC Freq =16 MHz with OSCTUNE<0:5> sets freq abd PLLEN=bit6 sets turbo mode
//OSCTUNE<6:0>set freq 011111 =16MHz and turboed by PLL
PLLEN=1; //Enables PLL Fosc=Fosc*4 up to 64MHz with Internal 16MHz osc.
//PLLRDY //Status Bit 1=PLL ON
PORTB = 1; //Note: if a PORTA,B,C set to I/O, bit state of PORT is random
PORTA = 0; //unless set by these instructions
PORTC = 0;
INTEDG0=0; //interrupt on falling edge
TRISB = 0x1; //INTO pin set for digital input
TRISA = 0x0;
TRISC = 0x0; //all outputs on PORTC
T1GPOL=0; //TMR1 Gate Settings
T1G=0;
T1GTM=0; //Gate Toggle Mode turned off
T1GSPM=0; //Gate Single-Pulse mode disabled Not sure any TMR1 Gate Control stuff is needed, turned off
T1GCON=(T1GCON & 0x9); //T1GSS=Timer1 Gate pin
T1OSCEN=1; //Enable TMR1 Clocking
TMR1GE=1;
TMR1H = 0x0; //If this TMR1 is timing out, the scope must show it.
TMR1L = 0x0;
T1CON = 0b01001000; //Enables system clock as clock source for TMR1
//T1CKPS=00 1:1 prescaler of clock
TMR1IP = 0; //Low Priority interrupt enabled for TMR1.
TMR1ON = 1;
TMR1IF = 0;
TMR1IE = 1; //Enable TMR1 interrupt
INT0IE = 1; //Enable INT0 interrupt, it is always high priority
INT0IF = 0; //Not here reset?, probably needs to be reset in ISR
IPEN = 1; //High and Low interrupts enabled
PEIE=1; //turn on any possibly needed interrupt enables
PIE1=1;
PIE2=1;
GIEL=1;
GIEH=1; //Start the ball rolling (although is seems to shaped more like a brick)
//Progress, cbit3 LED always kinda blinks at about 1 second interval on/off
//Failure:
// ****** NOTE: cbit2 LED does not blink! ******** and even cbit2 doesn't stay lit with INT0 trigger
//----------------------------------------------------------------------
Start:
for(ttemp=0;ttemp<60000;ttemp++)//approx 1-second timed loop at 16MHz x 4
{ //cbit3 stays ON, as expected
cbit3=1; //There is a a 1K resistor connected to a LED to Vss
/ /cbit3 blinks, cbit2 should and doesn't, won't even stay lit for more than 50uSecs or so
if(TMR1IE==0) //NOTE: there is a 1K to +5 pullup on bbit0 INTIO0 bbit1
{ TMR1ON=0; // There is a LED connected to Vss with a 1k
cbit2=1; // resistor to cbit2 pin.
TMR1H = 0x0;
TMR1L = 0x0;
TMR1IF = 0; //Something's wrong: No cbit2 blink!
TMR1IE = 1;
TMR1ON = 1; //Start the timer to blink the cbit2 LED
}
INT0IE=0; //First it is TMR1's job to blink the LED
INT0IF=0;
}
for(ttemp=0;ttemp<60000;ttemp++) //Takes about a second at 16MHz x 4
{
if(TMR1IE==1) //If I ground bbit0 the cbit2 LED should light steady
{ TMR1IE=0; //N.O. Momentary switch connected from bbit0 to Vss
cbit2=0; //cbit2 stays off, something is wrong!
TMR1ON=0; //No blinking by TMR1, with only INT0 at work
TMR1IF=0; //TMR1 is turned off during this ttemp timed loop
}
cbit3=0; //cbit3 turns off and stays o as expected
TMR1IE = 0; //TMR1 is turned off, only bbit0 INT0 working
INT0IE = 1;
}
goto Start;
}
//======================== END of MAIN ==================================