Hardware Connections
The first step to prototyping any kind of system is to set up connections from the microcontroller to each component and to check that each one works in the way you want them to. In the case of this project the components I need to test are:
- The Nokia 5110 lcd display
- 2 Potentiometers and a button that represent a joystick
- A further 2 buttons (Button A and Button B)
- A green LED
- A piezo-electric buzzer (Cannot be tested currently as it is not currently available)
First and foremost the LCD display uses an SPI protocol(serial peripheral interface to transfer information to and from the FRDM-K64FFRDM-K64F microcontroller using selected SPI compatible pins In ordinary SPI configurations both MOSI(Master out slave in and MISO(Master in slave out pins can be used to transfer data from and to the microcontroller respectively however I have only used MOSI in this case as I will only be using the SPI protocol to transfer data to the lcd but not back Further connections needed are+3.3V GND SCE(serial chip enable and SCLK(serial clock as the SPI protocol is synchronous
The pinout diagram for this microcontroller can be found below. Note that only one set of pins exist to assist with SPI, this is because the SPI protocol is widely used to communicate between multiple components using the same SCLK, MOSI and MISO pins. The large difference between SPI and the popular I2C protocol is that SPI uses Serial Chip Enable (SCE) to specify which component should listen to the instructions meaning one more digital connection is needed for each component, whereas I2C uses only a clock line and a data line and uses addresses to differentiate between multiple components using the same buses.
The other components use simple digital or PWM pins, all of which are displayed on the connections diagram below.
The +3.3V connections will come from the microcontroller but for the purposes of keeping the diagram clear these connection have been ommited. The same applies to ground connections.
In the following steps I have used a pre-built library for interfacing with the LCD display so the code reflects this. The testing code used can be found here: https://developer.mbed.org/users/el14jw/code/InitialHardwareConnectionChecking/. Please note that a lot of the code written in this project cannot be uploaded due to the possibility of it being plagiarized, this initial code however is freely available due to anybody who knows how to google basic C terminology being able to reproduce it.
The pin connections for my project can be found in the System Architecture Block diagram and also displayed is my approximate PCB layout for all the components in this project.
Step 1 - Getting the LCD to work
I will be using the lcd display to check if the other components are working so it makes sense to test if that works correctly first. Using the 5110 library I wrote code that prints out a splash screen saying "Hello World!" as a string. After uploading this binary file to the K64F and resetting it the display showed some random pixels as on for a short period of time before clearing them and printing "Hello World!" on the first line. This problem was easily solved by adding a small delay after first initializing the display thereby giving it enough time to initialize before communicating with it.
Step 2 - PWM with LED
The green LED is being used as a power indicator and so to preserve power it has a PWM signal with relatively low duty cycle (25%) making it dim but visible. The syntax for dealing with PWM signals on the K64F as follows:
PwmOut <objectName>(<address of pin>);
<objectName>.period = <period>
<objectName> = <duty cycle>
Example:
PwmOut g_led(PTC11);
g_led.period(0.001); // Frequency of 1kHz
g_led = 0.25; // Duty cycle of 0.25
Step 3 - Buttons and Potentiometers
I have replaced the lcd testing code with a splash screen that says "Calibrating, do not move joystick" as this is an ideal time to get an average value for the potentiometers that act as the joysticks x and y axes. The next step is to create the data structures to deal with polling the x and y potentiometers as well as the joystick button. A struct is used to contain information about the centered x and y potentiometer values, the current x and y potentiometer values, the state of the button and the current direction represented as an enumerated type.
struct JoyStick {
float x; // current x value
float x0; // 'centred' x value
float y; // current y value
float y0; // 'centred' y value
int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
DirectionName direction; // current direction
};
Now it is the simple case of getting the centered x and y values at startup and creating a "Ticker" which is a time based interrupt to poll each of the components at a time interval we specify, in this case 10 times a second. The potentiometers information must then be dealt with to give us the direction the "joystick" has been pressed. This is all done in the interrupt service routines so meanwhile the code has been woken up from sleeping in the while(1) loop and checks to see if any of the interrupt flags are set, in which case it prints the relevant information to the lcd display. A further two event based interrupts can be used with button A and button B rather than polling them to save power and also make the acquisition of the states of the buttons more accurate. The states of these buttons are also displayed on the lcd as a string saying which button was pressed last.
Step 4 - Uploading and Testing the code
It is a good idea the test the code regularly even if this means just trying to compile it and then carrying on as this will reveal any of the mistakes you have made and how many pesky semi-colons have slipped through your fingers. The code when uploaded to the K64F displayed the relevant data. Included are the physical setup of the breadboard and microcontroller prototype.
Top Comments