//////////////////////////////////////////////////////////////////////
//
// File: 16F88-binary-clock.c
//
// Author: J F Main.
//
// Description:
//
// Driving an led dot matrix as a binary clock
//
// Compiler : mikroC, mikroElektronika C compiler
// for Microchip PIC microcontrollers.
//
// Note Testing:
//
// Tested on 16F88
//
// Requirements:
//
// Clock : 4MHz (Internal) - For accurate clock use External Xtal.
//
// Target : 16F88
//
// Version:
// 1.00 - Initial release.
// 1.01 - Compiler update 6.4.0, add display rotate, flip, SPEEDUP debug.
//
// Copyright : Copyright � John Main
// http://www.best-microcontroller-projects.com
// Free for non commercial use as long as this entire copyright notice
// is included in source code and any other documentation.
//
//////////////////////////////////////////////////////////////////////
#include "types.h"
#include "bit.h"
//////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////
// Un-comment the following to enable code .
//
// #define debug
//
// #define ROT180 1 // When you wire it wrong set this as required
// #define FLIPLR 1 // left right bit swap
// #define SPEEDUP 1 // See what happens faster.
// Control definitions.
#define ROW_RESET setBit(PORTA,4) ; resBit(PORTA,4)
#define NEXT_ROW_STROBE setBit(PORTA,2) ; resBit(PORTA,2)
//////////////////////////////////////////////////////////////////////
// file scope variables
static U16 time=0; // count milliseconds
#ifndef debug
static U8 hours=18;
static U8 minutes=53;
static U8 seconds=47;
#else
static U8 hours=23; // Test time overflow.
static U8 minutes=59;
static U8 seconds=47;
#endif
//////////////////////////////////////////////////////////////////////
void init(void) {
OSCCON = 0x60; // b6..4 = 110 = 4MHz, 111 = 8MHz
ANSEL = 0; // all ADC pins to digital I/O
// Mainly Timer 0
// GPPU b7 = 1 : Pullups disabled.
// INTEDG b6 = 0 : Interrupt edge = low to high.
// T0CS b5 = 0 : Clock select Internal Fosc/4.
// T0SE b4 = 0 : Timer 0 edge low to high.
// PSA b3 = 0 : Prescaler assigned to WDT (1) (Timer0 (0).
// PS b2..0 = 010 : Prescale=1:8 (note PS=0-> 1:2 for TMR0).
OPTION_REG = 0x02 | (1<<7);
}
//////////////////////////////////////////////////////////////////////
void init_ports(void) {
PORTA = 0;
TRISA = 0; // 0=o/p.
PORTB = 0;
TRISB = 0; // 0=o/p.
}
//////////////////////////////////////////////////////////////////////
void enable_interrupts(void) {
// Timer 0
// Osc off, Internal clk, On,zero T0IF
INTCON = (1<<TMR0IE);
// Global & Peripheral interrupt enable.
INTCON |= (1<<GIE) | (1<<PEIE);
}
//////////////////////////////////////////////////////////////////////
void disable_interrupts(void) {
INTCON &= ~(1<<GIE); // disable interrupts
}
//////////////////////////////////////////////////////////////////////
void add_a_second(void) {
if (++seconds==60) {
minutes++;
seconds=0;
}
if (minutes==60) {
hours++;
minutes=0;
}
if (hours==24) {
hours=0;
minutes=0;
seconds=0;
}
}
////////////////////////////////////////////////////////////////////////
// Start here
//
void main() {
U8 i,chr,dmy,tmp = 0; // General purpose.
U8 mskl,mskr = 0; // Masks.
U16 num; // General purpose number var.
U8 row = 0; // Current display row.
U16 blinkc = 0; // LED blinker counter.
U16 blink_onoff = 1; // LED state.
U8 bcd_h,bcd_m,bcd_s; // BCD numbers.
init_ports();
init();
enable_interrupts();
ROW_RESET;
/////////////////////////////
//
for (;;) { // infinite loop
// FLASH LED @ RA3
if (++blinkc>500) { // time to change state ?
blinkc=0;
if (blink_onoff = !blink_onoff) setBit(PORTA,3); else resBit(PORTA,3);
} // end blink
// Output row data each row after the other for 8 rows then repeats.
tmp = row;
#ifdef ROT180
tmp = 7-row; // FLIP 180 degrees
#endif
switch(tmp) {
case 0 : chr = (bcd_h & 0xf0)>>4; break;
case 1 : chr = (bcd_h & 0x0f) ; break;
case 2 : chr = (bcd_m & 0xf0)>>4; break;
case 3 : chr = (bcd_m & 0x0f) ; break;
case 4 : chr = (bcd_s & 0xf0)>>4; break;
case 5 : chr = (bcd_s & 0x0f) ; break;
default : chr = 0;
}
#ifdef FLIPLR // Swap b7,b0..b6,b1 etc.
dmy = 0;
mskl = 0x80;
mskr = 0x01;
for (i=0;i<8;i++) {
if (chr & mskl) dmy|=mskr;
mskl>>=1; mskr<<=1;
}
chr=dmy;
#endif
PORTB = chr;
bcd_h = Dec2Bcd(hours);
bcd_m = Dec2Bcd(minutes);
bcd_s = Dec2Bcd(seconds);
PORTB=0x00;
row++; // Done here as want top row to be value 0.
if (row==8) ROW_RESET; // Start at reset pos
row %=8; // Keep to 8 rows.
NEXT_ROW_STROBE; // Move next row, 1st - reset position.
} // Infinite loop.
}
////////////////////////////////////////////////////////////////////////
void interrupt(void) {
// Timer 0
if (INTCON & (1<<TMR0IF) ) { // T0 overflowed ?
INTCON &= ~(1<<TMR0IF); // clear timer0 overflow bit.
// Fosc/4 x (Prescale1:8) x (count to overflow) = repeat rate.
// 1us x 8 x 125 = 1ms repeat rate.
TMR0 = 256-125+2; // need 125 but TMR0 looses 2
time++; // Count 1ms periods for general use.
#ifndef SPEEDUP
if (time==1000) {
add_a_second();
time=0;
}
#else
if (time==10) {
add_a_second();
time=0;
}
#endif
}
INTCON |= (1<<TMR0IE); // Enable Timer 0.
// Note GIE set by RETFIE instruction (see assembler output).
}
binary-clock-1-01.zip_Good Luck_LCD_xp Binary Clock
版权申诉
127 浏览量
2022-09-20
09:26:37
上传
评论
收藏 14KB ZIP 举报
JonSco
- 粉丝: 70
- 资源: 1万+