// ***************************************************************************
// File Name : 16F886.c
// Version : 0.0
// Description : UP-DOWN 4 DIGIT
// Author : xxxxx
// Target : Microchip PIC16F886 Microcontroller
// Compiler : HI-TECH C Lite for the PIC10/12/16 MCU family V9.71a
// IDE : Microchip MPLAB IDE v8.56
// Programmer : xxxx
// Last Updated : xx xxx xxxx
// ***************************************************************************
#include <pic.h>
/* PIC Configuration Bit:
** INTIO - Using Internal RC No Clock
** WDTDIS - Wacthdog Timer Disable
** PWRTEN - Power Up Timer Enable
** MCLRDIS - MCLR functions as IO
** UNPROTECT - Code Un-Protect
** DUNPROTECT - Do not read protect EEPROM data
** BORDIS - Brown Out Detect Disable
** IESODIS - Internal External Switch Over Mode Disable
** FCMDIS - Monitor Clock Fail Safe Disable
** BORV21 - Brown Out Reset 2.1 Volt
*/
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLRDIS & UNPROTECT & DUNPROTECT & \\\\
BORDIS & IESOEN & FCMDIS & LVPDIS & DEBUGEN); // Address 0x2007
__CONFIG(BORV21); // Address 0x2008
__EEPROM_DATA(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07);
// Inital Write data to EEPROM
// Using Internal Clock of 8 MHz
#define FOSC 8000000L
// Variable Used for Thermometer
#define LDR_THRESHOLD 50
#define MAX_DCYCLE 255
#define KEY_O_DOWN 0b11111110
#define KEY_0_UP 0b11111101
#define KEY_1_DOWN 0b11111011
#define KEY_1_UP 0b11110111
#define KEY_2_DOWN 0b11101111
#define KEY_2_UP 0b11011111
#define KEY_3_DOWN 0b10111111
#define KEY_3_UP 0b01111111
int digit0_3[4];
unsigned char flag_update;
unsigned char read_key1,read_key2;
unsigned char DispDigit[4];
unsigned char DigitCount;
void _delay_ms(unsigned int ms);
void update_DIGIT(void);
void SSEG_putnum(void);
const char SSEG[] = {
//0b10111000, // ----
0b11000000, // 0, LED Segment: A,B,C,D,E,F
0b11111001, // 1, LED Segment: B,C
0b10100100, // 2, LED Segment: A,B,D,E,G
0b10110000, // 3, LED Segment: A,B,C,D,G
0b10011001, // 4, LED Segment: B,C,F,G
0b10010010, // 5, LED Segment: A,C,D,F,G
0b10000010, // 6, LED Segment: A,C,D,E,F,G
0b11111000, // 7, LED Segment: A,B,C
0b10000000, // 8, LED Segment: A,B,C,D,E,F,G
0b10010000, // 9, LED Segment: A,B,C,D,F,G
0b11000110, // C, LED Segment: A,D,E,F
0b10001110 // F, LED Segment: A,E,F,G
};
static void interrupt isr(void)
{
if(T0IF) { // TIMER0 Interrupt Flag
/* Pull Low the Segment */
PORTB = 0xFF;
PORTC = ~DispDigit[DigitCount];
/* Activate the Digit and Advanced to next Digit */
PORTB = ~(1 << DigitCount);
DigitCount++;
/* Reset the Digit Count */
if (DigitCount > 3)
DigitCount=0;
TMR0 = 156; // Initial Value for 3.2 ms Interrupt
T0IF = 0; // Clear TIMER0 interrupt flag
}
}
// Delay Function
#define _delay_us(x) { unsigned char us; \\\\
us = (x)/(12000000/FOSC)|1; \\\\
while(--us != 0) continue; }
void _delay_ms(unsigned int ms)
{
unsigned char i;
do {
i = 4;
do {
_delay_us(164);
} while(--i);
} while(--ms);
}
void SSEG_putnum(void)
{
/* Global interrupt disable */
GIE = 0;
if(flag_update == 1) {
DispDigit[0]=SSEG[digit0_3[0]]; // Centigrade Sign
DispDigit[1]=SSEG[digit0_3[1]]; // Zero Digit
DispDigit[2]=SSEG[digit0_3[2]]; // Zero Digit
DispDigit[3]=SSEG[digit0_3[3]]; // Zero Digit
}
/* Global interrupt enable */
GIE = 1;
}
void main(void)
{
unsigned char i;
OSCCON=0x70; /* Select 8 MHz internal clock */
TRISA = 0xFF; // Input for RA0 to RA7
TRISB = 0x00; // Output for RB0 to RB7
TRISC = 0x00; // Output for RC0 to RC7
ANSEL = 0b00000000; // Set PORT AN0 and AN1 to analog input AN2 to AN7 digital I/O
ANSELH = 0b00000000; // Set Other as Digital I/O
/* Initial Output Port */
PORTC=0xFF;
PORTB=0xFF;
PORTA=0xFF;
/* Init TIMER0: Period: 1/(Fosc/4) x Prescaler x TMR0
0.0005 ms x 64 * 100 = 3.2 ms */
OPTION = 0b00000101; // 1:64 Prescaler
TMR0=156; // Interrupt every 3.2 ms
T0IE = 1; // Enable interrupt on TMR0 overflow
GIE = 1; // Global interrupt enable
DigitCount=0;
for(i=0;i<4;i++) {
digit0_3[i] = eeprom_read(i);
DispDigit[i]=SSEG[digit0_3[i]];
}
for(;;) {
flag_update = 0;
read_key1 = PORTA;
if(read_key1 != read_key2) {
_delay_ms(10);
if(PORTA != 0xFF) {
update_DIGIT();
}
}
read_key2 = read_key1;
SSEG_putnum();
//------- WRITE EEPROM -------------
if(flag_update == 1) {
for(i=0;i<4;i++) {
eeprom_write(i,digit0_3[i]);
}
}
//----------------------------------
// _delay_ms(200);
}
}
void update_DIGIT(void)
{
unsigned char i;
flag_update = 0;
switch(PORTA) {
case KEY_O_DOWN:
i = 3;
digit0_3[i]--;
if(digit0_3[i] <0 ) {
digit0_3[i] = 9; i--;
digit0_3[i]--;
if(digit0_3[i] <0 ) {
digit0_3[i] = 9; i--;
digit0_3[i]--;
if(digit0_3[i] <0 ) {
digit0_3[i] = 9; i--;
digit0_3[i]--;
if(digit0_3[i] <0 ) {
digit0_3[i] = 9; i--;
}
}
}
}
flag_update = 1;
break;
case KEY_0_UP:
i = 3;
digit0_3[i]++;
if(digit0_3[i] >9 ) {
digit0_3[i] = 0; i--;
digit0_3[i]++;
if(digit0_3[i] >9 ) {
digit0_3[i] = 0; i--;
digit0_3[i]++;
if(digit0_3[i] >9 ) {
digit0_3[i] = 0; i--;
digit0_3[i]++;
if(digit0_3[i]>9) {
digit0_3[i] = 0; i--;
}
}
}
}
flag_update = 1;
break;
case KEY_1_DOWN:
digit0_3[2]--; if(digit0_3[2] < 0) digit0_3[2] = 9; flag_update = 1; break;
case KEY_1_UP:
digit0_3[2]++; if(digit0_3[2] > 9) digit0_3[2] = 0; flag_update = 1; break;
case KEY_2_DOWN:
digit0_3[1]--; if(digit0_3[1] < 0) digit0_3[1] = 9; flag_update = 1; break;
case KEY_2_UP:
digit0_3[1]++; if(digit0_3[1] > 9) digit0_3[1] = 0; flag_update = 1; break;
case KEY_3_DOWN:
digit0_3[0]--; if(digit0_3[0] < 0) digit0_3[0] = 9; flag_update = 1; break;
case KEY_3_UP:
digit0_3[0]++; if(digit0_3[0] > 9) digit0_3[0] = 0; flag_update = 1; break;
}
}
/* EOF: 16F886.c */
----------------------------------------------
ยังมีส่วนที่ต้องปรับปรุง คือ จะมีการเขียน EEPROM ทุกครั้งที่มีเปลี่ยนแปลงค่า
ซึ่งตามหลักความเป็นจริง ควรจะบันทึกค่า เมื่อไฟเลี้ยงวงจรตกลง
.
แก้ไขเมื่อ 20 ก.ค. 54 05:43:26
แก้ไขเมื่อ 20 ก.ค. 54 05:40:05