|
Lets have some practice and write simple AVR LCD menu routine. For this we need to write LCD control library. I decided not to use one from AVRLIB. LCD controlling isn't difficult just a few lines of code unless you want to make it more universal. I want to demonstrate how LCD menu control may look. Of course this isn't the best practice as it uses pretty simple logic, but may do the job. To make it interesting I am going to have 4 buttons: 2 for menu scrolling up and down and two for changing submenu parameters. As output I am going to use three LED diodes that will light according to parameters selected in menu. Button states are going to be read using timer0 overflow interrupts. Code is written for WinAVR compiler.
First of all construct a circuit: 
I have excluded power circuit, just left main parts: LCD, LED's and buttons connected. This circuit works well with Proteus simulator as it is. Proteus circuit is attached to project archive. My idea is to store menu strings in Flash memory without occupying MCU RAM. This way menu items are limited only by Flash memory, not by RAM. As you can see in code menu structure is pretty simple and there is many ways to optimize. Feel free to do so. Firs of all decide how many Menu items we are going to have. According to my example there are 4 menu items: //Menu Strings in flash //menu 1 const uint8_t MN100[] PROGMEM="<<One Led>>\0"; //menu 2 const uint8_t MN200[] PROGMEM="<<All ON/OFF>>\0"; //menu 3 const uint8_t MN300[] PROGMEM="<<Auto scroll>>\0"; //menu 4 const uint8_t MN400[] PROGMEM="<<Blink All>>\0"; Then we have to describe submenus: //SubMenu Strings in flash //menu 1 submenus const uint8_t MN101[] PROGMEM="R ON\0"; const uint8_t MN102[] PROGMEM="G ON\0"; const uint8_t MN103[] PROGMEM="B ON\0"; //Submenus of menu 2 const uint8_t MN201[] PROGMEM="All ON\0"; const uint8_t MN202[] PROGMEM="All OFF\0"; //Submenus of menu 3 const uint8_t MN301[] PROGMEM="Left\0"; const uint8_t MN302[] PROGMEM="Right\0"; //submenus of menu 4 const uint8_t MN401[] PROGMEM="Blink Fast\0"; const uint8_t MN402[] PROGMEM="Blink Slow\0"; Then we have to create array pointers to menu strings stored in flash: const uint8_t *MENU[] ={ MN100, //menu 1 string MN200, //menu 2 string MN300, //menu 3 string MN400 //menu 4 string //add more if more menu items are used }; const uint8_t *SUBMENU[] ={ MN101, MN102, MN103, //submenus of menu 1 MN201, MN202, //submenus of menu 2 MN301, MN302, //submenus of menu 3 MN401, MN402 //submenus of menu 4 //continue with other menu submenu strings }; These pointers are used to call proper menu string when menu/submenu item is changed. There could be different logic used, but this time I've chosen this one :) Then wee need to describe menu structure with number constants indicating how many menus and submenu items there are: const uint8_t MSTR2[] PROGMEM ={ 4, //number of menu items 3, //Number of submenu items of menu item 1 2, //of menu item 2 2, //of menu item 3 2 //of menu item 4 //enter further submenu items }; This array is stored in Flash memory. Last thing is functions. I used pointer to function. As functions are similar: //Functions for each menu item void func101(void); void func102(void); void func103(void); void func201(void); void func202(void); void func301(void); void func302(void); void func401(void); void func402(void); //...add more functions if more menu items are used It is ease to use function pointer, that can be changed during menu item change. To make things easier to manage I have created Array of function pointers in Flash const FuncPtr FuncPtrTable[] PROGMEM= { func101, func102, func103, //functions for submenus of menu 1 func201, func202, //functions for submenus of menu 2 func301, func302, //functions for submenus of menu 3 func401, func402 //functions for submenus of menu 4 //further functions... }; Using this function array I can easily point to required function with single code line: FPtr=(FuncPtr)pgm_read_word(&FuncPtrTable[MFIndex(MN.menuNo, MN.subMenuNo)]); Where MFIndex(MN.menuNo, MN.subMenuNo) function returns array index according to menu and submenu number. Download WinAVR project files (with pre-compiled hex) and Proteus model here .
Related Items:
|
Request help - code not working correct
By: avr_1950 on 12-03-2008 19:52
Dear Administrator,
I have directly used your given code for ATmega16. First modified ISR required for 1MHz, then as is used for 1 MHz in both cased the sequence does not follow the menu design but performs its own sequence. Is it possible to guide what else we have to take care of.
avr_1950
» Report this comment to administrator
» Reply to this comment...
» See all 2 replie(s)