/************************************************************* * jl16-3.c - Demonstrate simple I/O functions of MC68HC908JL16 * and the use of an internal timer and interrupt * * This program will cause a 7-segment display to either count up in * hexadecimal (0,1,2,...,E,F,0,1,...) or count down in decimal * (9,8,...,1,0,9,8,..) depending on whether or not a switch is pressed. * * Port A, bit 1 - input from switch (0 = pressed, 1 = not pressed) * When the switch is not pressed, the 7-segment display counts * up in hexadecimal. When the switch is pressed, the 7-segment * display counts down in decimal. * Port B, bits 0-6 - Outputs to data inputs of 74LS374 register. * Bit 6 -> segment A, 5->B, ... , 1->F, 0->G * A low output bit will cause the LED segment to light up. * Port A, bit 5 - Output to positive edge-triggered clock input * of 74LS374 register. * * Revision History * Date Author Description * 01/03/05 M. Redekopp Initial Release * 10/07/05 A. Weber Modified for JL8 processor * 01/13/06 A. Weber Modified for CodeWarrior 5.0 * 08/25/06 A. Weber Modified for JL16 processor * 11/30/06 A. Weber Add struct for multiple bits * 05/21/07 A. Weber Some edits for clarity * 08/17/07 A. Weber Incorporated changes to demo board * 04/22/08 A. Weber Added "one" variable to make warning go away * 04/25/08 A. Weber Adjusted timing delay for new clock rate * 07/09/12 A. Weber Removed code to set security bytes * 05/29/13 A. Weber Renamed CWJL-3.c to jl16-3.c *************************************************************/ #include /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ /* Define PTB0 through PTB6 as "Segments", and bit PTA5 as "RegClock" */ volatile struct { byte Segments:7; /* PTB0-6 = Segments */ byte :1; /* PTB7 = unassigned */ } MyPTB @0x0001; #define Segments MyPTB.Segments volatile struct { byte :5; /* PTA0-4 = unassigned */ byte RegClock:1; /* PTA5 = RegClock */ } MyPTA @0x0000; #define RegClock MyPTA.RegClock /* Store the 7-segment display codes in ROM to save on RAM space */ const unsigned char digit_segs[16] = { 0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70, 0x7f,0x73,0x77,0x1f,0x4e,0x3d,0x4f,0x47 }; unsigned char cnt; void display_digit(int digit); // prototype void main(void) { unsigned char one = 1; EnableInterrupts; /* enable interrupts */ /* include your code here */ CONFIG1_COPD = 1; // disable COP reset PTAPUE_PTAPUE1 = 1; // Enable pull-up for switch on PTA1 DDRA = 0x20; // Set PTA bit 5 for output DDRB = 0x7f; // Set PTB bits 0-6 for output /* The demo board has a 9.8304 MHz clock which makes the processor run at 2.4576 MHz. We want the timer to interrupt every half second (2 Hz) so we need to count clocks to 2.4576MHz/2Hz = 1,228,800. This is too big for the 16 bit counter register so use the prescaler to divide the clock by 32 and then count that clock to 38,400 (0x9600). */ T1SC_PS = 5; // set prescalar for divide by 32 T1SC_TOIE = 1; // enable timer interrupt T1MOD = 38400; // store modulo value in T1MODH:T1MODL T1SC_TSTOP = 0; // start timer running display_digit(cnt); while(one) { // Loop forever asm { WAIT ; Make the processor go into a wait state ; until the timer interrupt occurs } } /* please make sure that you never leave this function */ } void display_digit(int digit) { Segments = digit_segs[digit] ^ 0x7f; // invert the bits (active low outputs) RegClock = 1; // toggle the clock bit to 1 RegClock = 0; // toggle the clock bit to 0 } /* The ISR for timer 1 */ #pragma TRAP_PROC void timerISR(void) { unsigned char up; T1SC_TOF = 0; // must read T1SC and then write a zero in bit 7 up = PTA_PTA1; if (up) { // if button is not pressed, up = 1 if (++cnt > 15) // and we count up in hex cnt = 0; } else { // if button is pressed, up = 0 if (--cnt < 0 || cnt > 9) // and we count down in decimal cnt = 9; } display_digit(cnt); }