demonstrator.c

来自「The collection of AVR source code in C.」· C语言 代码 · 共 242 行

C
242
字号
// 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);	
	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;
	
	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);
		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
}



// 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();					// disabel 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)
{
    gSECOND++;		// increment second

    if (gSECOND == 60)
    {
        gSECOND = 0;
        gMINUTE++;		// increment minute
        
        if (gMINUTE > 59)
        {
            gMINUTE = 0;
            gHOUR++;	// increment hour
            
            if (gHOUR > 12)
            {             
                gHOUR = 0;
			}
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?