Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C Programming for microcontrollers (Joe Pardue, 2005).pdf
Скачиваний:
260
Добавлен:
12.08.2013
Размер:
4.55 Mб
Скачать

Chapter 8: C Pointers and Arrays

Finally we get the Tens by right shifing the byte 4-bits, which we use as the ASCII character offset.

Tens = (Tens >> 4) + '0';

We’ll use these ideas in the showClock function in the software.

The Real Timer Clock Software

In the software you will encounter: uint8_t, which is WinAVR specific and denotes what would normally we called ‘unsigned char’ and is the same as a byte.

Create a new directory, Real Time Clock, and copy the .c and .h files and the makefile from the Messenger directory.

Open Messenger.h in Programmers Notepad and write:

// identify yourself specifically

const char TALKING_TO[] PROGMEM = "\rYou are talking to the "; const char WHO_DEMO[] PROGMEM = "'Real Time Clock' demo.\r";

// bad command

const char BAD_COMMAND1[] PROGMEM = "\rYou sent: '";

const char BAD_COMMAND2[] PROGMEM = "' - I don't understand.\r";

const char ENTER[] PROGMEM = "Enter ";

const char TEXT_GET[] PROGMEM = "'get' to get the time and date.\r";

const char TEXT_SEC[] PROGMEM = "'secXX' to set the second"; const char TEXT_MIN[] PROGMEM = "'minXX' to set the minute"; const char TEXT_HOUR[] PROGMEM = "'hourXX' to set the hour"; const char TEXT_TOXX[] PROGMEM = " to XX.\r";

const char ERROR_NUMBER[] PROGMEM = "\rERROR - number must be less than ";

const char ERROR_60[] PROGMEM = " 60.\r"; const char ERROR_12[] PROGMEM = " 12.\r";

const char THE_TIME_IS[] PROGMEM = "The time is: ";

Open Demonstrator.h and write:

182

Chapter 8: C Pointers and Arrays

// Demonstrator.h Real Timer Clock version

void initializer(void); void parseInput(char *);

void setSecond(char *); void setMinute(char *); void setHour(char *);

char CHAR2BCD2(char input); void RTC_init(void);

void showClock(void); void setClock(void);

Open Demonstrator.c and write:

// Demonstrator.c Real Time Clock version

#include "PC_Comm.h" #include "Messages.h"

unsigned char gSECOND; unsigned char gMINUTE; unsigned char gHOUR;

void initializer()

{

//Calibrate the oscillator: OSCCAL_calibration();

//Initialize the USART USARTinit();

//Initialize the RTC

RTC_init();

// Display instructions on PC sendFString(TALKING_TO); sendFString(WHO_DEMO); sendFString(ENTER); sendFString(TEXT_GET); sendFString(ENTER); sendFString(TEXT_SEC); sendFString(TEXT_TOXX); sendFString(ENTER); sendFString(TEXT_MIN); sendFString(TEXT_TOXX); sendFString(ENTER);

183

Chapter 8: C Pointers and Arrays

sendFString(TEXT_HOUR); sendFString(TEXT_TOXX);

}

void parseInput(char s[])

{

// parse first character switch (s[0])

{

case 'g':

if( (s[1] == 'e') && (s[2] == 't') ) showClock();

break; case 's':

if( (s[1] == 'e') && (s[2] == 'c') ) setSecond(s);

break; case 'm':

if( (s[1] == 'i') && (s[2] == 'n') ) setMinute(s);

break; case 'h':

if( (s[1] == 'o') && (s[2] == 'u') && (s[3] == 'r')) setHour(s);

break; case 'd':

if((s[1]=='e')&&(s[2]=='m')&&(s[3]=='o')&&(s[4]=='?')) sendFString(TALKING_TO); sendFString(WHO_DEMO);

break;

default: sendFString(BAD_COMMAND1); sendChar(s[0]); sendFString(BAD_COMMAND2);

break;

}

s[0] = '\0';

}

void setSecond(char s[])

{

char str[] = {0,0,'\0'}; int sec;

184

Chapter 8: C Pointers and Arrays

str[0] = s[3]; str[1] = s[4];

sec = atoi(str); if( sec <= 60)

{

gSECOND = (uint8_t)sec;

}

else

{

sendFString(ERROR_NUMBER); sendFString(ERROR_60);

}

}

