[ Log In ]
Image of the Atmega324p

Atmega324P

$8.50
Qty:
Serial to USB converter with Micro USB cable

USB to Serial Converter

$10.95
Qty:
Thumbnail: Crystal Oscillator 18.432 MHz for UART

18.432 MHz Crystal Oscillator 18pf 30ppm

$0.94
Qty:
Thumbnail: 22 pF Capacitor

22 pF Multilayer Ceramic Capacitor

$0.43
Qty:
Thumbnail: Quartz crystal oscillator - 16 MHz

16 MHz Crystal Oscillator 20 pF Through Hole

$0.75
Qty:
Thumbnail: 4x4 keypad top view.

4x4 Keypad with Adhesive Backing

$3.80
Qty:
Thumbnail: quad buffer line driver 74HC126E

Quad Buffer Line Driver (Through Hole)

$0.69
Qty:
USB AVR programmer

USB AVR Programmer

$9.95
Qty:
3 pin slide switch

SPDT Slide Switch 3 pin 30V

$1.49
Qty:
Handheld auto range multimeter

Handheld Auto Ranging Digital Multimeter

$17.95
Qty:
Skip Navigation Links

Microcontroller - A Beginners Guide - Passing a String to the LCD using Pointers

We had a great way of displaying characters to the display and controlling the display to do what we want, so why would we need to do anything else? If we needed to send one character at a time, the programming would be very tidious. We also wouldn't have a good way to display numbers. So, let's enhance the program to display a lot of characters using a single command.

How will the program work? We will first introduce the string of characters in a command, like this:

Send_A_String("NewbieHack.com");. We will need to make the program traverse through the string of characters. We have a few options on how to do this. We could store the string into an array of characters, and then create a loop to traverse through the array, displaying each character. But, we already know a little bit about how to use arrays. Let's challenge ourselves and use pointers. Pointers may actually start to creep into the intermediate level of programming, but there is no reason we can't use the pointer for this operation.

Pointers pretty much describe itself. It points. The pointer will accept memory addresses, but they return the value of the data in that memory address. That is to say, they point to memory locations "see the value" instead of containing the value. In the video, I use the analogy of comparing memory addresses to the addresses of houses in a city. Each memory location must contain an address (similar to the address of a house). You can store data in these memory locations. So, let's say, we store a string of characters like "NewbieHack.com" in memory and we tell the pointer to point at this string of characters. Initially, this pointer will be pointing to the "N" in the string. If you increment the pointer by one (1), it will point to the "e". Doing this for each character, you will eventually get to the end, which is populated by a 0, or null. The null character, or "0" informs us where we may be able to stop the loop as we travers through the string.

The pointer looks just like a standard variable, but with one minor difference. The pointer uses the asterisk (*) character before the variable. For example, using the char data type, a standard declaration of a variable may be: char aCharacter = 0x41;. The 0x41 is an ASCII (American Standard Code for Information Interchange) code and represents the "A" character. The "aCharacter" is the variable that has the data type of "char". If we put an * just before the variable (can also be located just after the data type), then the variable becomes a pointer.

So, we know what the command may look like: Send_A_String("NewbieHack.com");. What might the routine look like to send each character to the display? It will contain a loop that checks for the end of the string, and the pointer will be incremented with the unary operator "++" at the end. Remember, the ++ is just a shortcut to increment a variable. It might look like this: aValue++; Ours will have an asterisk, so it may look like this: *aPointer++; Don't let the variable name confuse you, it can be almost anything. So, here is what the routine may look like:

void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}

Wow, that's a very short routine. This is the benefit of using pointers. When you send the command: Send_A_String("NewbieHack.com");, the string "NewbieHack.com" automagically gets stored in a memory location of the microcontrollers choosing, but we HUMANS don't have the slightest clue as to this memory location. That's why the MAN created pointers!! thank heavens for the pointer, because, now you can just increment this pointer and it will point to each of the characters and inform the HUMAN of the contents of each of these memory locations. The really cool thing is that all of this happens in the Send_A_Character() command. Inside those beautiful parenthesis. Notice the asterisks riddled throughout the routine.

Here is what the full program may look like:

include <avr/io.h>
#include <util/delay.h>

#define MrLCDsCrib PORTB
#define DataDir_MrLCDsCrib DDRB
#define MrLCDsControl PORTD
#define DataDir_MrLCDsControl DDRD
#define LightSwitch 5
#define ReadWrite 7
#define BiPolarMood 2
void Check_IF_MrLCD_isBusy(void);
void Peek_A_Boo(void);
void Send_A_Command(unsigned char command);
void Send_A_Character(unsigned char character);
void Send_A_String(char *StringOfCharacters);

int main(void)
{
DataDir_MrLCDsControl |= 1<<LightSwitch | 1<<ReadWrite | 1<<BiPolarMood;
_delay_ms(15);

Send_A_Command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(2);
Send_A_Command(0x38);
_delay_us(50);
Send_A_Command(0b00001110);
_delay_us(50);

Send_A_String("NewbieHack.com");

while(1)
{
}
}

void Check_IF_MrLCD_isBusy()
{
DataDir_MrLCDsCrib = 0;
MrLCDsControl |= 1<<ReadWrite;
MrLCDsControl &= ~1<<BiPolarMood;

while (MrLCDsCrib >= 0x80)
{
Peek_A_Boo();
}

DataDir_MrLCDsCrib = 0xFF; //0xFF means 0b11111111
}
void Peek_A_Boo()
{
MrLCDsControl |= 1<<LightSwitch;
asm volatile ("nop");
asm volatile ("nop");
MrLCDsControl &= ~1<<LightSwitch;
}

void Send_A_Command(unsigned char command)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = command;
MrLCDsControl &= ~ ((1<<ReadWrite)|(1<<BiPolarMood));
Peek_A_Boo();
MrLCDsCrib = 0;
}

void Send_A_Character(unsigned char character)
{
Check_IF_MrLCD_isBusy();
MrLCDsCrib = character;
MrLCDsControl &= ~ (1<<ReadWrite);
MrLCDsControl |= 1<<BiPolarMood;
Peek_A_Boo();
MrLCDsCrib = 0;
}

void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}

If all of this code looks confusing to you, you may want to check out the earlier tutorial.