第五節(jié) LCD12864顯示
上一節(jié)我們成功控制了LED和蜂鳴器,這一節(jié)我們馬不停蹄接著LCD12864的控制。
為了系統(tǒng)能夠穩(wěn)定的工作,首先我們將系統(tǒng)時鐘切換到32M的外部晶振,為了自由配置所需要的時鐘,主要借助于CLKCONCMD.OSC選擇系統(tǒng)主時鐘,而借助于CLKCONCMD.OSC32K則用于選擇芯片32K時鐘源!而低功耗模式設(shè)置時,需要借助于SLEEPCMD寄存器,在《CC253x- CC2540-41Applications User‘s Guide.pdf>中并沒有說明SLEEPCMD第二位功能,如下所示:
但是參考cc2430芯片的說明書可以發(fā)現(xiàn),對應(yīng)的SLEEP寄存器則有說明,如下所示,這個是TI有意隱藏芯片細節(jié),當SLEEPCMD.OSC_PD為0時,32MHz晶振與16MHz RC振蕩器都會起振:
對于SLEEPSTA寄存器中BIT6/BIT5說明在cc2530說明書中也并沒有說明,可以參考cc2430說明書中內(nèi)容,其中第6位 XOSC_STB表明外部高速32M晶振是否上電并穩(wěn)定起振,當穩(wěn)定時該位為1;同樣對于第5位HFRC_STB則表明內(nèi)部16MHz高速RC振蕩器是否起振,并是否穩(wěn)定,當16MHz RC振蕩器穩(wěn)定時該位為1。
void SysStartXOSC(void)
{
SLEEPCMD &= ~0x04; // 啟動所有晶振
while (?。⊿LEEPSTA & 0x40)); // 等待晶振穩(wěn)定
CLKCONCMD = (CLKCONCMD & 0x80) | 0x49; // 使用16M晶振作為主時鐘
while ((CLKCONSTA & ~0x80) != 0x49 ); // 等待主時鐘切換到16M晶振
CLKCONCMD = (CLKCONCMD & ~0x80) ; // 使用外部32K晶振作為休眠時鐘
while ( (CLKCONSTA & 0x80) != 0 ); // 等待睡眠時鐘切換到外部32K晶振
CLKCONCMD = (CLKCONCMD & 0x80) ; // 使用32M晶振作為主時鐘
while ( (CLKCONSTA & ~0x80) != 0 ); // 等待主時鐘切換到32M晶振
SLEEPCMD |= 0x04; // 關(guān)閉未使用的晶振
}
按照上述方式配置后,我們就可以工作在外部的32M晶振上了,配置好系統(tǒng)時鐘和SPI后,剩下的工作只需要按照液晶屏的說明書發(fā)送相應(yīng)的指令就可以將液晶屏驅(qū)動起來了,具體的驅(qū)動代碼詳見下一堂課程。這里使用的是ASCII的點陣表,所以只能顯示英文,如果需要顯示中文,就需要中文字庫的支持了。
LCD12864的驅(qū)動程序:
P0.1 - LCD_MODE
P1.2 - LCD_CS
//spi
P1.5 - CLK
P1.6 - MOSI
/* LCD lines */
#define LCD12864_MAX_LINE 64
#define LCD12864_MAX_ROW 128
#define HAL_LCD_FONT_LINES 8
#define HAL_LCD_FONT_ROWS 6
/* LCD Max Chars and Buffer */
#define HAL_LCD_MAX_LINES (LCD12864_MAX_LINE/HAL_LCD_FONT_LINES) // 6*8點陣最大行數(shù)
#define HAL_LCD_MAX_CHARS (LCD12864_MAX_ROW/HAL_LCD_FONT_ROWS) // 6*8點陣最大列數(shù)
/* LCD Control lines */
#define HAL_LCD_RS_PORT 0
#define HAL_LCD_RS_PIN 1
#define HAL_LCD_CS_PORT 1
#define HAL_LCD_CS_PIN 2
/* LCD SPI lines */
#define HAL_LCD_CLK_PORT 1
#define HAL_LCD_CLK_PIN 5
#define HAL_LCD_MOSI_PORT 1
#define HAL_LCD_MOSI_PIN 6
// 12864 命令
#define LCD_CMD_DISPLAY_ON 0xAF
#define LCD_CMD_DISPLAY_OFF 0xAE
#define LCD_CMD_BEGIN_LINE 0x40
#define LCD_CMD_PAGE_LINE 0xB0
#define LCD_CMD_ROW_HIG 0x10
#define LCD_CMD_ROW_LOW 0x00
#define LCD_CMD_READ_STATE 0x00
#define LCD_CMD_ROW_ADDR_NORMAL 0xA0 // 從左到右
#define LCD_CMD_ROW_ADDR_REVERSE 0xA1 // 從右到左
#define LCD_CMD_DISPLAY_NORMAL 0xA6
#define LCD_CMD_DISPLAY_REVERSE 0xA7
#define LCD_CMD_DISPLAY_POINT_ALL 0xA5
#define LCD_CMD_DISPLAY_POINT_NORMAL 0xA4
#define LCD_CMD_BIAS_SET 0xA2 // 0XA2:BIAS=1/9 (常用) 0XA3:BIAS=1/7
#define LCD_CMD_SOFT_RESET 0xE2
#define LCD_CMD_LINE_NORMAL 0xC0 // 從上到下
#define LCD_CMD_LINE_REVERSE 0xC8 // 從下到上
#define LCD_CMD_POWER_ONE 0x2C
#define LCD_CMD_POWER_TWO 0x2E
#define LCD_CMD_POWER_THREE 0x2F
#define LCD_CMD_CONTRAST_ONE_LEVEL 0x22 // 0x20-0x27
#define LCD_CMD_CONTRAST_TWO_CMD 0x81 // 0x00-0x3F
#define LCD_CMD_STATIC_PICTURE_ON 0xAD
/* SPI interface control */
#define LCD_SPI_BEGIN() HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 0); /* chip select */
#define LCD_SPI_END()
{
asm(“NOP”);
asm(“NOP”);
asm(“NOP”);
asm(“NOP”);
HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 1); /* chip select */
}
/* clear the received and transmit byte status, write tx data to buffer, wait till transmit done */
#define LCD_SPI_TX(x) { U1CSR &= ~(BV(2) | BV(1)); U1DBUF = x; while( !(U1CSR & BV(1)) ); }
/* Control macros */
#define LCD_DO_WRITE() HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT, HAL_LCD_RS_PIN, 1);
#define LCD_DO_CONTROL() HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT, HAL_LCD_RS_PIN, 0);
/*全體ASCII 列表:5x7點陣庫*/
const static uint8 aucAsciiTable5x7[][5]={
0x00,0x00,0x00,0x00,0x00,//space
0x00,0x00,0x4f,0x00,0x00,//!
0x00,0x07,0x00,0x07,0x00,//“
0x14,0x7f,0x14,0x7f,0x14,//#
0x24,0x2a,0x7f,0x2a,0x12,//$
0x23,0x13,0x08,0x64,0x62,//%
0x36,0x49,0x55,0x22,0x50,//&
0x00,0x05,0x07,0x00,0x00,//]
0x00,0x1c,0x22,0x41,0x00,//(
0x00,0x41,0x22,0x1c,0x00,//)
0x14,0x08,0x3e,0x08,0x14,//*
0x08,0x08,0x3e,0x08,0x08,//+
0x00,0x50,0x30,0x00,0x00,//,
0x08,0x08,0x08,0x08,0x08,//-
0x00,0x60,0x60,0x00,0x00,//。
0x20,0x10,0x08,0x04,0x02,///
0x3e,0x51,0x49,0x45,0x3e,//0
0x00,0x42,0x7f,0x40,0x00,//1
0x42,0x61,0x51,0x49,0x46,//2
0x21,0x41,0x45,0x4b,0x31,//3
0x18,0x14,0x12,0x7f,0x10,//4
0x27,0x45,0x45,0x45,0x39,//5
0x3c,0x4a,0x49,0x49,0x30,//6
0x01,0x71,0x09,0x05,0x03,//7
0x36,0x49,0x49,0x49,0x36,//8
0x06,0x49,0x49,0x29,0x1e,//9
0x00,0x36,0x36,0x00,0x00,//:
0x00,0x56,0x36,0x00,0x00,//;
0x08,0x14,0x22,0x41,0x00,//《
0x14,0x14,0x14,0x14,0x14,//=
0x00,0x41,0x22,0x14,0x08,//>
0x02,0x01,0x51,0x09,0x06,//?
0x32,0x49,0x79,0x41,0x3e,//@
0x7e,0x11,0x11,0x11,0x7e,//A
0x7f,0x49,0x49,0x49,0x36,//B
0x3e,0x41,0x41,0x41,0x22,//C
0x7f,0x41,0x41,0x22,0x1c,//D
0x7f,0x49,0x49,0x49,0x41,//E
0x7f,0x09,0x09,0x09,0x01,//F
0x3e,0x41,0x49,0x49,0x7a,//G
0x7f,0x08,0x08,0x08,0x7f,//H
0x00,0x41,0x7f,0x41,0x00,//I
0x20,0x40,0x41,0x3f,0x01,//J
0x7f,0x08,0x14,0x22,0x41,//K
0x7f,0x40,0x40,0x40,0x40,//L
0x7f,0x02,0x0c,0x02,0x7f,//M
0x7f,0x04,0x08,0x10,0x7f,//N
0x3e,0x41,0x41,0x41,0x3e,//O
0x7f,0x09,0x09,0x09,0x06,//P
0x3e,0x41,0x51,0x21,0x5e,//Q
0x7f,0x09,0x19,0x29,0x46,//R
0x46,0x49,0x49,0x49,0x31,//S
0x01,0x01,0x7f,0x01,0x01,//T
0x3f,0x40,0x40,0x40,0x3f,//U
0x1f,0x20,0x40,0x20,0x1f,//V
0x3f,0x40,0x38,0x40,0x3f,//W
0x63,0x14,0x08,0x14,0x63,//X
0x07,0x08,0x70,0x08,0x07,//Y
0x61,0x51,0x49,0x45,0x43,//Z
0x00,0x7f,0x41,0x41,0x00,//[
0x02,0x04,0x08,0x10,0x20,// 斜杠
0x00,0x41,0x41,0x7f,0x00,//]
0x04,0x02,0x01,0x02,0x04,//^
0x40,0x40,0x40,0x40,0x40,//_
0x01,0x02,0x04,0x00,0x00,//`
0x20,0x54,0x54,0x54,0x78,//a
0x7f,0x48,0x48,0x48,0x30,//b
0x38,0x44,0x44,0x44,0x44,//c
0x30,0x48,0x48,0x48,0x7f,//d
0x38,0x54,0x54,0x54,0x58,//e
0x00,0x08,0x7e,0x09,0x02,//f
0x48,0x54,0x54,0x54,0x3c,//g
0x7f,0x08,0x08,0x08,0x70,//h
0x00,0x00,0x7a,0x00,0x00,//i
0x20,0x40,0x40,0x3d,0x00,//j
0x7f,0x20,0x28,0x44,0x00,//k
0x00,0x41,0x7f,0x40,0x00,//l
0x7c,0x04,0x38,0x04,0x7c,//m
0x7c,0x08,0x04,0x04,0x78,//n
0x38,0x44,0x44,0x44,0x38,//o
0x7c,0x14,0x14,0x14,0x08,//p
0x08,0x14,0x14,0x14,0x7c,//q
0x7c,0x08,0x04,0x04,0x08,//r
0x48,0x54,0x54,0x54,0x24,//s
0x04,0x04,0x3f,0x44,0x24,//t
0x3c,0x40,0x40,0x40,0x3c,//u
0x1c,0x20,0x40,0x20,0x1c,//v
0x3c,0x40,0x30,0x40,0x3c,//w
0x44,0x28,0x10,0x28,0x44,//x
0x04,0x48,0x30,0x08,0x04,//y
0x44,0x64,0x54,0x4c,0x44,//z
0x08,0x36,0x41,0x41,0x00,//{
0x00,0x00,0x77,0x00,0x00,//|
0x00,0x41,0x41,0x36,0x08,//}
0x04,0x02,0x02,0x02,0x01,//~
};
const uint8 asciiTableSize = sizeof( aucAsciiTable5x7 ) / sizeof( aucAsciiTable5x7[0]);
static void LCD12864_Cmd(uint8 cmd)
{
LCD_SPI_BEGIN();
LCD_DO_CONTROL();
LCD_SPI_TX(cmd);
LCD_SPI_END();
}
static void LCD12864_Dat(uint8 data)
{
LCD_SPI_BEGIN();
LCD_DO_WRITE();
LCD_SPI_TX(data);
LCD_SPI_END();
}
void LCD12864_Init(void)
{
PERCFG |= 0x02; // 設(shè)置UART alt2 為 SPI
// 配置引腳為SPI功能
HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_CLK_PORT, HAL_LCD_CLK_PIN);
HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MOSI_PORT, HAL_LCD_MOSI_PIN);
/* Configure SPI */
U1UCR = 0x80; // 清除原來的數(shù)據(jù)
U1CSR = 0x00; // SPI 主機模式
// 高位在前,第一個上升沿發(fā)送數(shù)據(jù),波特率為2M
U1GCR = HAL_SPI_TRANSFER_MSB_FIRST | HAL_SPI_CLOCK_PHA_0 | HAL_SPI_CLOCK_POL_LO | 0x0F;
U1BAUD = 0xFF;
// CS RS 配置為輸出
HAL_CONFIG_IO_OUTPUT(HAL_LCD_RS_PORT, HAL_LCD_RS_PIN, 1);
HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 1);
SoftWaitUs(15000); // 15 ms
LCD12864_Cmd(LCD_CMD_SOFT_RESET); //軟復(fù)位
SoftWaitUs(15000); // 15 ms
LCD12864_Cmd(LCD_CMD_POWER_ONE); //升壓步聚1
SoftWaitUs(15); // 15 us
LCD12864_Cmd(LCD_CMD_POWER_TWO); //升壓步聚2
SoftWaitUs(15); // 15 us
LCD12864_Cmd(LCD_CMD_POWER_THREE); //升壓步聚3
SoftWaitUs(150); // 15 us
LCD12864_Cmd(LCD_CMD_CONTRAST_ONE_LEVEL); //粗調(diào)對比度,可設(shè)置范圍0x20~0x27
LCD12864_Cmd(LCD_CMD_CONTRAST_TWO_CMD); //微調(diào)對比度
LCD12864_Cmd(0x3a); //0x1a,微調(diào)對比度的值,可設(shè)置范圍0x00~0x3f
LCD12864_Cmd(LCD_CMD_BIAS_SET); // 1/9偏壓比(bias)
LCD12864_Cmd(LCD_CMD_LINE_NORMAL); //行掃描順序:從上到下
LCD12864_Cmd(LCD_CMD_ROW_ADDR_REVERSE); //列掃描順序:從左到右
LCD12864_Cmd(LCD_CMD_BEGIN_LINE); //起始行:第一行開始
LCD12864_Cmd(LCD_CMD_DISPLAY_ON); //打開顯示
LCD12864_Cmd(LCD_CMD_DISPLAY_POINT_NORMAL);
LCD12864_Cmd(LCD_CMD_DISPLAY_NORMAL); //設(shè)置為正顯模式
SoftWaitUs(150); // 150 us
}
評論
查看更多