#include
#include
/ / Interrupt function definition
Void IRQ1 (Void) __ATtribute __ ((ier));
Void IRQ5 (void) __ATtribute __ ((ISR));
Void IRQ6 (Void) __ATtribute __ ((ier));
Enum {run, chgsecond, chgminute, chGHOUR} clock_status; // clock status
Unsigned int hour, minute, second;
Unsigned int show_Hour, show_minute, show_second;
ENUM {NOKEY, PRESSING, PRESSED} key_status; // Keyboard Press or not
UNSIGNED key_code;
// 7 segment of the LED digital tube word code, using high eight-bit output, decide the displayed glyph, such as: '0', '1', etc.
Const unsigned int zhixingma [] = {0X
3F
00, 0x0600, 0x5B00, 0X
4F
00,
0x6600, 0x6d00, 0x
7C
00, 0x0700,
0x
7f
00, 0x
6f
00};
// Digital tube selected "bit code", decide which digital tube display
Const unsigned int weiduana [] = {0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040};
// The two DD pins of the digital tube, when the middle colon is bright
Const unsigned int Wei_dd = 0x0081;
Void Display (unsigned int,, unsigned int number)
{
* P_ioa_data = zhixingma [number];
/ / When setting the bit segment code, you cannot change the state of the colon.
* P_iob_data = weiduanma [wei] | (* p_iob_buffer & wei_dd);
}
/ / Reverse the colon in the middle of the digital tube
void oppositive_dots ()
{
* P_iob_data = wei_dd ^ (* p_iob_buffer);
}
Void delay (unsigned int howlong)
{
While (howlong -) {
Unsigned int TEMP = 0x00FF;
* P_watchdog_clear = 1;
While (TEMP -);
}
}
void init ()
{
Int_off ();
* P_ioa_dir = 0xff00;
* P_ioa_attrib = 0xff00;
* P_iob_dir = 0x00FF;
* P_iob_attrib = 0x00FF;
* P_timera_data = 0xffff - 256;
* P_timera_ctrl = c_sourcea_1 | c_sourceb_256hz;
* P_int_ctrl = C_IRQ1_TMA | C_IRQ6_TMB2 | C_IRQ5_2Hz;
INT_IRQ ();
}
void change_clock ()
{
Unsigned int key_code = get_key ();
Static unsigned int max;
Switch (key_code) {// key_code == 0 Will Do Nothing
Case 1:
Switch (clock_status) {
Case chgsecond: IF ( second == 60) second = 0;
Break;
Case Chgminute:
IF ( minute == 60) minute = 0;
Break;
Case Chghour:
IF ( hour == 24) hour = 0;
Break;
DEFAULT:
Break;
}
Break;
Case 2:
Switch (clock_status) {
Case chgsecond:
IF (- SECOND == 0) second = 59;
Break;
Case Chgminute:
IF (- minute == 0) minute = 59;
Break;
Case Chghour:
IF (- Hour == 0) Hour = 23;
Break;
DEFAULT:
Break;
}
Break;
Case 3:
Switch (clock_status) {
Case Run:
Clock_status = chgsecond;
Break;
Case chgsecond:
Clock_status = chgminute;
Break;
Case Chgminute:
Clock_status = chGHOUR;
Break;
Case Chghour:
Clock_Status = Run;
Break;
}
Break;
DEFAULT:
Break;
}
}
int main ()
{
INIT ();
While (1) {
Change_clock ();
IF (show_second) {
Display (5, Second% 10);
DELAY (1);
Display (4, Second / 10);
DELAY (1);
}
IF (show_minute) {
Display (3, minute% 10);
DELAY (1);
Display (2, minute / 10);
DELAY (1);
}
IF (show_Hour) {
Display (1, Hour% 10);
DELAY (1);
Display (0, hour / 10);
DELAY (1);
}
}
}
Void IRQ1 ()
{
/ / Clock count interrupt
IF ((C_IRQ1_TMA & * P_INT_CTRL)! = 0)
{IF (Clock_Status == Run)
{Second ;
IF (Second> = 60) second = 0, Minute ;
IF (minute> = 60) minute = 0, Hour ;
IF (hour> = 24) hour = 0;
}
* P_int_clear = c_irq1_tma;
}
}
Void IRQ5 ()
{// Digital Tube Flashing
IF ((C_IRQ5_2Hz & * P_INT_CTRL)! = 0)
{
Switch (clock_status) {
Case Run:
Opposite_dots ();
SHOW_HOUR = Show_minute = show_second = 0xfff;
Break;
Case chgsecond:
Show_second ^ = 0xffff;
Show_minute = show_Hour = 0xfff;
Break;
Case chgminute: show_minute ^ = 0xfff;
SHOW_SECOND = show_Hour = 0xfff;
Break;
Case Chghour:
SHOW_HOUR ^ = 0xfffff;
SHOW_SECOND = show_minute = 0xfff;
Break;
}
* P_int_clear = c_irq5_2hz;
}
}
Void IRQ6 ()
{// Scan a keyboard every 10ms
Static unsigned int ket_key = 0;
Static unsigned int key_count = 0;
Unsigned int current_key;
IF ((C_IRQ6_TMB2 & * P_INT_CTRL)! = 0)
{Current_key = * p_ioa_data & 0x0007;
IF (current_key! = 0)
{// with buttons
IF (Key_Status == Nokey)
{OLD_KEY = CURRENT_KEY;
Key_Count ;
Key_Status = pressing;
} else {
IF (current_key == old_key) // does not equal, shake
{
IF ( Key_Count> = 5)
//> 5 times the value of the scan, explanation is not shake, determine the key value
{IF (current_key == 0x0001) key_code = 1;
IF (current_key == 0x0002) key_code = 2;
IF (current_key == 0x0004) key_code = 3;
}
} else {
// jitter
OLD_KEY = 0;
Key_count = 0;
Key_Status = NoKey;
}
}
} else {// no button
OLD_KEY = 0;
Key_count = 0;
IF (key_status == pressure) key_status = PRESSED; / / button released
}
* P_int_clear = C_IRQ6_TMB2;
}
}