|
|
Freescale
MC9S08QG8/4
|
|
Code
Example #11
|
2011.12.31 | ||
2012.01.01 | - recent update | |
- added LCD info | ||
- added Example 4. | ||
2012.01.13 | - Introduction to Examples | |
- added explanations, various comments | ||
- added example 5 | ||
2012.01.15 | - Global and local variables | |
- Stacks | ||
2012.01.16 | - Interrupts | |
2012.01.19 | - 7-Segment LED interface | |
2012.02.13 | - Example #10 - Four 7-segment LED multiplexed | |
2012.02.14 | - Modifications to Example #10 | |
2012.03.14 | - Examples on individual pages | |
Example #1 | Simple ASM program vs C program | |
Watchdog Memory I/O Model Page Zero Addressing Infinite Loop External Crystal |
||
Example #2 | Flashing LED |
|
Software delay | ||
Example #3 | Character Output | |
Serial Transmit Data LCD Display Function Prototypes |
||
Example #4 | Text Message | |
Characters, Strings and Pointers |
||
Example #5 | Timer test with oscilloscope |
|
Example #6 | Timer test with flashing LED | |
Gobal and Local variables Stacks Subroutines |
||
Example #7 | Timer test with flashing LED using interrupts | |
Interrupts | ||
Example #8 | Single Hexadecimal Display on 7-segment LED | |
Common Cathode Display | ||
Example #9 | Single Hexadecimal Display on 7-segment LED | |
Common Anode Display | ||
Example #10 | Four multiplexed 7-segment Common Anode LED | |
Displaying decimal digits Switch/Case statements |
||
Example #11 | Four multiplexed 7-segment Common Anode LED | |
Displaying 8-bit and 16-bit integers as hexadecimal digits | ||
Eventually, there comes the necessity and challenge to be able to determine and confirm that your program is generating correct numerical results. This can be accomplished using the DEBUG feature of your IDE (Integrated Development Environment). Sometimes the DEBUG feature cannot be used when the test must be conducted under real time operating conditions.
Multiple LEDs may not be a choice if there are no remaining input/output pins available. The solution calls for a means of displaying text (ASCII characters) transmitted to a suitable text display such as an LCD module or a PC screen. This solution is particularly efficient since it requires a single output pin on the MCU, the SCI TXD signal (Serial Communications Interface - Transmit Data), pin-11 on the MC9S08QG8 chip. This has been demonstrated in Example #4.
Here is an example of displaying an 8-bit value as two hexadecimal digits. Instead of displaying 1234, we modify the code in main( ) to replace the values in d3-d0 as follows:
d3 = 1; |
added - 2012.02.13
COMMON ANODE DISPLAYS
#include <MC9S08QG8.h>
// 4-digit COMMON ANODE LED Display
// Declare global constants
here
#define COUNT_LIMIT 61
// Declare global variables
byte Count, TimerCount;
byte d3, d2, d1, d0;
byte select;
byte Display[16];
void EnableInterrupts(void)
{
asm
{
CLI
}
}
void Init(void)
{
SOPT1 = 0x52; // disable COP watchdog
PTADD = 0b00001111; // set PTA3-0 as output
PTBDD = 0b11111111; // set PTB7-0 as output
// initialize MTIM (8-bit timer module)
// XTAL = 8MHz
// BUSCLK = 4MHz
//MTIMCLK = 0b00000000; // 4MHz = 250ns
//MTIMCLK = 0b00000001; // 2MHz = 500ns
//MTIMCLK = 0b00000010; // 1MHz = 1us
//MTIMCLK = 0b00000011; //500KHz = 2us
//MTIMCLK = 0b00000100; //250KHz = 4us
//MTIMCLK = 0b00000101; //125KHz = 8us
//MTIMCLK = 0b00000110; // 62KHz = 16us
//MTIMCLK = 0b00000111; // 31KHz = 32us
//MTIMCLK = 0b00001000; // 16KHz = 64us
// overflow every 256 x 16us = 4.096ms
// switch to new digit every 4ms
MTIMCLK = 0b00000110;
MTIMSC = 0b01000000; // Start the timer with interrupts enabled
Display[0] = 0b00111111;
Display[1] = 0b00000110;
Display[2] = 0b01011011;
Display[3] = 0b01001111;
Display[4] = 0b01100110;
Display[5] = 0b01101101;
Display[6] = 0b01111101;
Display[7] = 0b00000111;
Display[8] = 0b01111111;
Display[9] = 0b01101111;
Display[0xA] = 0b01110111;
Display[0xB] = 0b01111100;
Display[0xC] = 0b00111001;
Display[0xD] = 0b01011110;
Display[0xE] = 0b01111001;
Display[0xF] = 0b01110001;
EnableInterrupts()
}
// example of ISR for Modulo Timer Overflow
void interrupt 12 TimerISR(void)
{
byte status;
// toggle PortB bits
// read Timer Status
status = MTIMSC;
// restart Timer
MTIMSC = 0b01000000;
select = select >> 1; // shift right by one bit
if (select == 1) PTBD = ~Display[d0];
if (select == 2) PTBD = ~Display[d1];
if (select == 4) PTBD = ~Display[d2];
if (select == 0)
{
select = 0x08; // reset select for most significant digit
PTBD = ~Display[d3];
}
PTAD = select; // output digit select signal
}
void main(void)
{
Init(); // Initialize hardware
// Initialize variables
select = 0x08;
d3 = 1;
d2 = 2;
d1 = 3;
d0 = 4;
// Example of binary to hex display
// override the values in d3-d0
Count = 0xFE;
d3 = 0;
d2 = 0;
d1 = Count >> 4; // extract upper nibble
d0 = Count & 0x0F; // extract lower nibble
// Endless loop, nothing to do here for now
for(;;)
{
}
}
Notes:
Each digit is powered on for 4ms using PTA3 to PTA0. This is accomplished with
the variable select which is
outputted to PORTA on every TIMER interrupt. The TIMER interrupt routine has
been simplified since we can use the timer prescaler feature to get a suitable
interrupt frequency.
Now we show how to display a 16-bit value as four hexadecimal digits. Note that the example shown with uiCount = 0xFEDC is just an easily recognisable test pattern. We can make uiCount = 1234 or any number representation we choose. What is being displayed is in hexadecimal representation. You'll get it eventually.
// declare an new variable as unsigned
integer
unsigned int uiCount;
// Example of 16-bit binary to hex display
// override the values in d3-d0
uiCount = 0xFEDC;
d3 = (uiCount >> 12) & 0x0F;
d2 = (uiCount >> 8) & 0x0F;
d1 = (uiCount >> 4) & 0x0F;
d0 = uiCount & 0x0F;
// Endless loop, nothing to do here for now
for(;;)
{
}
I will leave it as an exercise for you to display a 16-bit integer value in the range 0 to 9999 in decimal representation.
Connect Vss to GND
2006.11.09 - 2012.03.14