This tutorial brings you on getting working with 4-digit (4X8) segment LCD present in KL46Z freedom board and demonstrate Time in Minutes and Seconds.
We will use the Freescale’s new Kinetis Design Studio Based on free, open-source software including Eclipse, GNU Compiler Collection (GCC), GNU Debugger (GDB), with an Eclipse Integrated Development Environment (IDE) for developing embedded applications targeted at the range of Freescale Kinetis MCUs based on ARM Cortex-M technology.
Download link:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=KDS_IDE&fpsp=1&tab=Design_Tools_Tab
So let’s start in creating a new project using KDS IDE
Open KDS IDE by double clicking the KDS icon present in your desktop:
It will ask for the Workspace, give the path of your choice and click ‘ok’
After opening you can see the KDS welcome window as shown here
Create a New project as shown below:
File -> New -> Kinetis Design Studio Project
Choose project name of your choice, i have given it as “Timer in secs_mins-KL46”
Select Device “MKL46Z256xxx4” from the filter as shown
Kinetis L -> MKL4x->KL46Z(48 MHz) -> MKL46Z256xxx4
Now select the option “Use Processor Expert for configuration” and uncheck “Use Kinetis SDK for headers, drivers” and click finish.
You can see the progress bar creating all required header files and libraries..Etc
After completion you can see below project window
Click on CPU, you can see the clock settings, i am using the default settings as shown below i.e the clock source is from internal oscillator with reference clock of 32.768 KHz and Fast internal reference clock is 4 MHz as shown below.
Since now our project skeleton is ready (i.e no component module peripherals has been added to our project), we need to add the required peripheral component modules for our LCD Timer project.
LCD connection details
Refer to my earlier blog on “[FRDM-KL46Z - PE - CW] Tutorial: Display easily on a Segment LCD” to understand the working on Segment LCD.
Connection details of Luminex LCD-S401M16KR
And the display’s elements are illustrated below according to their references in the connection table in the original data sheet:
In order to configure the SLCD driver to match this display 4 of its LCD pins are configured as COM drive pins and 8 as segment drive pins. The COM drive pins are configured to drive in different phases (eg. COM0 in phase 1, COM1 in phase 2, COM2 in phase 3 and COM3 in phase 4, where each of the phases are repeated according to ¼ duty driving mode). The duty mode and any other specific configuration are also set in the SLCD controller.
Now we need to add a LCD component available in Processor Expert to operate the LCD screen embedded on the board.
FRDM-KL46Z is using a 4 digit display (LUMEX LCD-S401M16KR) 4x8 segments. Following table shows connection from KL46 board to s401 LCD display and same configuration need to be assigned to the port pins.
s401 pin | Pin connection | KL46 LCD Pin |
1 | (COM0) | LCD_P40 |
2 | (COM1) | LCD_P52 |
3 | (COM2) | LCD_P19 |
4 | (COM3) | LCD_P18 |
5 | (1D/1E/1G/1F) | LCD_P37 |
6 | (DP1/1C/1B/1A) | LCD_P17 |
7 | (2D/2E/2G/2F) | LCD_P7 |
8 | (DP2/2C/2B/2A) | LCD_P8 |
9 | (3D/3E/3G/3F) | LCD_P53 |
10 | (DP3/3C/3B/3A) | LCD_P38 |
11 | (4D/4E/4G/4F) | LCD_P10 |
12 | (COL/4C/4B/4A) | LCD_P11 |
Components selection:
Select in the Components Library view the LCD module available in Component Library > Logical Device Driver > Display > SegLCD_LDD and add it to project by double clicking as shown below:
Select the SegLCD1:SegLCD_LDD in the Components view and switch to the Component Inspect view to enter the parameter (a red cross on the component module indicates that parameters are missing)
Base clock must be defined as 1.024kHz
A new window will appear with Possible settings
Double click on the 1.024kHz and press OK to fill-in the field in the Component Inspector window.
Next click on ‘Interrupt service/event’ and uncheck if it is enabled as shown:
LCD component has Backplane pins and Frontplane pins, as there are 4 Backplane pins, which are common pins connected to LCD com0, com1, com2, com3 pins.
Increase Backplane pins up to 4 by clicking on the +
Expand the Backplane pins menu by clicking on the white arrow and assign corresponding port pins (refer to the KL46 LCD Pin table mentioned earlier) to the Backplane pins:
Backplane pin0 / Backplane pin > LCD_P40
Backplane pin 1 / Backplane pin > LCD_P52
Backplane pin 2 / Backplane pin > LCD_P19
Backplane pin 2 / Backplane pin > LCD_P18
Increase Frontplane pins up to 8 by clicking on the +
Now similarly, define the 8 segment pins corresponding to the Frontplane pins in KDS with following assignments:
Frontplane pin0 / Frontplane pin > LCD_P37
Frontplane pin1 / Frontplane pin > LCD_P17
Frontplane pin2 / Frontplane pin > LCD_P7
Frontplane pin3 / Frontplane pin > LCD_P8
Frontplane pin4 / Frontplane pin > LCD_P53
Frontplane pin5 / Frontplane pin > LCD_P38
Frontplane pin6 / Frontplane pin > LCD_P10
Frontplane pin7 / Frontplane pin > LCD_P11
Auto initialization must be checked in check box
If you follow carefully the instructions above you should get a green tick on the SegLCD1:SegLCD_LDD component in the Components view of your project.
Now as we are implementing Time in mins and secs we need a Periodic interrupt for 1000ms, so select component “TimerInt” from “CPU Internal Peripheral” section as shown below:
Double click or right click and select Add to Project
Now since TimerInt is a hardware resource we selected, it has a referenced component ‘TimerUnit_LDD’ as shown below.
We need to configure the settings for TimerInt component to generate 1 second interrupt so we are selecting source to be LPTMR0_CMR
By clicking to icon enter Interrupt period as 1000 ms
Next click on initialization and click on Enabled in init code as shown:
After this settings are made the component will be tick marked as correct symbol as shown below:
Software drivers are required for communication between LCD controller and LCD screen and manage the display. You can write your own driver or use Freescale existing drivers.
To get the Freescale LCD drivers, simply download the Sample Code Package KL46Z_sc.exe from the FRDM-KL46Z product page in the download tab.
You will find a LCD folder following the path kinetis_kl46_sc_rev2\klxx-sc-pex\cw\FRDM-KL46z-PEx-sLCD\Sources\LCD which contains *.C files and *.h files as shown below:
Copy these files and paste in the KDS Projects view in the Sources folder as shown below:
Now our all the components and drivers are ready Next click on generate icon as shown below:
You can see the tool generates required code as shown below:
All the required header files will get generated under ‘Generated_Code’
As we are using ‘TimerInt’ component in interrupt mode to generate 1 sec interrupt we need to define the action required in ISR() which is present in Events.c file as shown below:
int second=0;
void TI1_OnInterrupt(void)
{
/* Write your code here ... */
second++;
}
In ISR on every event trigger we are incrementing the “second” variable and we are declaring this as global variable so that we can access this in our main program.
Next open the main.c file available in the Sources folder from the KDS Project view and write/paste the below lines of code:
#include"Cpu.h"
#include "Events.h"
#include "SegLCD1.h"
#include "TI1.h"
#include "TimerIntLdd1.h"
#include "TU1.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "LCD.h"
/* User includes (#include below this line is not maintained by Processor Expert) */
/*lint -save -e970 Disable MISRA rule (6.3) checking. */
static LDD_TDeviceData *MySegLCDPtr;
extern int second; // global variable defined in Events.c for ISR
int secmin, minute=0, val;
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
/* Write your local variable definition here */
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
/* For example: for(;;) { } */
MySegLCDPtr = SegLCD1_Init(NULL); //initialize sLCD according to PEx
unsigned char lcdBuf[sizeof("1234")];
_LCD_COL_ON(); /* : between digit two and three */
for(;;){
secmin=second+minute;
sprintf(lcdBuf,"%04i",secmin);
vfnLCD_Write_Msg(lcdBuf);
if (second>=60) { /* can only display 4 digits */
second=0;
minute=minute+100;
}
if(minute>=10000){
minute=0;
second=0;
}
}
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
/* END main */
/*!
** @}
*/
/*
** ###################################################################
**
** This file was created by Processor Expert 10.4 [05.09]
** for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/
In my project i am displaying the Time in minutes from 00 to 99 mins which are on left side last 2 digits in the LCD display, and on the right side 2-digits will display seconds i.e from 00 to 60 secs.
Explaination of code:
for(;;){
secmin=second+minute;
sprintf(lcdBuf,"%04i",secmin);
vfnLCD_Write_Msg(lcdBuf);
if (second>=60) { /* can only display 4 digits */
second=0;
minute=minute+100;
}
if(minute>=10000){
minute=0;
second=0;
}
}
I have created 3 main variables second, minute, and secmin to store the time values seconds, minutes and the append value.
Based on timer interrupt set value (1seconds) the variable ‘second’ will be incremented every time when interrupt occurs and in the infinite for loop we are checking if ‘second’ is greater than or equal to 60 its value is reset to ‘0’
The variable ‘secmin’ is to meant add minute value and second value to display together.
As minute is displayed in MSB 2-digits of LCD and it should get reset to ‘0’ once it crosses the value 10000
vfnLCD_Write_Msg((uint8 *)sLCDBuffer)
writes the character to digits of LCD this function is defined in LCD.c file in driver.
sprintf(sLCDBuffer,"%04i",i)
is writing the integer value ‘i’ into char buffer sLCDBuffer array and ‘%04i’ is limiting the buffer value display to 4-digits
Example:
second | if second>=60, | minute | if minute>=10000, | secmin | lcdbuf |
0 |
| 0 |
| 0 | 00:00 |
1 |
| 0 |
| 1 | 00:01 |
2 |
| 0 |
| 2 | 00:02 |
59 |
| 0 |
| 59 | 00:59 |
0 |
| 100 |
| 100 | 01:00 |
55 |
| 100 |
| 155 | 01:55 |
60 | 0 | 500 |
| 600 | 06:00 |
30 |
| 900 |
| 930 | 09:30 |
22 |
| 1000 |
| 1022 | 10:22 |
60 | 0 | 5000 |
| 5060 | 50:60 |
43 |
| 9000 |
| 9043 | 90:43 |
25 |
| 9900 |
| 9925 | 99:25 |
60 | 0 | 9900 |
| 0000 | 00:00 |
59 |
| 10000 | 0 | 0059 | 00:59 |
First save the project selecting File > Save All
OpenSDA Driver
We will now test the project on the FRDM-KL46Z board. Before building the project we need to configure the board for Debugging
Make sure that the board is loaded with MSD-DEBUG-FRDM-KL46Z48M_Pemicro_v114.SDA opensda driver file, if not follow below procedure:
Before launching the debug session, you need to setup your FRDM-KL46Z with the OpenSDA P&E Debug interface.
To ensure a proper detection, download the P&E Windows USB drivers available at www.pemicro.com/opensda and install it. At the same time download the P&E Firmware Apps package.
Keep the Reset button while connecting the USB cable to SDA Connector (bottom one below) to enter in Bootloader mode.
From your file explorer drag’n drop or copy-paste in the BOOTLOADER drive the configuration file MSD-DEBUG-FRDM-KL46Z48M_Pemicro_v114.SDA available in the P&E Firmware Apps package.
Unplug and replug the USB cable
Windows should detect new peripherals (PEMicro OpenSDA Debug Driver, FRDM-KL46Z Mass Storage drive, OpenSDA CDC Serial Port) and automaticaly install the right drivers.
Debug configuration
Now we need to configure debug settings for the board.
To configure the board in KDS tool open Debug Configuration as shown below:
Debug configuration window opens select “GDB PEmicro interface debugging” right click and select option ‘New’
Then automatically the project “Timer in secs_mins-kl46” gets selected as shown below, further make sure you select the current project name in ‘Project’ field
and corresponding elf file in C/C++ Application field as shown below:
Now select Degugger tab as shown below:
Now drop down the ‘Interface’ field to select the exact USB debug port as shown and select “OpenSDA Embedded Debug-USB Port“
In the port field you can see the OpenSDA driver gets detected if not able to see this make sure you have connected the board to SDA usb port and click on ‘Refresh’ button.
Next select the Device name as shown below our target MCU is KL46Z256M4 and select Apply and close.
Now the board is configured and detected in KDS and its ready for execution.
Build and Run the project
First save the project selecting File > Save All
Clean and Build the project by right clicking the project folder “Timer in secs_mins-KL46” as shown below:
Compile the project using Project > Build All or clicking on the icon available in the toolbar.
Now enter the debug session by selecting Run > Debug Configuration. Click on “Timer in secs_mins-KL46 Debug” and select Debug as shown below.
The debug window will open, click on the Resume button from the toolbar to launch the debug session.
You can now watch the LCD Segment of your FRDM-KL46Z which displays minutes and seconds as shown below
I have enclosed the project folder and video output execution for quick reference.