Electronics ru
Advanced Search +


Four Channel PWM Controller. Part 2

In the previous part we have familiarised with the scheme of the four channel PWM controller, have considered principles of work and the basic characteristics of the device.

All of the ATMega32 software was written in assembler within the AVR Studio IDE environment. This has allowed easy simulation and debugging of the code, and quick transfer of the latest software version to the board via the AVRISP programmer.

On power-up reset, the software loads stored configuration settings from the EEPROM, loading many into SRAM for faster access should they be required. The reset routine then configures the microcontroller peripherals appropriately (these include Timer0, Timer1, Timer2, the USART, the AD converter, and port pins). Space is allocated for, and initial values set for variables and FIFO buffers. Five FIFO buffers are employed (USART receive, USART transmit, EEPROM write, Keypad key presses, and LCD data/commands) to allow multiple tasks to run efficiently and concurrently (for instance, writing a series of bytes to EEPROM, readiing incoming bytes from the USART, and displaying data on the LCD). Commonly used variables (such as configuration settings and frequently used counters) are allocated to the lower working registers of the AVR cpu (registers r0 to r15) to grant quick access to, and bitwise testing of these variables efficiently.

One main feature of the code employed in this project is that given the name ‘Ticker_Val’. This variable is incremented during the interrupt service routine caused by Timer0 overflow, and serves to count 32us time periods. By decreasing a counter by Ticker_Val, and testing for an underflow on decrement, specific time periods can be obtained. An 8-bit counter can cause an underflow condition after up to 8.1ms; a 16-bit counter can cause an underflow condition after up to approximately 2 seconds. By using Ticker_Val in conjunction with a counter, non-critical delays can be timed without holding the microcontroller in a software loop, allowing other tasks to be performed. Note that this approach was taken to delay timing because all available timers on the ATMega32 were allocated to PWM functions.

Interrupt service routines (ISRs) are used after critically important events. These events include detecting a key press on the keypad via the external interrupt pins (this ISR prevents further external interrupts until after the keypad has been scanned and the precise key pressed has been determined) and data reception via the USART (the incoming byte is placed into the USART receive FIFO). ISRs are also used to speed up serial data transmission (using the USART DRE interrupt) and EEPROM writes (using the EEPROM ready interrupt).

The main loop in the program constantly checks for tasks that need to be performed. It does this by checking sequentially the USART receive FIFO, the USART transmit FIFO, the EEPROM FIFO, and Ticker_Val updates.

If the USART FIFO contains data, one byte is read from the FIFO and acted upon. In order to ensure the correct action is taken, indirect jump (ijmp) addresses are allocated to specific states of operation, and set or reset to a default address after each byte is written. For example, if the byte DC1 (0x11) is received, the next byte contains data relevant to the controllers LCD configuration. Thus, the ijmp address for the USART receive FIFO read routine is set so that the next byte is acted upon correctly. This method of storing indirect jump addresses is used for all routines that require sequential steps to be taken. These include LCD display routines and keypad scanning routines.

If the USART transmit buffer contains data, data transmission is enabled and further checking of the FIFO is disabled until the FIFO buffer is empty. This allows for fewer cpu cycles spent redundantly checking the FIFO status. EEPROM writing from the EEPROM FIFO is handled in a similar fashion.

Ticker_Val updates require the reading and subsequent reseting of the Ticker_Val. The read value is then subtracted from a counter controlling Keypad delays, LCD data/command delays, and LCD display mode delays. An underflow on these counters calls a routine that controls the specific function.

The keypad requires approximately 20ms after a key press has been detected until a keypad scan to ensure the keys have been debounced properly. After a keypad scan, an action is taken depending on the key being pressed, and the PWM configuration. These actions may include sending key press values via the RS232 interface, or promting the user through a PWM channel control operation.

The LCD data/command routine requires delays of between 160us and 4.1ms to ensure proper operation of most alphanumeric LCD modules available. Many modern modules require shorter delays, however compatibility with older devices was deemed more important than faster LCD character writing.

An LCD display routine uses a Ticker_Val update to control the update of PWM and ADC information in the LCD. The displayed data is updated two times per second, with PWM and ADC values alternating every five seconds in cyclic display mode.

Once all Ticker_Val updates have been performed and acted upon, the program loops and begins checking the USART receive FIFO buffer again. This method of testing priority tasks first, and using the Ticker_Val technique for non-critical delays allows adequate response time for all tasks in practically any situation.


  1. Source code of the program for the microcontroller (including .HEX file for ATMega32)
  2. Control Bytes for RS232 Interface

Slices ↓
Radiolocman facebook Radiolocman twitter Radiolocman google plus