由于項目所需,所以這段時間,抽空學了一下LPC2134,它是基于ARM7核的微處理器,內部有128K的flash與16k的RAM,所以一般的處理程序,內部空間就夠用了,當然你要上想在上面跑跑操作系統什么的,那就另當別論了。關于這個處理器其它方面的內部資料,如果你想了解,建議你好好翻翻它的數據手冊,如果你說英文太難啃,網上有大把中文的資料,當然懶貓還是建議你看英文原版,一它是廠家的資料,比較真實可靠一般不會有什么大錯,二你還可以湊這個空檔學學英語,真學好了這也是你要工資的籌碼。
今天只是實驗一下它的IO端口功能,如何實驗,懶貓就不再從流水燈開始了,懶貓選擇從LCD12864開始,說實在看著這么大一塊屏,挺嚇人的,其實LCD也沒有那么可怕,處理好時序就能讓它乖乖的顯示,所以想寫好LCD12864的驅動首先還是要好好翻看它的數據手冊,這里懶貓就不再詳述數據手冊上的內容了。不過在這里懶貓要先啰嗦一句,想讓LCD12864正確顯示,一定要記住先清屏,其實也就是清它內部寄存器,否則初始化時它內部的RAM中不知道是什么亂七八糟的東東,一旦你沒有清屏,很可能在顯示時會出現亂碼或顯示不正常,如下圖所示:
本文引用地址:http://www.104case.com/article/201611/319452.htm

圖1-1 初始化時沒有加清屏函數
其實懶貓在上大學時就試著用51寫LCD12864的驅動程序,所以這次使用還算順利,記得當時初次使用LCD12864出現這種情況,懶貓非常郁悶,以為自己的驅動程序沒有寫好,于是使勁翻看數據手冊,仔細的看時序,最后還單步調試,發現問題還是沒有解決,最后懶貓看到LCD12864中RAM時,突然想到單片機的設置變量時,初值也是隨機的,于是就想著清一下RAM,結果問題還真解決了,呵呵,當時那個興奮呀,無以言表。現在想想那時真的有點傻的可愛,網上有好多現成的程序,自己卻一個人死扣自己的程序。可惜時光如梭,轉眼間懶貓畢業就要兩年了,那些激情燃燒的歲月已漸漸遠去,卻永遠無法抹去我美好的記憶……
好了,不費話,說一說這次測試的電路,外圍電路很簡單,沒有接什么東東,就接了一塊LCD12864,2134的晶振是12MHz的,實時時鐘頻率是32.768KHz,下面給出仿真電路圖,上面省略了很多東東,這次仿真用的是proteus7.5的版本,仿真不能代替實物,懶貓的程序都是通過實物測試通過的,仿真只是為了調試之用,如果你真想學到真本領,做項目是最好的途徑。

