📄 main.c
字号:
////Atmel AVR Design Contest 2006 Registration Number AT3221////***************************************************************************//// File........: main.c//// Author(s)...: ATMEL Norway//// Target(s)...: ATmega169//// Compiler....: AVR-GCC 3.3.1; avr-libc 1.0//// Description.: AVR Butterfly main module//// Revisions...: 1.0//// YYYYMMDD - VER. - COMMENT - SIGN.//// 20030116 - 1.0 - Created - KS// 20031009 port to avr-gcc/avr-libc - M.Thomas (*)// 20040308 - 0.14 - Modified for VUW TempBug Use - N. Lott// 20060815 - 0.25 - Modified for Butterfly Logger - N. Lott//***************************************************************************// (*) Martin Thomas, Kaiserslautern, Germany, e-mail: mthomas(at)rhrk.uni-kl.de // or eversmith(at)heizung-thomas.de//// I'm not working for ATMEL.// The port is based on REV_06 of the ATMEL-Code (for IAR-C)// Initialy I marked my changes with "// mt" or enclosed them with "// mtA" and // "// mtE" but forgot this for some changes esp. during debugging. 'diff' // against the original code to see everything that has been changed.//mtA//#include <inavr.h>//#include "iom169.h"#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/sleep.h>#include <inttypes.h>//mtE#include "main.h"#include "LCD_functions.h"#include "LCD_driver.h"#include "button.h"#include "RTC.h"#include "timer0.h"#include "BCD.h"#include "usart.h"#include "ADC.h"#include "dataflash.h"#include "speed.h"#include "menu.h"#include "Sht.h"#include "alarm.h"#define pLCDREG_test (*(char *)(0xEC))extern unsigned int LCD_character_table[] PROGMEM;char gAutoPressJoystick = FALSE; // global variable used in "LCD_driver.c"unsigned char state; // helds the current state, according to // "menu.h"// gPowerSave globals//char gPowerSaveTimeout; // Autopowersave period in minutesBOOL gAutoPowerSave; // Variable to enable/disable the Auto Power Save funcchar gPowerSave; // current state of Power save modeextern BOOL glogSpeed; // from speed.c to prevent sleep while timming speed.char gUART; // prevent entering power save, when using the UART// timing globals from RTC.c// extern char gLogTimeCounter; // current elapsed logging intervalextern char gLogTimeUnit; // units for gLogTimeextern char gLogTime; // interval between loggingextern char gPowerSaveTimer; // external Counter from "RTC.c"// Global variables for the Flash//BOOL gEnableRollover; // allow flash to reset after filling completlychar gRolloverFlash; // number of times flash has filledunsigned char gDataPosition; // position in page of next write to df unsigned int gDataPage; // current page to be written to the flashBOOL gUploading; // Let other functions know we are uploading from the dfBOOL gLogging; // Logging is enabledBOOL gLogNow; // write to log next iteration of the main loop// Private functions//void DF_write_int(int data);int DF_read_int(void);//uint8_t DS1820_SENSOR_ID[]=0x00,0x00,0x00,0x00;/******************************************************************************* Function name : main** Returns : None** Parameters : None** Purpose : Contains the main loop of the program******************************************************************************/// mt __C_task void main(void)int main(void){ // unsigned char state, nextstate; unsigned char nextstate; // mt static char __flash *statetext; PGM_P statetext; char (*pStateFunc)(char); char input; uint8_t i; // char i; char buttons; char last_buttons; // set default values for the global variables gEnableRollover = DEFAULT_EN_ROLLOVER; gRolloverFlash = 0; gDataPosition=0; gDataPage=0; gUploading= FALSE; gLogging =DEFAULT_EN_LOGGING; gLogNow = FALSE; gUART = TRUE; gPowerSaveTimeout = DEFAULT_POWERSAVETIMEOUT; gAutoPowerSave = DEFAULT_EN_POWERSAVE; gPowerSave = FALSE; last_buttons='\0'; // mt // Initial state variables state = nextstate = ST_AVRBF; statetext = MT_AVRBF; pStateFunc = 0; // Program initalization Initialization(); sei(); // mt __enable_interrupt(); for (;;) // Main loop { if(!gPowerSave) // Do not enter main loop in power-save { // Plain menu text if (statetext) { LCD_puts_f(statetext, 1); LCD_Colon(0); statetext = NULL; } input = getkey(); // Read buttons if (pStateFunc) { // When in this state, we must call the state function nextstate = pStateFunc(input); } else if (input != KEY_NULL) { // Plain menu, clock the state machine nextstate = StateMachine(state, input); } if (nextstate != state) { state = nextstate; // mt: for (i=0; menu_state[i].state; i++) for (i=0; pgm_read_byte(&menu_state[i].state); i++) { //mt: if (menu_state[i].state == state) if (pgm_read_byte(&menu_state[i].state) == state) { // mtA // mt - original: statetext = menu_state[i].pText; // mt - original: pStateFunc = menu_state[i].pFunc; /// mt this is like the expample from an avr-gcc guru (mailing-list): statetext = (PGM_P) pgm_read_word(&menu_state[i].pText); // mt adresses?! // mt - store pointer to function from menu_state[i].pFunc in pStateFunc //// pStateFunc = pmttemp; // oh je - wie soll ich das jemals debuggen - ? pStateFunc = (PGM_VOID_P) pgm_read_word(&menu_state[i].pFunc); // mtE break; } } } } //Put the ATmega169 enable power save modus if autopowersave if(gAutoPowerSave) { if(gPowerSaveTimer >= gPowerSaveTimeout) { state = ST_AVRBF; gPowerSaveTimer = 0; gPowerSave = TRUE; gUART=FALSE; } } // Check if the joystick has been in the same position for some time, // then activate auto press of the joystick buttons = (~PINB) & PINB_MASK; buttons |= (~PINE) & PINE_MASK; if( buttons != last_buttons ) { last_buttons = buttons; gAutoPressJoystick = FALSE; } else if( buttons ) { if( gAutoPressJoystick == TRUE) { PinChangeInterrupt(); gAutoPressJoystick = AUTO; } else gAutoPressJoystick = AUTO; } if(!gUART && !glogSpeed) // Do not enter Power save if using UART or playing tunes { if(gPowerSave) cbi(LCDCRA, 7); // disable LCD // mtA SMCR = (3<<SM0) | (1<<SE); // Enable Power-save mode asm volatile ("sleep"::); // __sleep(); // Go to sleep // mt 20031204 - avr-libc 1.0 sleep.h seems to be incompatible with mega169 /// no! // set_sleep_mode(SLEEP_MODE_PWR_SAVE); /// no! // sleep_mode(); // mtE if(gPowerSave) { if(!(PINB & 0x40)) // press UP to wake from SLEEP { gPowerSave = FALSE; gUART = TRUE; // wake up Uart as well for(i = 0; i < 20; i++) // set all LCD segment register to the variable ucSegments { *(&pLCDREG_test + i) = 0x00; } sbi(LCDCRA, 7); // enable LCD input = getkey(); // Read buttons } } } else { // mtA SMCR = (1<<SE); // Enable idle mode asm volatile ("sleep"::); //__sleep(); // Go to sleep // mt 20031204 - avr-libc 1.0 sleep.h seems to be incompatible with mega169 /// no! // set_sleep_mode(SLEEP_MODE_IDLE); /// no! // sleep_mode(); // mtE } SMCR = 0; // Just woke, disable sleep // do logging if needed if (gLogNow) { doLogging(); } } //End Main loop return 0; // mt }/******************************************************************************* Function name : StateMachine** Returns : nextstate** Parameters : state, stimuli** Purpose : Shifts between the different states******************************************************************************/unsigned char StateMachine(char state, unsigned char stimuli){ unsigned char nextstate = state; // Default stay in same state unsigned char i; // mt: for (i=0; menu_nextstate[i].state; i++) for (i=0; pgm_read_byte(&menu_nextstate[i].state); i++) { // mt: if (menu_nextstate[i].state == state && menu_nextstate[i].input == stimuli) if (pgm_read_byte(&menu_nextstate[i].state) == state && pgm_read_byte(&menu_nextstate[i].input) == stimuli) { // This is the one! // mt: nextstate = menu_nextstate[i].nextstate; nextstate = pgm_read_byte(&menu_nextstate[i].nextstate); break; } } return nextstate;}/******************************************************************************* Function name : Initialization** Returns : None** Parameters : None** Purpose : Initializate the different modules******************************************************************************/void Initialization(void){ unsigned char tst; // dummy OSCCAL_calibration(); // calibrate the OSCCAL byte CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable // set prescaler = 2, Inter RC 8Mhz / 2 = 4Mhz // WARNING NOW RUNNING AT 4MHZ CLKPR = (0<<CLKPS1) | (1<<CLKPS0); // Disable Analog Comparator (power save) ACSR = (1<<ACD); // Disable Digital input on PF0-2 (power save) DIDR1 = (7<<ADC0D); // mt PORTB = (15<<PORTB0); // Enable pullup on PORTB = (15<<PB0); // Enable pullup on // mt PORTE = (15<<PORTE4); PORTE = (15<<PE4); PORTF &= ~((1<<PORTF4)|(1<<PORTF6)); DDRF &= ~(1<<PORTF4); Button_Init(); // Initialize pin change interrupt on joystick RTC_init(); // Start timer2 asynchronous, used for RTC clock Timer0_Init(); // Used for call backs#ifdef OSC_ALT USART_Init(3); // Baud rate = 28800bps @ 1Mhz, 115200 @ 4Mhz#else USART_Init(12); // Baud rate = 9600bps @ 1Mhz, 38400 @ 4Mhz#endif DF_SPI_init(); // init the SPI interface to communicate with the DataFlash tst = Read_DF_status(); DF_CS_inactive; // disable DataFlash USART_Tx_Hex(tst); // dumpflash status on powerup as a safety check. LCD_Init(); // initialize the LCD#if EN_LOG_SPEED Speed_init(); // init Windspeed counter#else gSpeedSecondsToLog =0;#endif#if EN_LOG_SHT ShtInit(); // Initialize Temp / Humidity sensor; ShtReadStatus(&tst); USART_Tx_Hex(tst); #endif ALARM_clear();}/******************************************************************************* Function name : BootFunc** Returns : char ST_state (to the state-machine)** Parameters : char input (from joystick)** Purpose : Reset the ATmega169 which will cause it to start up in the * Bootloader-section. (the BOOTRST-fuse must be programmed)******************************************************************************/// mt __flash char TEXT_BOOT[] // mt - as in jw-patch: const char TEXT_BOOT[] PROGMEM = "Jump to bootloader";char BootFunc(char input){ static char enter = 1; if(enter) { enter = 0; // mt jw LCD_puts_f(TEXT_BOOT, 1); LCD_puts_f(PSTR("Jump to bootloader"), 1); } else if(input == KEY_ENTER) { // mt WDTCR = (1<<WDCE) | (1<<WDE); //Enable Watchdog Timer to give reset WDTCR = (1<<WDCE) | (1<<WDE); //Enable Watchdog Timer to give reset while(1); // wait for watchdog-reset, since the BOOTRST-fuse is // programmed, the Boot-section will be entered upon reset. }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -