/*
* Copyright (c) by BlackMark 2013
* Date 27/05/2013
* Version 1.3
*
* Used Ports: SW1, SW2, PortA.6, PortA.7
* Used Periphery: 3x4 Keyboard, 2x8 LCD
* Used Libraries: IntFunc_Lib.cc, Key_Lib.cc, LCD_Lib.cc
* Purpose: Initialize a countdown through the 3x4 keyboard. The keys '*' and '#' move the cursor left and right.
* SW1 starts the countdown and SW2 exits the program.
* Once the countdown has reached 0 it turns PortA.7 on for 1 second and starts counting upwards until 99:59:59 at which point it stops.
*/
#define PORT_A6 6
#define PORT_A7 7
long g_lSecondCounter;
byte g_bStartCounter;
char g_szLCDText[9];
void CounterToLCDText( void )
{
long lPositiveSecondCounter;
byte byteHour;
byte byteMinute;
byte byteSecond;
lPositiveSecondCounter = ( (g_lSecondCounter < 0) ? (-g_lSecondCounter) : (g_lSecondCounter) );
byteHour = lPositiveSecondCounter / 3600;
byteMinute = lPositiveSecondCounter / 60 - byteHour * 60;
byteSecond = lPositiveSecondCounter - byteMinute * 60 - byteHour * 3600l;
Str_Printf( g_szLCDText, "%02d:%02d:%02d", byteHour, byteMinute, byteSecond );
}
void DisplayTime( byte byteStartCursorPos, byte byteEndCursorPos )
{
LCD_CursorPos( byteStartCursorPos );
LCD_WriteText( g_szLCDText );
LCD_CursorPos( byteEndCursorPos );
}
void ProcessKeyboard( void )
{
static char s_chKeyOld;
static char s_chCursorPos;
word wKey;
char chKey;
wKey = Key_Scan();
if( wKey )
{
chKey = Key_TranslateKey( wKey );
if( chKey != s_chKeyOld )
{
s_chKeyOld = chKey;
if( chKey == '*' )
{
--s_chCursorPos;
if( s_chCursorPos == 2 || s_chCursorPos == 5 )
{
--s_chCursorPos;
}
}
else if( chKey == '#' )
{
++s_chCursorPos;
if( s_chCursorPos == 2 || s_chCursorPos == 5 )
{
++s_chCursorPos;
}
}
else
{
g_szLCDText[s_chCursorPos] = chKey;
++s_chCursorPos;
}
if( s_chCursorPos == 2 || s_chCursorPos == 5 )
{
++s_chCursorPos;
}
if( s_chCursorPos < 0 )
{
s_chCursorPos = 0;
}
if( s_chCursorPos > 7 )
{
s_chCursorPos = 7;
}
DisplayTime( 0, s_chCursorPos );
}
}
else
{
s_chKeyOld = 0;
}
}
// Timer2 gets called every 10ms
void Timer2Callback( void )
{
static int s_iTickCounter;
static byte s_bStopCounter;
static byte s_bPortState;
static byte s_bSignaled;
if( !g_bStartCounter )
{
ProcessKeyboard();
}
else
{
++s_iTickCounter;
if( g_lSecondCounter == 0 && !s_bSignaled )
{
if( !s_bPortState )
{
Port_WriteBit( PORT_A7, PORT_ON );
s_bPortState = true;
}
}
else
{
if( s_bPortState )
{
Port_WriteBit( PORT_A7, PORT_OFF );
s_bPortState = false;
s_bSignaled = true;
}
}
if( s_iTickCounter == 10 )
{
CounterToLCDText();
if( g_lSecondCounter < 0 )
{
DisplayTime( 0, 0 );
}
else if( g_lSecondCounter == 0 )
{
DisplayTime( 0, 0 );
DisplayTime( 0x40, 0x40 );
}
else
{
DisplayTime( 0x40, 0x40 );
}
}
if( s_iTickCounter == 100 && !s_bStopCounter )
{
g_lSecondCounter = g_lSecondCounter + 1;
if( g_lSecondCounter > 359999 )
{
g_lSecondCounter = 0;
s_bStopCounter = true;
}
s_iTickCounter = 0;
}
}
Irq_GetCount( INT_TIM2COMP );
}
void main( void )
{
byte byteSW1;
byte byteSW2;
char szBuffer[3];
byte byteHour;
byte byteMinute;
byte byteSecond;
g_lSecondCounter = 0;
g_bStartCounter = false;
g_szLCDText = "00:00:00";
szBuffer = "00";
LCD_Init();
LCD_ClearLCD();
LCD_CursorOn();
LCD_CursorPos( 0 );
LCD_WriteText( g_szLCDText );
LCD_CursorPos( 0 );
Key_Init();
Port_DataDirBit( PORT_SW1, PORT_IN );
Port_DataDirBit( PORT_SW2, PORT_IN );
Port_WriteBit( PORT_SW1, PORT_OFF );
Port_WriteBit( PORT_SW2, PORT_OFF );
Port_DataDirBit( PORT_A6, PORT_IN );
Port_DataDirBit( PORT_A7, PORT_OUT );
Port_WriteBit( PORT_A7, PORT_OFF );
Irq_SetVect( INT_TIM2COMP, Timer2Callback );
while( true )
{
byteSW1 = Port_ReadBit( PORT_SW1 );
byteSW2 = Port_ReadBit( PORT_SW2 );
if( !byteSW1 && !g_bStartCounter )
{
szBuffer[0] = g_szLCDText[0];
szBuffer[1] = g_szLCDText[1];
byteHour = Str_ReadInt( szBuffer );
szBuffer[0] = g_szLCDText[3];
szBuffer[1] = g_szLCDText[4];
byteMinute = Str_ReadInt( szBuffer );
szBuffer[0] = g_szLCDText[6];
szBuffer[1] = g_szLCDText[7];
byteSecond = Str_ReadInt( szBuffer );
g_lSecondCounter = -( byteHour * 3600l + byteMinute * 60 + byteSecond );
if( g_lSecondCounter < -359999 )
{
g_lSecondCounter = -( 99 * 3600 + 59 * 60 + 59 );
}
LCD_CursorOff();
g_bStartCounter = true;
}
if( !byteSW2 )
{
LCD_CursorPos( 0 );
LCD_CursorOff();
LCD_ClearLCD();
break;
}
}
}