Ryan Robucci
MPLAB® XC8 C Compiler User’s Guide for AVR® MCU
https://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB XC8 C Compiler UG for AVR MCU 50002750C.pdf
SCL User Guide:
file:///opt/microchip/mplabx/v5.50/mplab_platform/mplab_ide/modules/docs/SCL_Users_Guide/index.html
Usage as reported by debugger:
Report using size command:
robucci@sensi:~/MPLABXProjects/discussion05.X/dist/default/production$ /opt/microchip/xc8/v2.32/avr/bin/avr-size discussion05.X.production.elf
text data bss dec hex filename
460 108 0 568 238 discussion05.X.production.elf
Next I add a compile option to disable the default behavior in this tool of placing static constants in program memory:
-mno-const-data-in-progmem
And this is the new result:
text data bss dec hex filename
438 112 0 550 226 discussion05.X.debug.elf
What happened?
IN THIS SYSTEM, THE DEFAULT IS THAT constants are stored and accessed from program memory.
In older versions of the compiler, macros and directive were required to place constants, including constant literal strings in program memory:
https://www.csee.umbc.edu/~alnel1/cmpe311/discussions/Discussion6.pdf
https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
Find the -mno-const-data-in-progmem
option in the compiler user manual:
MPLAB® XC8 C Compiler User’s Guide for AVR® MCU
https://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB XC8 C Compiler UG for AVR MCU 50002750C.pdf
Connection of LCD Array
AVR Butterfly Evaluation Kit:
http://ww1.microchip.com/downloads/en/devicedoc/doc4271.pdf Section 3.4 LCD Display
AVR065: LCD Driver for the STK502
Array of segments available on LCD Glass Pannel on AVR (similar to STK502 devkit)
Register/bit map for controlling characters
Goto file U0_LCD_Driver.c and note this line:
0x2A80, // '+'
How does 0x2A80 correspond to +, according to the bit mapping?
Seems to help with debugging while using stdio
//file:simple.c //author: Robucci #include <avr/io.h> void bubble4(volatile int arr[]){ int i; int tmp; for (i=0;i<3;i++){ if (arr[i+1]>arr[i]){ if (PINB){ tmp=arr[i]; arr[i]=arr[i+1]; arr[i+1]=tmp; } } } } int main(){ DDRB=0x0F; int arr[]={0xFF,10,30,40}; arr[0]=50; int i; while(1){ for (i=0;i<3;i++){ arr[i++]=PINA; bubble4(arr); PORTB=arr[i++]; } }; }
#mdb.cmd device atmega169p # for hw set AutoSelectMemRanges auto set communication.speed 1.00 set memories.programmemory true #for sim set oscillator.frequencyunit None set oscillator.frequency 8000000 set breakoptions.stimulusmessages.notes Report set codecoverage.enabled Disable #hwtool sim set communication.interface jtag hwtool snap program ./a.out # may need the following for sim # upload rest #reset MCLR Sleep 1500 #watch PORTB W #stim stim.scl #b main #run
Compile program
/opt/microchip/xc8/v2.32/bin/xc8-cc -mcpu=atmega169p -Wall -O0 -g simple.c
Start gdb
sudo /opt/microchip/mplabx/v5.50/mplab_platform/bin/mdb.sh mdb.cmd
Commands to run:
b simple.c:23
reset
run
bt full
print arr
print /a arr
b bubble4
run
list
stepi
list
bt full
x 256
example command
>bt full ?
#0 main () at /home/robucci/GIT/cmpe311/mdb/first_c/simple.c:13
arr =
Note: if running on the simulator, this command is useful
stopwatch
print arr seems to fail. it seems that a mapping or linker file might be needed, but the memory can be seen with x
Get the address of arr
>print /a arr ?
Address range starting at 256
>x /h256 256 ?
00ff 000a 001e 0028 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
(if time allows)
Tips for using program space
Using program space
AVR has a library for keeping const data in program memory (flash) and accessing it directly instead of using RAM
#include <avr/pgmspace.h>
Declare const strings using special flag PROGMEM
//PROGMEM used to locate a variable in flash ROM
const PROGMEM char myString[] = "Repeated Use";
you can create special pointers using PGM_P and access the data using a
special macro pgm_read_byte
Documentation is available online
PGM_P progPtr; progPtr =myString; //Somewhere in your code while(pgm_read_byte(progPtr)!=’\0’){ printf("%c",pgm_read_byte(progPtr)); progPtr++; }
#include <avr/pgmspace.h> void lcd_puts_P(const char c[]) { //same const char *c uint8_t ch = pgm_read_byte(c); while(ch != 0) { lcd_putc(ch); ch = pgm_read_byte(++c); } } // Usage: Note PSTR macro which simplifies placing string // literals in flash ROM // Code: lcd_puts_P(PSTR("Hello World")); // Or: const PROGMEM char SOME_STRING[] = "Repeated Use"; // lcd_puts_P(SOME_STRING)