* information for the simulator */ #include "avr_mcu_section.h" AVR_MCU(F_CPU, "atmega2560"); // tell simavr to listen to commands written in this (unused) register AVR_MCU_SIMAVR_COMMAND(&GPIOR0); AVR_MCU_SIMAVR_CONSOLE(&GPIOR1); /* * This small section tells simavr to generate a VCD trace dump with changes to these * registers. * Opening it with gtkwave will show you the data being pumped out into the data register * UDR0, and the UDRE0 bit being set, then cleared */ const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { { AVR_MCU_VCD_SYMBOL("UDR3"), .what = (void*)&UDR3, }, { AVR_MCU_VCD_SYMBOL("UDRE3"), .mask = (1 << UDRE3), .what = (void*)&UCSR3A, }, { AVR_MCU_VCD_SYMBOL("GPIOR1"), .what = (void*)&GPIOR1, }, }; volatile uint8_t cnt = 0; volatile uint8_t done = 0; static int uart_putchar(char c, FILE *stream) { uint8_t startcnt; if (c == '\n') uart_putchar('\r', stream); loop_until_bit_is_set(UCSR3A, UDRE3); startcnt = cnt;
#include <avr/io.h> #include <util/delay.h> /* * This demonstrate how to use the avr_mcu_section.h file * The macro adds a section to the ELF file with useful * information for the simulator */ #include "avr_mcu_section.h" AVR_MCU(F_CPU, "atmega328p"); AVR_MCU_SIMAVR_CONSOLE(&GPIOR0); const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { { AVR_MCU_VCD_SYMBOL("DDRB"), .what = (void*)&DDRB, }, { AVR_MCU_VCD_SYMBOL("PORTB"), .what = (void*)&PORTB, }, }; int main (void) { DDRB |= _BV(DDB0); const char *s = "Hello World\r"; for (const char *t = s; *t; t++) GPIOR0 = *t; while(1) { PORTB ^= _BV(PB0); _delay_ms(100); }
* This demonstrates how to use the avr_mcu_section.h file. * The macro adds a section to the ELF file with useful information for the simulator. */ #include "avr_mcu_section.h" AVR_MCU(F_CPU, "atmega88"); /* * This small section tells simavr to generate a VCD trace dump with changes to these registers. * Opening it with gtkwave will show you the data being read & written to these It also demonstrate * how you can use unused pins to generate your own traces, with your own events to be displayed. * * Here the port B first 2 bits are used to display when a tick occurs, and when a TCNT reset * occurs. */ const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { { AVR_MCU_VCD_SYMBOL("TCNT1L"), .what = (void*)&TCNT1L, }, { AVR_MCU_VCD_SYMBOL("TCNT1H"), .what = (void*)&TCNT1H, }, { AVR_MCU_VCD_SYMBOL("tick"), .mask = (1 << 0), .what = (void*)&PORTB, }, { AVR_MCU_VCD_SYMBOL("reset_timer"), .mask = (1 << 1), .what = (void*)&PORTB, }, { AVR_MCU_VCD_SYMBOL("OC2A"), .mask = (1 << 3), .what = (void*)&PORTB, }, }; volatile uint16_t tcnt; ISR(TIMER2_COMPA_vect) // handler for Output Compare 2 overflow interrupt { // this really doesn't no anything but proves a way to wake the main() from sleep at regular // intervals PORTB ^= 1; }
#include <avr/sfr_defs.h> #include <avr/io.h> AVR_MCU(1000000UL, "atmega328"); // +-\/-+ // PC6 1| |28 PC5 (AI 5/*D19) // (D 0) PD0 2| |27 PC4 (AI 4/*D18) // (D 1) PD1 3| |26 PC3 (AI 3/*D17) // (D 2) PD2 4| |25 PC2 (AI 2/*D16) // PWM+ (D 3) PD3 5| |24 PC1 (AI 1/*D15) // (D 4) PD4 6| |23 PC0 (AI 0/*D14) // VCC 7| |22 GND // GND 8| |21 AREF // *(D20) PB6 9| |20 AVCC // *(D21) PB7 10| |19 PB5 (D 13) // PWM+ (D 5) PD5 11| |18 PB4 (D 12) // PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM // (D 7) PD7 13| |16 PB2 (D 10) PWM // (D 8) PB0 14| |15 PB1 (D 9) PWM // +----+ // const struct avr_mmcu_vcd_trace_t _mytrace[1] _MMCU_ = { //{ AVR_MCU_VCD_SYMBOL("D4"), .mask = 0b001000, .what = (void*)&PORTC, }, //{ AVR_MCU_VCD_SYMBOL("D5"), .mask = 0b000100, .what = (void*)&PORTC, }, { AVR_MCU_VCD_SYMBOL("D6"), .mask = 0b000010, .what = (void*)&PORTC, }, //{ AVR_MCU_VCD_SYMBOL("D7"), .mask = 0b000001, .what = (void*)&PORTC, }, //{ AVR_MCU_VCD_SYMBOL("Enable"), .mask = 0b100000, .what = (void*)&PORTC, }, //{ AVR_MCU_VCD_SYMBOL("RegSelect"), .mask = 0b010000, .what = (void*)&PORTC, }, };