📄 avrdependent.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 + -