/**************************************************************** 【文 件 名 稱】lcd12864.h 【功 能 描 述】lcd12864 頭文件 【 作 者 】shifu *****************************************************************/ #ifndef __LCD12864_H #define __LCD12864_H //**************************************************************** #include "stm32f10x_gpio.h" #include "systick_delay.h" //***************************************************************** //管腳定義 #define GPIO_LCD GPIOE #define RCC_APB2Periph_GPIO_LCD RCC_APB2Periph_GPIOE //片選 #define LCD_CS_1 GPIO_LCD->BSRR = GPIO_Pin_8 #define LCD_CS_0 GPIO_LCD->BRR = GPIO_Pin_8 //數(shù)據(jù) #define LCD_SID_1 GPIO_LCD->BSRR = GPIO_Pin_9 #define LCD_SID_0 GPIO_LCD->BRR = GPIO_Pin_9 //同步時(shí)鐘 #define LCD_CLK_1 GPIO_LCD->BSRR = GPIO_Pin_10 #define LCD_CLK_0 GPIO_LCD->BRR = GPIO_Pin_10 //復(fù)位 低電平復(fù)位 #define LCD_RET_1 GPIO_LCD->BSRR = GPIO_Pin_11 #define LCD_RET_0 GPIO_LCD->BRR = GPIO_Pin_11 #define LCD_Write_Con_Cmd (uc32)0xf8000000 // 1111 1000 0000 0000 0000 0000 0000 0000 #define LCD_Write_Dis_Data (uc32)0xfa000000 // 1111 1010 0000 0000 0000 0000 0000 0000 //********************函數(shù)聲明************************************ void LCD_Port_Config(void); void LCD_Init(void); void LCD_Write(u32 inst, u8 ddata); void LCD_Dis_Str(u8 row, u8 col, u8 *str); void LCD_Dis_Digital(u8 row, u8 col,u32 Dig_Data); void LCD_Clear(void); void LCD_Reset(void); void LCD_Dis_Frame(void); void LCD_Clear_GDRAM(void); void LCD_Clear_Graphics(u8 row, u8 col, u8 row_Pixel, u8 col_Pixel); void LCD_Dis_Graphics(u8 row, u8 col, u8 row_Pixel, u8 col_Pixel, u8 *Dis_Data); /***************************************************************** 液晶模塊指令集定義 ***************************************************************** 0x01 //清顯示指令 0x06 //設(shè)置輸入模式 0x0c //設(shè)置開顯控制 0x30 //功能設(shè)定(基本指令) 0x34 //功能設(shè)定(擴(kuò)充指令) 0x36 //打開繪圖(擴(kuò)充指令) *****************************************************************/ #endif /**************************************************************************** 【文 件 名 稱】lcd12864.c 【功 能 描 述】lcd12864 驅(qū)動(dòng) 【 作 者 】shifu ****************************************************************************/ /**************************************************************************/ #include "lcd12864.h" #include "stm32f10x_lib.h" /**************************************************************************** 【功能說明】I/O端口功能、方向設(shè)定 ****************************************************************************/ void LCD_Port_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* 使能端口時(shí)鐘*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_LCD, ENABLE); /* 配置所用管腳為推免輸出,端口速度為50MHz*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_LCD, &GPIO_InitStructure); } /**************************************************************************** 【功能說明】 LCD寫字節(jié)函數(shù) 入口參數(shù) inst=cmd/data: 命令/數(shù)據(jù)標(biāo)志(data:寫顯示數(shù)據(jù) cmd:寫控制指令) x : 命令/數(shù)據(jù)字節(jié) ****************************************************************************/ void LCD_Write(u32 inst, u8 ddata) { u32 temp = inst; u32 i,t; temp |= ((u32)(ddata & (u8)0xf0) << 16) + ((u32)(ddata & (u8)0x0f) << 12); LCD_CS_1; //選中12864 //拉低CLK引腳,準(zhǔn)備產(chǎn)生上升沿 LCD_CLK_0; //串行傳送24個(gè)二進(jìn)制位 for(i=0;i<24;i++) { if(temp & 0x80000000) LCD_SID_1; else LCD_SID_0; //拉高CLK引腳,產(chǎn)生一個(gè)上升沿,最高位被傳送到LCD模塊中 LCD_CLK_1; t = 0x10; while(t--); //延時(shí) lcd讀取數(shù)據(jù) //拉低CLK引腳,準(zhǔn)備產(chǎn)生上升沿 LCD_CLK_0; //左移一位,準(zhǔn)備下一個(gè)待傳送的位 temp = temp<<1; } LCD_CS_0; //取消選中12864 } /**************************************************************************** 【功能說明】 LCD字符串顯示函數(shù):void LCD_Dis_Str(u8 x, u8 y, u8 *str); 入口參數(shù) row: 字符串起始顯示位置的行 col: 字符串起始顯示位置的列 str: 指向待顯示字符串的字符指針,字符串以'\0'結(jié)尾 注:CGRAM 與中文字型的編碼只能出現(xiàn)在adress counter 的起始位 DDRAM 8*16 字節(jié)的空間 Line1 80H 81H 82H 83H 84H 85H 86H 87H Line2 90H 91H 92H 93H 94H 95H 96H 97H Line3 88H 89H 8AH 8BH 8CH 8DH 8EH 8FH Line4 98H 99H 9AH 9BH 9CH 9DH 9EH 9FH Line5 A0H A1H A2H A3H A4H A5H A6H A7H Line6 B0H B1H B2H B3H B4H B5H B6H B7H Line7 A8H A9H AAH ABH ACH ADH AEH AFH Line8 B8H B9H BAH BBH BCH BDH BEH BFH ****************************************************************************/ void LCD_Dis_Str(u8 row, u8 col, u8 *str) { u8 addr, i = 0; //防止誤操作(調(diào)試) // if(row > 3) row = 3; // if(col > 7) col = 7; //根據(jù)x,y坐標(biāo)確定顯示緩沖區(qū)地址 switch(row) { case 0: addr = 0x80 + col; break; case 1: addr = 0x90 + col; break; case 2: addr = 0x88 + col; break; case 3: addr = 0x98 + col; break; } //設(shè)置DDRAM地址 LCD_Write(LCD_Write_Con_Cmd, addr); while(*str) { //下一行:從設(shè)置好的DDRAM地址開始寫字符并準(zhǔn)備好指向下一個(gè)字符的指針 LCD_Write(LCD_Write_Dis_Data, *str++); i++; if(i==2) { i = 0; //每寫倆字節(jié)DDRAM地址會(huì)自動(dòng)增量,跟蹤DDRAM的地址變化,以便換行調(diào)整 addr++; //當(dāng)addr=88H,90H,98H,a0H時(shí),說明DRAM地址需要重新指定 if( (addr&0x07) == 0 ) { switch(addr) { case 0x88: addr = 0x90; break; case 0x98: addr = 0x88; break; case 0x90: addr = 0x98; break; case 0xa0: addr = 0x80; break; } //設(shè)置被重新指定了的DDRAM地址 LCD_Write(LCD_Write_Con_Cmd, addr); } } } } /**************************************************************************** 【功能說明】 LCD 清屏 ****************************************************************************/ void LCD_Clear(void) { LCD_Write(LCD_Write_Con_Cmd, 0x01); ST_Delay_Ms(5); } /**************************************************************************** 【功能說明】 LCD 重啟 ****************************************************************************/ void LCD_Reset(void) { LCD_RET_0; ST_Delay_Ms(50); LCD_RET_1; ST_Delay_Ms(100); } /**************************************************************************** 【功能說明】 初始化LCD子程序 ****************************************************************************/ void LCD_Init(void) { //端口配置 LCD_Port_Config(); //LCD復(fù)位 LCD_Reset(); //基本指令集 8位數(shù)據(jù) LCD_Write(LCD_Write_Con_Cmd,0x30); ST_Delay_Ms(1); //基本指令集 8位數(shù)據(jù) LCD_Write(LCD_Write_Con_Cmd,0x30); ST_Delay_Ms(1); //顯示打開,光標(biāo)關(guān),反白關(guān) LCD_Write(LCD_Write_Con_Cmd,0x0C); ST_Delay_Ms(1); //清屏 LCD_Clear(); //DDRAM 的地址計(jì)數(shù)器(AC)加1 LCD_Write(LCD_Write_Con_Cmd,0x06); } /****************************************************************************** 【功能說明】 顯示十進(jìn)制數(shù) 入口參數(shù) row: 行 col: 列 Dig_Data:顯示的十進(jìn)制數(shù) ******************************************************************************/ void LCD_Dis_Digital(u8 row, u8 col,u32 Dig_Data) { u8 dd[11]; u8 i,j=9; u32 temp; temp = Dig_Data; dd[10]=0; for(i=10;(i>j)&(i>0);i--) { dd[i-1] = temp%10 + '0'; temp=temp/10; if(temp) j--; } LCD_Dis_Str(row,col,&dd[i]); } /**************************************************************************** 【功能說明】 LCD顯示邊框 圖形模式 ****************************************************************************/ void LCD_Dis_Frame(void) { u8 x,y; //LCD清除繪圖RAM LCD_Clear_GDRAM(); LCD_Write(LCD_Write_Con_Cmd,0x34); LCD_Write(LCD_Write_Con_Cmd,0x36); for(x=0;x<9;x += 8) { for(y=0;y < 32;y++) { //左豎 LCD_Write(LCD_Write_Con_Cmd, y+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, x+0x80);//列地址 LCD_Write(LCD_Write_Dis_Data,0x80); LCD_Write(LCD_Write_Dis_Data,0x00 ); //右豎 LCD_Write(LCD_Write_Con_Cmd, y+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, x+0x87);//列地址 LCD_Write(LCD_Write_Dis_Data,0x00); LCD_Write(LCD_Write_Dis_Data,0x01); } } for(y=0;y<2;y++) { for(x=0;x<8;x++) { LCD_Write(LCD_Write_Con_Cmd, y*31+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, x+0x80+8*y);//列地址 LCD_Write(LCD_Write_Dis_Data,0xff); LCD_Write(LCD_Write_Dis_Data,0xff); } } LCD_Write(LCD_Write_Con_Cmd,0x30); } /**************************************************************************** 【功能說明】 LCD清除全部繪圖RAM GDRAM 64*32字節(jié)空間 0 1 2****13 14 15 1**************** 2**************** ***************** * * 62 63 ****************************************************************************/ void LCD_Clear_GDRAM(void) { u8 x,y; LCD_Write(LCD_Write_Con_Cmd,0x34); for(y=0;y<64;y++) { for(x=0;x<16;x++) { LCD_Write(LCD_Write_Con_Cmd, y+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, x+0x80);//列地址 LCD_Write(LCD_Write_Dis_Data,0x00); LCD_Write(LCD_Write_Dis_Data,0x00); } } LCD_Write(LCD_Write_Con_Cmd,0x30); } /****************************************************************************** 【功能說明】 在指定行列顯示自定義圖形(定義為 64X8像素) 【入口參數(shù)】 u8 row: 行坐標(biāo) 取值范圍(0-63) u8 col: 列坐標(biāo) 取值范圍(0-7) u8 row_Pixel: 行像素個(gè)數(shù) 取值范圍(1-64) u8 col_Pixel: 列像素個(gè)數(shù) 取值范圍(1-8) u8 *Dis_Data: 顯示數(shù)據(jù)指針 【注意事項(xiàng)】 : 行坐標(biāo)加行偏移不能超過 63 列坐標(biāo)加列偏移不能超過 7 ******************************************************************************/ void LCD_Dis_Graphics(u8 row, u8 col, u8 row_Pixel, u8 col_Pixel, u8 *Dis_Data) { u8 r,c,r_count,c_count; //打開繪圖模式 LCD_Write(LCD_Write_Con_Cmd,0x34); LCD_Write(LCD_Write_Con_Cmd,0x36); for(r_count = row; r_count < row + row_Pixel; r_count++) { if(r_count > 31) r = r_count - 32; else r = r_count; for(c_count = col; c_count < col + col_Pixel; c_count++) { if(r_count > 31) c = c_count + 8; else c = c_count; LCD_Write(LCD_Write_Con_Cmd, r+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, c+0x80);//列地址 LCD_Write(LCD_Write_Dis_Data,*Dis_Data++); LCD_Write(LCD_Write_Dis_Data,*Dis_Data++); } } LCD_Write(LCD_Write_Con_Cmd,0x30); } /****************************************************************************** 【功能說明】 在指定行列清除自定義圖形(定義為 64X8像素) 【入口參數(shù)】 u8 row: 行坐標(biāo) 取值范圍(0-63) u8 col: 列坐標(biāo) 取值范圍(0-7) u8 row_Pixel: 行像素個(gè)數(shù) 取值范圍(1-64) u8 col_Pixel: 列像素個(gè)數(shù) 取值范圍(1-8) 【注意事項(xiàng)】 : 行坐標(biāo)加行偏移不能超過 63 列坐標(biāo)加列偏移不能超過 7 ******************************************************************************/ void LCD_Clear_Graphics(u8 row, u8 col, u8 row_Pixel, u8 col_Pixel) { u8 r,c,r_count,c_count; //擴(kuò)充指令 LCD_Write(LCD_Write_Con_Cmd,0x34); for(r_count = row; r_count < row + row_Pixel; r_count++) { if(r_count > 31) r = r_count - 32; else r = r_count; for(c_count = col; c_count < col + col_Pixel; c_count++) { if(r_count > 31) c = c_count + 8; else c = c_count; LCD_Write(LCD_Write_Con_Cmd, r+0x80);//行地址 LCD_Write(LCD_Write_Con_Cmd, c+0x80);//列地址 LCD_Write(LCD_Write_Dis_Data,0x00); LCD_Write(LCD_Write_Dis_Data,0x00); } } LCD_Write(LCD_Write_Con_Cmd,0x30); }