底下是接線圖 : (3.3V LCD 1602 module)
LCD1602 module 共有 16 Pins. 與 TM4C123GXL Lanchpad 的接腳如下 :
其中 LCD1602 的 Pin 3 接一個 3.9k 歐姆的電阻對地(圖上畫的是 3.3k, 那是因為沒找到 3.9k, 所以用 3.3k 代替) . 這地方是調整對比的 , 如果太暗或太亮造成看不清楚顯示的字, 可以接一個 10k 歐姆的可變電阻來調整. 接法如下 :
接下來寫一個 LCD1602 的 Driver , 方便我們使用 . 參考一下它的 Data Sheet . 在 LCD1602.h 中放我們程式函式的原型. 而 LCD1602.c 則是函式的內容 . 當要使用時 , 在我們的主程式中要加入 #include "LCD1602.h" , 並且要將 LCD1602.c 加入我們的 Project 中.
LCD1602.h :
/*********************************************************************************
**********************************************************************************
** LCD1602.h **
** 1. Support TIVA-C TM4C123GXL Launchpad **
** 2. PIN ASSIGNMENT --> RW-PA5, RS-PA6, E-PA7, D0~D7 => PB0~PB7 **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
/* Hardware connection between Launchpad and LCD1602 module
|| Lauchpad Pin <==> LCD1602 Pin
|| GND <==> Pin1
|| Vcc <==> Pin2 (3.3V)
|| GND <==> Pin3 (connect a 3.9k to GND)
|| PA6 <==> Pin4 (RS)
|| PA5 <==> Pin5 (R/W, To GND is only enable to write)
|| PA7 <==> Pin6 (E)
|| PB0 <==> Pin7
|| PB1 <==> Pin8
|| PB2 <==> Pin9
|| PB3 <==> Pin10
|| PB4 <==> Pin11
|| PB5 <==> Pin12
|| PB6 <==> Pin13
|| PB7 <==> Pin14
|| Vcc <==> Pin15, (A, connect a 330R to Vcc)
|| GND <==> Pin16, (K, connect to Ground) */
#define LINE1 0x80 //First Line of LCD1602
#define LINE2 0xC0 //Second Line of LCD1602
//********************************************************************************
//LCD1602 Initialize:
//********************************************************************************
void LCD1602_Init(void);
//********************************************************************************
//LCD1602 Clear Screen:
//********************************************************************************
void LCD1602_Clear(void);
//********************************************************************************
//LCD1602 Display String to Screen:
//********************************************************************************
void LCD1602_DisplayString(unsigned char *str);
//********************************************************************************
//LCD1602 Display Char to Screen:
//********************************************************************************
void LCD1602_DisplayChar(unsigned char CHAR);
//********************************************************************************
//LCD1602 Display Decimal number to Screen:
//********************************************************************************
void LCD1602_DisplayDec(unsigned int number);
//********************************************************************************
//LCD1602 Set Cursor Position on the Screen:
//Line : LINE1 or LINE2
//Digit : from 0 ~ 15
//********************************************************************************
void LCD1602_DisplayPosition(unsigned char Line,unsigned int digit);
LCD1602.c :
/*********************************************************************************
**********************************************************************************
** LCD1602.c **
** 1. Support TIVA-C TM4C123GXL Launchpad **
** 2. PIN ASSIGNMENT --> RW-PA5, RS-PA6, E-PA7, D0~D7 => PB0~PB7 **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
/* Hardware connection between Launchpad and LCD1602 module
|| Lauchpad Pin <==> LCD1602 Pin
|| GND <==> Pin1
|| Vcc <==> Pin2 (3.3V)
|| GND <==> Pin3 (connect a 3.9k to GND)
|| PA6 <==> Pin4 (RS)
|| PA5 <==> Pin5 (R/W, To GND is only enable to write)
|| PA7 <==> Pin6 (E)
|| PB0 <==> Pin7
|| PB1 <==> Pin8
|| PB2 <==> Pin9
|| PB3 <==> Pin10
|| PB4 <==> Pin11
|| PB5 <==> Pin12
|| PB6 <==> Pin13
|| PB7 <==> Pin14
|| Vcc <==> Pin15, (A, connect a 330R to Vcc)
|| GND <==> Pin16, (K, connect to Ground) */
#include <stdint.h>
#include <stdio.h>
#include "inc/tm4c123gh6pm.h"
#include "LCD1602.h"
#include "SYSTICK.h"
#define RW 0x20 //PA5
#define RS 0x40 //PA6
#define E 0x80 //PA7
//********************************************************************************
// LCD1602 Initial GPIO PORTB and PORTA- PA5,PA6,PA7 : GPIO_PortAB_Init()
//********************************************************************************
void GPIO_PortAB_Init(void){
volatile unsigned long delay;
//Initial PA7/PA6/PA5
SYSCTL_RCGC2_R |= 0x00000001;
delay = SYSCTL_RCGC2_R;
GPIO_PORTA_AMSEL_R &= ~0xE0;
GPIO_PORTA_PCTL_R &= ~0xFFF00000;
GPIO_PORTA_DIR_R |= 0xE0;
GPIO_PORTA_AFSEL_R &= ~0xE0;
GPIO_PORTA_DEN_R |= 0xE0;
GPIO_PORTA_DR8R_R |= 0xE0;
//Initial PB7 ~ 0
SYSCTL_RCGC2_R |= 0x00000002;
delay = SYSCTL_RCGC2_R;
GPIO_PORTB_AMSEL_R &= ~0xFF;
GPIO_PORTB_PCTL_R &= ~0xFFFFFFFF;
GPIO_PORTB_DIR_R |= 0xFF;
GPIO_PORTB_AFSEL_R &= ~0xFF;
GPIO_PORTB_DEN_R |= 0xFF;
GPIO_PORTB_DR8R_R |= 0xFF;
}
//********************************************************************************
//LCD1602 Write Commend to LCD module
//********************************************************************************
void Write_Command(unsigned char LCD_Comment){
GPIO_PORTA_DATA_R &= ~(RS+RW+E); //RS=0,RW=0,E=0
GPIO_PORTB_DATA_R = LCD_Comment; //Write Command
GPIO_PORTA_DATA_R |= E; //RS=0,RW=0,E=1
GPIO_PORTA_DATA_R &= ~(RS+RW);
SysTick_Delay(19); //Enable width 230 ns
GPIO_PORTA_DATA_R &= ~(RS+RW+E); //RS=0,RW=0,E=0
SysTick_Delay1ms(1); //Delay 1 ms
}
//********************************************************************************
//LCD1602 Write DATA to LCD module
//********************************************************************************
void Write_Data(unsigned char LCD_Data){
GPIO_PORTB_DATA_R = LCD_Data; //Write Data
GPIO_PORTA_DATA_R |= RS+E; //RS=1,RW=0,E=1
GPIO_PORTA_DATA_R &= ~RW;
SysTick_Delay(19); //Enable width 230 ns
GPIO_PORTA_DATA_R &= ~(RS+RW+E); //RS=0,RW=0,E=0
SysTick_Delay1ms(1); //Delay 1 ms
}
//********************************************************************************
//LCD1602 Initialize:
//********************************************************************************
void LCD1602_Init(){
GPIO_PortAB_Init();
SysTick_Delay1ms(15); //Delay 15ms
Write_Command(0x38);
SysTick_Delay1ms(5); //Delay 5ms
Write_Command(0x38);
SysTick_Delay1us(150); //Delay 150us
Write_Command(0x0C);
Write_Command(0x01);
Write_Command(0x06);
SysTick_Delay1ms(50); //Delay 50ms
}
//********************************************************************************
//LCD1602 Clear Screen:
//********************************************************************************
void LCD1602_Clear(){
Write_Command(0x01);
}
//********************************************************************************
//LCD1602 Display String to Screen:
//********************************************************************************
void LCD1602_DisplayString(unsigned char *str){
while(*str != 0){
Write_Data(*str++);
}
}
//********************************************************************************
//LCD1602 Display Char to Screen:
//********************************************************************************
void LCD1602_DisplayChar(unsigned char CHAR){
Write_Data(CHAR);
}
//********************************************************************************
//LCD1602 Display Decimal number to Screen:
//********************************************************************************
void LCD1602_DisplayDec(unsigned int number){
if(number >=10){
LCD1602_DisplayDec(number/10);
number = number%10;
}
LCD1602_DisplayChar(number+'0');
}
//********************************************************************************
//LCD1602 Set Cursor Position on the Screen:
//********************************************************************************
void LCD1602_DisplayPosition(unsigned char Line,unsigned int digit){
Write_Command(Line + digit);
}
//********************************************************************************
//LCD1602 support printf() function
//********************************************************************************
int fputc(int ch, FILE *f){
if((ch == 10) || (ch == 13) || (ch == 27)){
LCD1602_DisplayChar(13);
LCD1602_DisplayChar(10);
return 1;
}
LCD1602_DisplayChar(ch);
return 1;
}
接下來也整理一下之前寫過的 PLL 和 SYSTICK 部分 , 把它們改為模組化 , 如 PLL_80MHZ.c 和 PLL_80MHZ.h 以及 SYSTICK.c 和 SYSTICK.h , 那麼以後要用到就可直接加入 Project 中, 不用再重寫了 . 如下 :
PLL_80MHZ.h :
/*********************************************************************************
**********************************************************************************
** PLL_80MHZ.h **
** 1. Board : TIVA-C TM4C123GXL Launchpad **
** 2. Use PLL to set System Clock to 80MHZ **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
//********************************************************************************
// USE PLL to set system clock to 80MHZ
//********************************************************************************
//Initial PLL 80MHZ
void PLL_Init80MHZ(void);
PLL_80MHZ.c :
/*********************************************************************************
**********************************************************************************
** PLL_80MHZ.c **
** 1. Board : TIVA-C TM4C123GXL Launchpad **
** 2. Use PLL to set System Clock to 80MHZ **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
#include "PLL_80MHZ.h"
//********************************************************************************
// USE PLL to set system clock to 80MHZ
//********************************************************************************
//Initial PLL 80MHZ
void PLL_Init80MHZ(void)
{
SYSCTL_RCC2_R |= 0x80000000;
SYSCTL_RCC2_R |= 0x00000800;
SYSCTL_RCC_R = (SYSCTL_RCC_R &~0x000007C0)
+ 0x00000540;
SYSCTL_RCC2_R &= ~0x00000070;
SYSCTL_RCC2_R &= ~0x00002000;
SYSCTL_RCC2_R |= 0x40000000;
SYSCTL_RCC2_R = (SYSCTL_RCC2_R&~ 0x1FC00000)
+ (4<<22);
while((SYSCTL_RIS_R&0x00000040)==0){};
SYSCTL_RCC2_R &= ~0x00000800;
}
SYSTICK.h
/*********************************************************************************
**********************************************************************************
** SYSTICK.h **
** 1. Support TIVA-C TM4C123GXL Launchpad **
** 2. Assume System Clock is 80MHZ **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
//********************************************************************************
//Systick Initialize:
//********************************************************************************
void SysTick_Init(void);
//********************************************************************************
//Systick 12.5 ns Delay:
//********************************************************************************
void SysTick_Delay(unsigned long delay);
//********************************************************************************
//Systick 1 us Delay:
//********************************************************************************
void SysTick_Delay1us(unsigned long delay);
//********************************************************************************
//Systick 1 ms Delay:
//********************************************************************************
void SysTick_Delay1ms(unsigned long delay);
SYSTICK.c
/*********************************************************************************
**********************************************************************************
** SYSTICK.c **
** 1. Support TIVA-C TM4C123GXL Launchpad **
** 2. Assume System Clock is 80MHZ **
** 3. Michael @2014/05/10 **
** 4. Version 1.0 **
**********************************************************************************
*********************************************************************************/
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
#include "SYSTICK.h"
//********************************************************************************
// SysTick Timer Assume System clock is 80MHZ
//********************************************************************************
//********************************************************************************
//Systick Initialize:
//********************************************************************************
//Initial Systick Timer
void SysTick_Init(void){
NVIC_ST_CTRL_R = 0;
NVIC_ST_CTRL_R = 0x00000005;
}
//********************************************************************************
//Systick 12.5 ns Delay:
//********************************************************************************
// The delay parameter is 12.5ns in 80 MHz core clock.
void SysTick_Delay(unsigned long delay){
NVIC_ST_RELOAD_R = delay-1;
NVIC_ST_CURRENT_R = 0;
while((NVIC_ST_CTRL_R&0x00010000)==0){
}
}
//********************************************************************************
//Systick 1 us Delay:
//********************************************************************************
// 80*12.5ns => 1 us
void SysTick_Delay1us(unsigned long delay){
unsigned long i;
for(i=0; i<delay; i++) {
SysTick_Delay(80); // wait 1us
}
}
//********************************************************************************
//Systick 1 ms Delay:
//********************************************************************************
// 80000*12.5ns => 1 ms
void SysTick_Delay1ms(unsigned long delay){
unsigned long i;
for(i=0; i<delay; i++) {
SysTick_Delay(80000); // wait 1ms
}
}
現在我們來新建一個 LCD1602 的 Project . 如何建立請參考 " 如何使用 Keil 建立一個新 project for TM4C123G Launchpad " 這篇文章 .
這裡有一個地方要注意 , 在 " Option of Target " 的 Target 頁面中 , 要勾選 Use MicroLib . 如下圖所示 . 因為我們要使用 printf 功能 .
記得要將 LCD1602.c , PLL_80MHZ.c 和 SYSTICK.c 加入 Project 中 , 如下 :
底下是 main.c :
/*********************************************************************************
**********************************************************************************
** LCD 1602 Module Experiment **
** 1. Write a driver of LCD1602 for TM4C123GXL Launchpad **
** 2. Modularize for Systick, PLL_80MHZ **
** 3. LCD1602 with Launchpad detail connection please refer to LCD1602.h file **
** 4. Initial LCD1602 module and display a string and a counter which count **
** per second. **
** 5. Michael @ 2014/05/10 **
**********************************************************************************
*********************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "inc/tm4c123gh6pm.h"
#include "LCD1602.h"
#include "SYSTICK.h"
#include "PLL_80MHZ.h"
void PLL_Init(void);
unsigned char msg1[] = {0x54,0x4D,0x34,0x43,0x32,0x33,0x47,0x58,0x4C}; //ASCII code for "TM4C123GXL"
unsigned char *msg[1] = {msg1};
int main(void){
unsigned int counter=0;
PLL_Init80MHZ();
SysTick_Init();
LCD1602_Init();
LCD1602_DisplayPosition(LINE1,3);
LCD1602_DisplayString(msg[0]);
while(1)
{
LCD1602_DisplayPosition(LINE2,7);
LCD1602_DisplayDec(counter);
counter ++;
SysTick_Delay1ms(1000);
}
}
// Use printf function
// To use this, please comment out above int main() and re-name below int main1() to int main()
int main1(void){
unsigned int counter=0;
PLL_Init80MHZ();
SysTick_Init();
LCD1602_Init();
LCD1602_DisplayPosition(LINE1,3);
printf("TM4C123GXL");
while(1)
{
LCD1602_DisplayPosition(LINE2,7);
printf("%d",counter);
counter ++;
SysTick_Delay1ms(1000);
}
}
這裡說明一下 , 這裡有兩個 main function . int main() 是用一般的方式顯示字串和計數 . int main1()則是採用 printf() function . 這會方便許多 . 不過注意要加入 #include
參考文獻 :
Embedded Systems: Introduction to ARM® Cortex™-M Microcontrollers - Jonathan Valvano
Getting Started with the Tiva™ TM4C123G LaunchPad Workshop
TM4C123GH6PM DATA SHEET
Embedded Systems Shape The World





沒有留言:
張貼留言