圖2 電路仿真圖
注意,這是仿真電路圖,實際設計中要加上電源,晶振,電位器等部件,這個電路圖只說明一下LCD與LPC2134的數據接口。
說一下程序,程序包括main.c與display.c兩個C源程序代碼,只是簡單的測試一下lpc2134與LCD12864為后面的實驗做一個鋪墊,以后的實驗可能會用到這個驅動,由于程序東東比較多,所以就只貼出display.c這個源程序,其它的程序在附件中,如果有興趣可以下載下來查看:
//文件名稱:display.c
//功 能:LCD12864驅動函數
//作 者:懶貓愛飛
//備 注:MCU -- LPC2134
// Crystal -- 12MHz
// RTC -- 32.768KHz
// 開發環境 -- RealView MDK-ARM Verxion 4.12
#define IN_DISPLAY
#include "config.h"
#include "display.h"
//LCD12864引腳配置
#define LCD_CS1 4
#define LCD_CS2 3
#define LCD_RST 5
#define LCD_DI 21
#define LCD_RW 11
#define LCD_EN 10
//LCD12864操作宏定義
#define LCD_DE() IO0SET |= 1<
#define LCD_IE() IO0CLR |= 1<
#define LCD_RE() IO0SET |= 1<
#define LCD_WE() IO0CLR |= 1<
#define LCD_EH() IO0SET |= 1<
#define LCD_EL() IO0CLR |= 1<
//LCD12864命令宏定義
#define LCDSTARROW 0xC0
#define LCDPAGE 0xB8
#define LCDLINE 0x40
void delay_us(uint32 us)
{
while(us--);
}
void Out_Data(uint8 Odata)
{
IO1CLR |= (uint32)(0xFF<<16); // 將輸出端口置0
IO1SET |= (uint32)(Odata<<16); // 輸出要輸出的數據Odata
}
void Write_Data(uint8 Wdata)
{
LCD_DE(); // 寫數據使能
delay_us(1); // 延時等待端口電平穩定
LCD_WE(); // 寫命令使能
delay_us(1); // 延時等待數據寫進端口寄存器
Out_Data(Wdata); // 輸出要寫入LCD12864的數據
delay_us(1); // 延時等待端口電平穩定
LCD_EH(); // 數據在EN下降沿寫入LCD12864中
delay_us(3); // 延時
LCD_EL(); // EN下降沿
delay_us(3); // 延時一下
}
void Write_Cmd(uint8 Wcmd)
{
LCD_IE(); // 寫命令使能
delay_us(1);
LCD_WE(); // 寫命令使能
delay_us(1);
Out_Data(Wcmd); // 寫入命令
delay_us(1);
LCD_EH(); // 數據在EN下降沿寫入LCD12864中
delay_us(3);
LCD_EL(); // EN下降沿
delay_us(3);
}
void Init_LCDIO(void)
{
IO0DIR |= (1< // 初始端口方向
|(1<
|(1<
|(1<
|(1<
|(1<
IO0SET |= (1<
IO0CLR |= 1< // 初始化時EN腳置低
IO0CLR |= 1< // 初始化時先復位一下
delay_us(50);
IO0SET |= 1< // 再重新啟動LCD12864
delay_us(50);
IO0SET |= (1<
Write_Cmd(0x3F); //開顯示, 關顯示為 -- 0x3e
Write_Cmd(0x38); // 8位形式,兩行字符
Write_Cmd(0x0F); // 開顯示
Write_Cmd(0x01); // 清屏
Write_Cmd(0x06); // 畫面不動,光標右移
Write_Cmd(0xC0); // 設置起始行
}
void Show_Row(uint8 ucPage,uint8 ucLine,uint8 ucWidth,uint8 const *ucaRow)
{
uint8 ucCount = 0;
if(ucLine<64)
{
IO0SET |= 1< // 選通左屏
IO0CLR |= 1<
Write_Cmd(LCDPAGE+ucPage); // 設定頁號
Write_Cmd(LCDLINE+ucLine); // 設定列號
Write_Cmd(0x34);
if(ucLine+ucWidth<64) // 位于左半屏
{
for(ucCount = 0;ucCount
{
Write_Data(*(ucaRow+ucCount)); // 寫入數據
}
}
else // 跨越兩個半屏 先寫完左半屏
{
for(ucCount=0;ucCount<64-ucLine;ucCount++)
{
Write_Data(*(ucaRow+ucCount)); // 寫入數據
}
IO0CLR |= 1< // 再寫右半屏
IO0SET |= 1<
Write_Cmd(LCDPAGE+ucPage); // 設定頁號
Write_Cmd(LCDLINE); // 設定列號
Write_Cmd(0x34);
for(ucCount=64-ucLine;ucCount
{
Write_Data(*(ucaRow+ucCount));// 寫入數據
}
}
}
else // 位于右半屏
{
IO0CLR |= 1<
IO0SET |= 1<
Write_Cmd(LCDPAGE+ucPage); // 設定頁號
Write_Cmd(LCDLINE+ucLine-64); // 設定列號
Write_Cmd(0x34);
for(ucCount=0;ucCount
{
Write_Data(*(ucaRow+ucCount)); // 寫入數據
}
}
}
void Show_Word(uint8 ucPage,uint8 ucLine,uint8 const *ucaChinMap)
{
Show_Row(ucPage,ucLine,16,ucaChinMap); // 漢字上半部分
Show_Row(ucPage+1,ucLine,16,ucaChinMap+16); // 漢字下半部分
}
void Display_HZ(uint8 pagenum,uint8 colnum,uint8 num)
{
//uint8 k;
uint8 const *p1;
//k=colnum*16;
p1=hz_mode[num];
Show_Word(pagenum,colnum,p1);
}
void Show_Char(unsigned char ucPage,unsigned char ucLine,unsigned char const *ucaCharMap)
{
Show_Row(ucPage,ucLine,8,ucaCharMap);
Show_Row(ucPage+1,ucLine,8,ucaCharMap+8);
}
void Clear_Screen()
{
uint8 i,j;
for(i=0;i<8;i+=2) //共8頁
{
for(j=0;j<128;j+=8) //共128列
{
Show_Char(i,j,CHAR_B);
}
}
}
void Init_LCD(void)
{
Init_LCDIO(); // 初始化LCD接口
Clear_Screen(); // 要先清屏,不然會顯示不正常
Display_HZ(2,0,10); // 懶
Display_HZ(2,16,11); // 貓
Display_HZ(2,32,12); // 愛
Display_HZ(2,48,13); // 飛
Display_HZ(3,64,14); // 學
Display_HZ(3,80,15); // 習
Display_HZ(3,96,16); // 日
Display_HZ(3,112,17); // 志
}
當然這個程序還不完善,還沒顯示圖片的函數,還沒有菜單等功能,不過這些以后會慢慢加上的,現在只是在LPC2134中裸奔,主要是為了了解一下它內部結構與內部資源,以后的日志中會涉及到ucos或其它嵌入式系統,這個以后在日志中慢慢總結。
好了,今天說就先到這吧

評論