⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avrdependent.c

📁 学完单片机就要使用实时系统在单片机上运行
💻 C
字号:

// AVRdependent.c
// (C) 2004 Steve Childress stevech@san.rr.com

#ifndef __AVR_ATmega32__
#define __AVR_ATmega32__
#endif

#include "OPEX.h"

const BYTE TCCR2INIT = 2;		// 1 == 128 interrupts/sec with 32768Hz crystal
const int TICKSPERSECOND = 128/8;	// <<< Change this if TCCR2 initialization is changed


jmp_buf OPEX_sched_jmp;			// used for OPEX_sched_quit
BYTE TicksPerSecond; 		// stores timer-dependent tick rate

// storage in EEPROM
EEPROM char 		eeprom0;
EEPROM DATE_TIME 	saved_time;


/////////////////////////////////////////////////////////
    //outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCR);
    /* set baud rate */
    //outp( (u08)UART_BAUD_SELECT, UBRR); 
void io_init(void)
{

	// PortA
	PORTA = 0x0;
	DDRA = 0x0;
	// PortB
	PORTB = 0x0;
	DDRB = 0x2;	// LED on  bit 1
	// PortC
	PORTC = 0x0;
	DDRC = 0xFF;	// LEDs off
	// PortD
	PORTD = 0x0;
	DDRD = 0x0;

	// Watchdog 
	wdt_disable();
	//wdt_enable(7); // 2 second timeout
	// Analog Comparator Disabled
	ACSR = 0x80;
}



////////////////////////////////////////////////
void timer_init(void)
{
	
	// Timer/Counter0 Clock source: System Clock
	// Timer/Counter0 Clock value: Stopped
	// Timer/Counter0 Mode: Normal
	// Timer/Counter0 Output: Disconnected
	OCR0 = 0x0;
	TCNT0 = 0x0;
	TCCR0 = 0x0;

	// Timer/Counter1 Clock source: System Clock
	// Timer/Counter1 Clock value: Stopped
	// Timer/Counter1 Mode: Normal
	// Timer/Counter1 Output: A: Disconnected, B: Disconnected
	OCR1AL = 0x0;
	OCR1AH = 0x0;
	OCR1BL = 0x0;
	OCR1BH = 0x0;
	TCNT1L = 0x0;
	TCNT1H = 0x0;
	TCCR1A = 0x0;
	TCCR1B = 0x0;
	
	// Timer/Counter 2 initialization
    // Clock source: TOSC1 pin
    // Clock value: PCK2/128
    // Mode: Output Overflow
    // OC2 output: Disconnected
    
    // using 327868Hz crystal
    TCCR2 =TCCR2INIT;			// interrupts per sec
    ASSR = (1 << AS2); 	// AST bit -> use the wired 32768 Hz Xtal
    TCNT2=0x00;
	TIMSK |= (1 << TOIE2);	// Timer2 overflow interrupt
	
	TicksPerSecond= TICKSPERSECOND;	//for OPEX's timer routine to retrieve at run-time
	
	// default to prevent time of day interrupt from crumping
	time.year = 03;
	time.second = time.minute = time.hour = 0;
	time.day = time.month = 1;
	restore_date();	// restore last known date/time/TZ
	
}

/////////////////////////////////////////////////////////
// this is here as layout of jmp_buf may be chip dependent
void avr_setjmp(void)
{
	setjmp(OPEX_sched_jmp);	// save state
}


/////////////////////////////////////////////////////////
// Routines to save/restore params in EEPROM
struct TTEMP {
		DATE_TIME dt;
		int8_t GMT_offset_standard;
		int8_t GMT_offset_now;
		unsigned int csum;
};

