最近弄一個產品, 處理器是ARM STM32f10,
其中計畫加入一個簡單的顯示螢幕, 可以讓使用者知道目前系統的資訊
於是找了一個16行*2列的螢幕,
裡面使用到的是HD44780的chip吧, 大概長這樣
這個網站有基本的介紹與sample code (C語言)
** http://www.eeherald.com/section/design-guide/sample_lcd_c_programs.html
這個網站也有程式可看, 但不幸的是他寫的似乎是給8051那類的IC使用
但好處是可以將這些sample code互相比較, 找出同異
** http://www.microcontroller-project.com/alphanumeric-keypad-with-16×2-lcd.html
推薦!! 這個網址的說明是最清楚的
程式碼也是寫最棒的(for 4-bits), 還有影片分享
但有個小小錯誤需要改, 自己改吧~
** http://myactivities-mazen.blogspot.tw/2013/09/controlling-216-lcd-with-stm32f4.html
這篇寫得很詳細, 每個步驟都說明
可以study一下~
** http://web.alfredstate.edu/weimandn/lcd/lcd_initialization/lcd_initialization_index.html
以下分享從Mazen得到,
修改成 for 8-bits的版本
Thanks Mazen!
lcd_hd44780.c
#include "stm32f10x.h"#include "usb_box.h"#include "lcd_hd44780.h"#include "stm32f10x_gpio.h"#include #include #include //#include "stm32f4_discovery.h" GPIO_InitTypeDef GPIO_InitStructure;//-----------------------------------------------------------------------------void lcd_writenibble(unsigned char nibbleToWrite){ GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET); GPIO_WriteBit(LCD_GPIO, LCD_D0,(BitAction)(nibbleToWrite & 0x001)); GPIO_WriteBit(LCD_GPIO, LCD_D1,(BitAction)(nibbleToWrite & 0x002)); GPIO_WriteBit(LCD_GPIO, LCD_D2,(BitAction)(nibbleToWrite & 0x004)); GPIO_WriteBit(LCD_GPIO, LCD_D3,(BitAction)(nibbleToWrite & 0x008)); GPIO_WriteBit(LCD_GPIO, LCD_D4,(BitAction)(nibbleToWrite & 0x010)); GPIO_WriteBit(LCD_GPIO, LCD_D5,(BitAction)(nibbleToWrite & 0x020)); GPIO_WriteBit(LCD_GPIO, LCD_D6,(BitAction)(nibbleToWrite & 0x040)); GPIO_WriteBit(LCD_GPIO, LCD_D7,(BitAction)(nibbleToWrite & 0x080)); udelay(200); GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);} //-----------------------------------------------------------------------------unsigned char LCD_ReadNibble(void){ unsigned char tmp = 0; GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D0) << 0); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D1) << 1); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D2) << 2); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D3) << 3); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D4) << 4); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D5) << 5); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D6) << 6); tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D7) << 7); GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET); return tmp;} //-----------------------------------------------------------------------------unsigned char LCD_ReadStatus(void){ unsigned char status = 0; GPIO_InitStructure.GPIO_Pin = LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3 |LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(LCD_GPIO, &GPIO_InitStructure); GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_SET); GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_RESET); status = LCD_ReadNibble(); GPIO_InitStructure.GPIO_Pin = LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3 |LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LCD_GPIO, &GPIO_InitStructure); return status;} //-----------------------------------------------------------------------------unsigned char LCD_ReadOutNibble(void){ unsigned char tmp = 0; GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D0) << 0); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D1) << 1); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D2) << 2); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D3) << 3); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D4) << 4); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D5) << 5); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D6) << 6); tmp |= (GPIO_ReadOutputDataBit(LCD_GPIO, LCD_D7) << 7); GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET); return tmp;}//-----------------------------------------------------------------------------unsigned char LCD_ReadOutStatus(void){ unsigned char status = 0; GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_SET); GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_RESET); status = LCD_ReadOutNibble(); return status;} //------------------------------------------------------------------------------// Function Name : lcd_writedata// Description : Send Data Select routine(RS=1 & RW=0)//------------------------------------------------------------------------------void lcd_writedata(unsigned char dataToWrite){ GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_RESET); GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_SET); lcd_writenibble(dataToWrite); //LCD_ReadOutStatus(); while(LCD_ReadStatus() & 0x80);} //-----------------------------------------------------------------------------void lcd_writecommand(unsigned char commandToWrite){ GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS, Bit_RESET); lcd_writenibble(commandToWrite); //LCD_ReadOutStatus(); while(LCD_ReadStatus() & 0x80);} //-----------------------------------------------------------------------------void lcd_str(unsigned char * text){ while(*text) lcd_writedata(*text++);} //-----------------------------------------------------------------------------void lcd_locate(unsigned char x, unsigned char y){ lcd_writecommand(HD44780_DDRAM_SET | (x + (0x40 * y)));} //-----------------------------------------------------------------------------void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y){ lcd_locate(x,y); while(*text) lcd_writedata(*text++);} //-----------------------------------------------------------------------------void lcd_writebinary(unsigned int var, unsigned char bitCount){ signed char i; for(i = (bitCount - 1); i >= 0; i--) { lcd_writedata((var & (1 << i))?'1':'0'); }} //-----------------------------------------------------------------------------void LCD_ShiftLeft(void){ lcd_writecommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_LEFT | HD44780_SHIFT_DISPLAY);} //-----------------------------------------------------------------------------void LCD_ShiftRight(void){ lcd_writecommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_RIGHT | HD44780_SHIFT_DISPLAY);} //-----------------------------------------------------------------------------void lcd_init(void){ volatile unsigned char i = 0; volatile unsigned int delayCnt = 0; RCC_APB2PeriphClockCmd(LCD_CLK_LINE, ENABLE); GPIO_InitStructure.GPIO_Pin = LCD_D0|LCD_D1|LCD_D2|LCD_D3|LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_RS|LCD_RW|LCD_EN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LCD_GPIO, &GPIO_InitStructure); GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS | LCD_EN, Bit_SET); udelay(200); GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS | LCD_EN, Bit_RESET); udelay(200); /* Initial by instruction */ lcd_writecommand(0x030); udelay(500); lcd_writecommand(0x030); udelay(200); lcd_writecommand(0x030); udelay(200); lcd_writecommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT); //0x38 udelay(200); lcd_writecommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); //0x08 udelay(200); lcd_writecommand(HD44780_CLEAR); //0x01 udelay(200); lcd_writecommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);//0x06 udelay(200); lcd_writecommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_ON | HD44780_CURSOR_NOBLINK);//0x0E udelay(200);} //-----------------------------------------------------------------------------void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p){ lcd_writecommand(HD44780_CGRAM_SET | chrNum * 8); n *= 8; do lcd_writedata(*p++); while (--n);} //-----------------------------------------------------------------------------void lcd_cls(void){ lcd_writecommand(HD44780_CLEAR);} unsigned char* intToStr(int n){ int i = 0; int j = 0; char *tmp = (char*)malloc(sizeof(char)); unsigned char *ret = (unsigned char*)malloc(12); if(n<0 || n>9){ *tmp = n%10+48; n-=n%10; n/=10; tmp++; i++; } *tmp = n+48; i++; while(i--){ ret[j++] = *tmp--; } return ret;}void lcd_int(int a){ unsigned short ch,first; //you need this to display 0 if there was any char //Get first char ch = a/10000; if(ch){ lcd_writedata(48+ch); first = 1; } //Get second char ch = (a/1000)%10; if(ch || first){ lcd_writedata(48+ch); first = 1; } //Get third char ch = (a/100)%10; if(ch || first){ lcd_writedata(48+ch); first = 1; } //Get fourth char ch = (a/10)%10; if(ch || first){ lcd_writedata(48+ch); //first = 1; //q } //Get fifth char ch = a%10; //if(ch || first) //you dont need to check las one if ch is 0 then just display it, unless you dont want to then uncomment this line ("//q" line too) lcd_writedata(48+ch); // lcd_str(intToStr(n));} void lcd_intxy(int n, unsigned char x, unsigned char y){ lcd_locate(x,y); lcd_int(n);}
lcd_hd44780.h
//******************************************************************************// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.// AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING// FROM USE OF THIS SOFTWARE.//****************************************************************************** //##############################################################################// lcd_hd44780.h//############################################################################## //****************************************************************************////#include "main.h" #define LCD_GPIO GPIOB#define LCD_CLK_LINE RCC_APB2Periph_GPIOB #define LCD_D0 GPIO_Pin_0#define LCD_D1 GPIO_Pin_1#define LCD_D2 GPIO_Pin_5#define LCD_D3 GPIO_Pin_8#define LCD_D4 GPIO_Pin_9#define LCD_D5 GPIO_Pin_10#define LCD_D6 GPIO_Pin_11#define LCD_D7 GPIO_Pin_12 #define LCD_RS GPIO_Pin_13#define LCD_RW GPIO_Pin_14#define LCD_EN GPIO_Pin_15//******************************************************************************// #define HD44780_CLEAR 0x01 #define HD44780_HOME 0x02 #define HD44780_ENTRY_MODE 0x04 #define HD44780_EM_SHIFT_CURSOR 0x00 #define HD44780_EM_SHIFT_DISPLAY 0x01 #define HD44780_EM_DECREMENT 0x00 #define HD44780_EM_INCREMENT 0x02 #define HD44780_DISPLAY_ONOFF 0x08 #define HD44780_DISPLAY_OFF 0x00 #define HD44780_DISPLAY_ON 0x04 #define HD44780_CURSOR_OFF 0x00 #define HD44780_CURSOR_ON 0x02 #define HD44780_CURSOR_NOBLINK 0x00 #define HD44780_CURSOR_BLINK 0x01 #define HD44780_DISPLAY_CURSOR_SHIFT 0x10 #define HD44780_SHIFT_CURSOR 0 #define HD44780_SHIFT_DISPLAY 8 #define HD44780_SHIFT_LEFT 0 #define HD44780_SHIFT_RIGHT 4 #define HD44780_FUNCTION_SET 0x20 #define HD44780_FONT5x7 0x00 #define HD44780_FONT5x10 0x04 #define HD44780_ONE_LINE 0x00 #define HD44780_TWO_LINE 0x08 #define HD44780_4_BIT 0x00 #define HD44780_8_BIT 0x10 #define HD44780_CGRAM_SET 0x40 #define HD44780_DDRAM_SET 0x80 //##############################################################void lcd_init(void);void lcd_cls(void);void lcd_str(unsigned char * text);void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y);void lcd_locate(unsigned char x, unsigned char y);void lcd_int(int n);void lcd_intxy(int n, unsigned char x, unsigned char y); //############################################################### void lcd_writedata(unsigned char dataToWrite);void lcd_writecommand(unsigned char commandToWrite);void lcd_writebinary(unsigned int var, unsigned char bitCount);void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p);
main.c
lcd_init(); while (1) { lcd_locate(1,0); lcd_str("Mazen"); lcd_locate(7,0); lcd_str("A."); lcd_locate(0,1); lcd_str("-3125"); }