Fast PWM simulation using ATmega8A and Timer/Counter2

Preparing files

We're going to prepare all the necessary files in order to run firmware to generate PWM signal using Timer/Counter2 of the ATmega8A microcontroller in this example. We'll need these files and programs to be available or pre-installed:

  • mcusim
  • firmware file (Intel HEX format, for ATmega8A)
  • GTKWave (traces viewer, something similar to a logic analyser)

First of all, we'll need an additional directory to keep all our files in:

# mkdir ~/pwm-simulation

There is a firmware file firmware.hex compiled from main.c (available in archive attached to the page). It's a time to generate a run script for mcusim using mcusim-config:

# cd ~/pwm-simulation
# mcusim-config

Generate a run script

It is an interactive script which will ask you to provide some details (including MCU model, firmware file, etc). We're going to simulate ATmega8A (model is m8a, type mcusim -p ? to get all available models) running at 16 MHz with firmware file firmware.hex and I/O registers TCNT2,OCR2,TIFR6,PORTB3 dumped into VCD file:

	Directory to save configuration script in [ /home/dsl ]: .
	Name of the script [ start-avr ]: run-pwm
	Microcontroller [ m8 m8a m328 m328p m2560 ]: m8a
	Path to firmware (Leave empty to skip): firmware.hex
	Do you want to perform additional configuration? [y/N]: y
	Frequency (in Hz, leave empty for default): 16000000
	High fuse byte (leave empty for default): 0xC9
	Low fuse byte (leave empty for default): 0xEF
	Do you want I/O registers to be dumped? [y/N]: y
        Do you want to set up a firmware test? [y/N]: y

We'll receive a run-pwm script generated. However, we'll need our simulation to be terminated after, say, 400,000 clock cycles. Let's write a simple stop-test.lua to do this and modify run-pwm to load our script before simulation:

ticks_passed = 0

function module_tick(mcu)
        if ticks_passed > 400000 then
                -- Test finished successfully
                MSIM_SetState(mcu, AVR_MSIM_STOP)
                print("[Test stopper] ticks passed: " .. ticks_passed)

        ticks_passed = ticks_passed + 1

MODELS variable of run-pwm should be modified to contain name of the script:

# Append models to the list in order to load them during simulation.

Dump traces

It's a time to run run-pwm and dump traces into ATmega8A-trace.vcd:

# ./run-pwm
mcusim 0.1.75 - microcontroller-based circuit simulator <>
[I]: Model ./stop-test.lua doesn't provide configuration function: attempt to call a nil value
                  Model: ATmega8A
              Signature: 1E937
        Clock frequency: 16000.0 kHz
         Program memory: 0x0-0xFFF words
     Bootloader section: 0xC00-0xFFF words
            Data memory: 0x60-0x45F bytes
                 EEPROM: 0x0-0x1FF bytes
                     PC: 0x0 word
          Reset address: 0x0 word
Interrupt vectors table: 0x1 word
[Test stopper] ticks passed: 400001
# ls -lah
drwxr-xr-x   2 dsl  wheel     8B Jun 15 10:15 .
drwxr-xr-x  26 dsl  wheel    59B Jun 15 10:13 ..
-rw-r--r--   1 dsl  wheel    14M Jun 15 10:15 ATmega8A-trace.vcd
-rw-r--r--   1 dsl  wheel   664B May 20 22:46 firmware.hex
-rw-r--r--   1 dsl  wheel   4.0K May 20 22:46 firmware.hex.txt
-rw-r--r--   1 dsl  wheel   1.1K Jun 14 19:18 main.c
-rwxr-xr-x   1 dsl  wheel   2.5K Jun 15 10:14 run-pwm
-rw-r--r--   1 dsl  wheel   244B Jun 15 09:39 stop-test.lua

We'll have a PWM signal generated on a third pin of Port B (PORTB3 in VCD). Resulted file will look in GTKWave like:

We may compare simulation result with a real oscillogram obtained from ATmega8A with exactly the same firmware uploaded:

Last modified 5 weeks ago Last modified on Oct 10, 2018, 11:12:56 AM

Attachments (5)

Download all attachments as: .zip