/* 877_15seg_2disp.c.c * * Copyright (c) 2002, 2003 Bruce Kroeze * * 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 2 * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * --------------------------------- * * Displays characters on a pair of 15 seg led module * * Revisions: * 22 Dec 2002 - Initial Version * 25 Dec 2002 - Added ring buffer * * Hardware: * 16F877 at 20Mhz * PCF8574P I2C IO Expander (IO1) * PCF8574P I2C IO Expander (IO2) * 2 LTP588G displays connected on a bus with: * IO1 P0-P8: ABCDEFGH * IO2 P0-P7: IJKLMNO * * V+ for the displays wired through a 2907A transistor: * LED0: RB7 * LED1: RB6 */ #include "defs_877.h" #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(CLOCK=20000000) #use fast_io(b) #include "15seg.h" #use rs232(baud=9600, PARITY=N, BITS=8, xmit=PIN_C7, rcv=PIN_C6) #use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW) int8 displayIx = 1; char display_chars[] = {'\0', '\0'}; #define MAX_RING_SIZE 2 #include "ring_buffer.c" #define clear15 ring_clear #DEFINE IO1 0b01000000 #DEFINE IO2 0b01000010 int8 clock=100; void write_i2c_byte(int8 addr, int8 data) { i2c_start(); i2c_write(addr); i2c_write(data); i2c_stop(); } void display_segs(int16 ch) { write_i2c_byte(IO1, ch ^ 0xFF); write_i2c_byte(IO2, (ch >> 8) ^ 0xFF); } inline void print_ch(char ch) { display_segs(get_15seg(ch)); } void display_current() { if (displayIx == 0) { print_ch(display_chars[0]); PORTB = 0b01111111; displayIx = 1; } else { print_ch(display_chars[1]); PORTB = 0b10111111; displayIx = 0; } } void print15(char ch) { ring_append(ch); display_chars[0] = ring_peek(0); display_chars[1] = ring_peek(1); if (display_chars[1] != 0) inc_ring_read_ix(); printf("%c%c\n\r", display_chars[0],display_chars[1]); } #int_rtcc void rtc_handler() { // hits at 5Khz == 200 uSec // dividing by 50 gives us 100hz --clock; if (clock == 0) { display_current(); clock = 50; } enable_interrupts(INT_RTCC); } void main() { char curr; setup_psp(PSP_DISABLED); setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4); TRISB = 0; // all output PORTB = 0xFF; clear15(); printf("Ready to display 2.\n\r"); getch(); enable_interrupts(INT_RTCC); enable_interrupts(GLOBAL); while (1) { curr = getch(); printf("%c = %X\n\r", curr, curr); print15(curr); } }