Writing Code For Microcontrollers: A Rough Outline For Your Program
Writing Code For Microcontrollers: A Rough Outline For Your Program
Also included at the beginning is how the hardware is to be connected. Embedded code is intimately connected to the hardware. If you dont specification hardware connections, the code cannot be debugged efficiently.
// // // // // // // // // // // // HARDWARE SETUP: PORTA is connected to the shared segments of the LED display. PORTA.0 corresponds to seg a, PORTA.1 corresponds to seg b, etc. PORTB bits 4-7 correspond to LED digits 0-3. Switch 0: toggle function, amount to increment or decrement count. Switch 1: toggle function, selects which encoder (0,1) changes count. Switch 2: toggle function, sets display to bright or dim. Enocder pinout: encoder 0, A = PORTE.3 B = PORTE.2 encoder 1, A = PORTE.5 B = PORTE.4
A good practice to use function prototypes. These are a declaration of the function that omits the function body but only specifies the function's name, argument types and return type. Declaring them all in a header file and including that file allows you to use them in any order without the compiler complaining.
//main while loop of program follows // -checks encoders // -increment/decrement count if something changed // -display next digit // -check increment/decrement amount and encoder to check while(1){ _delay_loop_2(500); //loop debounce required
Note comment style. Dont box areas with /* */. Causes too much re-editing.
To set this register up, this would be most clear: TCCRO = (1<<FOC0) | (1<<WGM00) | (1<<CS00); TCCRO would be loaded with 0b1100_0001; This form is most likely to work across multiple models of the AVR architecture.
To set this register up, this would be most clear: OCR0 = 0x53; // OCR0 match is at 0x53
If we simply wrote a 0x02 to TIFR, a pending interrupt in the TOV0 bit would be cleared and lost. So instead we do this: TIFR |= (1<<OCF0); // clear OCF0 interrupt and not this: TIFR = (1<<OCF0); //clear OCFO interrupt(OOPS!)
//from code for a mega128 void spi_init(void){ DDRB |= (1<<PB2) | (1<<PB1) | (1<<PB0); //Turn on SS, MOSI, SCLK SPCR=(1<<SPE) | (1<<MSTR); //enbl SPI, clk low init, rising edge sample SPSR=(1<<SPI2X); //SPI at 2x speed (8 MHz) }//spi_init
Only the pin definitions for ports differ. Why does this work?
from iomx8.h (included from iom48.h) also in (.../avr/avr/include/avr) #define SPCR _SFR_IO8 (0x2C) /* SPCR */ #define SPIE 7 #define SPE 6 #define DORD 5 #define MSTR 4 #define CPOL 3 #define CPHA 2 #define SPR1 1 #define SPR0 0
Although the SPCR register is at a different address and the control register bits may have been at different positions, as long as these definitions are here, the code is portable across any Mega type processor.