// Optional use: get last saved time from EEPROM
// returns 0 if successful read from EEPROM
int restore_date()
{
	unsigned int cs;
	BYTE i, *p;
	struct TTEMP ttemp;

	
	// read saved date from EEPROM, verify checksum
	eeprom_read_block(&ttemp, &saved_time, sizeof(ttemp));  // read from EEPROM
	// verify checksum
	cs = 0;
	p = (BYTE *)&ttemp;
	for (i = 0; i < (sizeof(ttemp) - sizeof(ttemp.csum)); ++i)
		cs += (unsigned int)*p++;
	if (cs == ttemp.csum)  {  // if checksum is OK, use the EEPROM saved date info
		cli();
		memcpy(&time, &ttemp.dt, sizeof(DATE_TIME));  // fast copy to volatile (ISR accesses)
		GMT_offset_now = ttemp.GMT_offset_now;
		GMT_offset_standard = ttemp.GMT_offset_standard; 
		sei();
		return(0);
	}
	return(1);
}

// Optional use: save the time to EEPROM, along with a checksum
void save_date()
{
	BYTE i, *p;
	struct TTEMP ttemp;

	// copy current date/time into local buffer
	cli();
	memcpy(&ttemp.dt, &time, sizeof(DATE_TIME));  // fast copy from volatile (ISR accesses)
	ttemp.GMT_offset_standard = GMT_offset_standard;
	ttemp.GMT_offset_now = GMT_offset_now;	
	sei();
	// calculate/save checksum
	ttemp.csum = 0;
	p = (BYTE *)&ttemp;
	for (i = 0; i < (sizeof(ttemp) - sizeof(ttemp.csum)); ++i)
		ttemp.csum += (unsigned int)*p++;		
	// save date/time/GMT offset and checksum
	eeprom_write_block(&ttemp, &saved_time, sizeof(ttemp));  // put time in EEPROM
}


/////////////////////////////////////////////
void serial_init(void)
{
	
	// Baud Rate: 19200
	// Character Size: 8-bit
	// Mode: Asynchronous
	// Parity: Disabled
	// Stop Bit: 1-bit

	UCSRA = 0;
	UCSRB = (1<<RXCIE) | (1<<TXEN) | (1<<RXEN);  // Async no parity 1 stop bit; Tx, Rx enabled
	UCSRC = (1<<URSEL) | (3<<UCSZ0); // URSEL to write USART control, 3 -> 8 bit chars
	
	UBRRL = 0x13; // (fCPUosc / 16Baud) - 1, for 6MHz crystal
	UBRRH = 0;
	
	//uart = fdevopen ( &usart_putchar,0,0);
}

/////////////////////////////////////////////
void serial_stop(void)
{	
	loop_until_bit_is_clear(UCSRA, UDRIE);	
	cbi(UCSRB, TXEN);
}



//////////////////////////////////////////
// change state of transmit interrupt enable
// called by OPEX
void serial_change_txIE(BYTE state)
{
	if(state == 0)
		cbi(UCSRB, UDRIE); // tx interrupt disnable
	else
		sbi(UCSRB, UDRIE); // tx interrupt enable	
}

//////////////////////////////////////////
// get state of transmit interrupt enable
// called by OPEX
int serial_get_txIE(void)
{
	if (bit_is_clear(UCSRB, UDRIE))
		return(0);
	return(1);
}
//////////////////////////////////////////
// Send byte to serial transmit register
void serial_tx_put(BYTE c)
{
	UDR = c;	
}


////////////////////////////////////////////////////
// Non-blocking serial output
void serial_tx_put_nb(OPEX_TCB *f)
{

}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//// INTERRUPT SERVICE ROUTINES

/////////////////////////////////////////////////
// Timer interrupt
///
SIGNAL(SIG_OVERFLOW2)
{
	if(time.tick == 0)
		PORTB = PORTB ^ 2; // TOGGLE LED
	OPEX_timer_ISR();		// time of day processing
}

///////////////////////////////////////
// U(S)ART  Receive Data Arrival
SIGNAL(SIG_UART_RECV)
{
	OPEX_com_rx_ISR(UDR);
}

///////////////////////////////////////
// U(S)ART Transmit Data Reg Empty Interrupt
SIGNAL(SIG_UART_DATA)  
{
	OPEX_com_tx_ISR();
}

⌨️ 快捷键说明

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