void setMinute(char s[])

{

char str[] = {0,0,'\0'}; int min;

str[0] = s[3]; str[1] = s[4];

min = atoi(str); if( min <= 60)

{

gMINUTE = (uint8_t)min;

}

else

{

sendFString(ERROR_NUMBER); sendFString(ERROR_60);

}

}

void setHour(char s[])

{

char str[] = {0,0,'\0'}; int hour;

str[0] = s[4]; str[1] = s[5];

hour = atoi(str); if( hour <= 12)

{

gHOUR = (uint8_t)hour;

}

else

{

sendFString(ERROR_NUMBER);

185

Chapter 8: C Pointers and Arrays

sendFString(ERROR_12);

}

}

void showClock(void)

{

uint8_t HH, HL, MH, ML, SH, SL;

HH = CHAR2BCD2(gHOUR);

HL = (HH & 0x0F) + '0';

HH = (HH >> 4) + '0';

MH = CHAR2BCD2(gMINUTE);

ML = (MH & 0x0F) + '0';

MH = (MH >> 4) + '0';

SH = CHAR2BCD2(gSECOND);

SL = (SH & 0x0F) + '0';

SH = (SH >> 4) + '0';

sendFString(THE_TIME_IS); sendChar(HH); sendChar(HL); sendChar(':'); sendChar(MH); sendChar(ML); sendChar(':'); sendChar(SH); sendChar(SL); sendChar('\r');

}

//convert a character into a binary coded decimal chracter in the range

//0 to 99 resulting byte has tens in high nibble and ones in low nibble char CHAR2BCD2(char input)

{

char high = 0;

while (input >= 10)

// Count tens

{

 

high++;

 

input -= 10;

 

}

 

return (high << 4) | input;

// Add ones and return answer

}

186

Chapter 8: C Pointers and Arrays

//initialize Timer/counter2 as asynchronous using the 32.768kHz watch

//crystal.

void RTC_init(void)

{

// wait for external crystal to stabilise for(int i = 0; i < 10; i++)

_delay_loop_2(30000);

cli();

// disable global

interrupt

cbi(TIMSK2, TOIE2);

// disable OCIE2A

and TOIE2

ASSR = (1<<AS2);

// select asynchronous operation of Timer2

TCNT2 = 0;

// clear TCNT2A

//select precaler: 32.768 kHz / 128 = 1 sec between each overflow TCCR2A |= (1<<CS22) | (1<<CS20);

//wait for TCN2UB and TCR2UB to be cleared

while((ASSR & 0x01) | (ASSR & 0x04));

TIFR2 = 0xFF;

// clear interrupt-flags

sbi(TIMSK2, TOIE2);

// enable Timer2 overflow interrupt

sei();

 

// enable global interrupt

// initial time and date setting

gSECOND

= 0;

 

gMINUTE

= 0;

 

gHOUR

= 0;

 

}

 

 

// one second interrupt from 32kHz watch crystal

SIGNAL(SIG_OVERFLOW2)

 

{

 

// increment second

gSECOND++;

if (gSECOND == 60)

 

{

 

 

gSECOND = 0;

// increment minute

gMINUTE++;

if (gMINUTE > 59)

 

{

gMINUTE = 0;

 

 

// increment hour

 

gHOUR++;

if (gHOUR > 12)

187

Chapter 8: C Pointers and Arrays

{

gHOUR = 0;

}

}

}

}

Using Real Time Clock:

After compiling and loading the code, in HyperTerminal you should see:

You are talking to the 'Real Time Clock' demo.

Enter 'get' to get the time and date.

Enter 'secXX' to set the second to XX.

Enter 'minXX' to set the minute to XX.

Enter 'hourXX' to set the hour to XX.

Get the current time:

get

The time is: 12:00:03

Which initially should be a few seconds past 12. Set the current time as follows:

sec45

min4

hour11

Then you can get the correct time:

get

The time is: 11:05:01 get

The time is: 11:05:12 get

The time is: 11:05:17

188