祝大家端午和六一快樂!原本今天是想休息休息的,但是實在無奈沒什麼事幹.所以就來學習學習LCD顯示圖片的函數
函數是照搬奮鬥的例子,算是些筆記吧.不過奮鬥的例子註釋的不是很詳細.今天去看了正點原子的論壇,唉..瞬間感覺正點原子做得真的很好
能把所有的資料都開源,並且論壇上大多問題都耐心的解答了.這實在是非常非常好的售後服務了!!自己也偷偷的去下了寫資料來看看,(*^__^*) 嘻嘻……
好,進入主題:
開發板:奮鬥V5
LCD:3寸 400X240
直接上代碼吧
void lcd_DrawPicture(u16 StartX,u16 StartY,u8 Dir,u8 *pic)
{
u32 i=8, len;
u16 temp,x,y;
/**************************************/
/*a1 長:240 寬:400*/
/*a2 長:400 寬:240*/
x=((uint16_t)(pic[2]<<8)+pic[3])-1; //從圖像數組裏取出圖像的長度
y=((uint16_t)(pic[4]<<8)+pic[5])-1; //從圖像數組裏取出圖像的高度
if(Dir==0){
LCD_WR_CMD(0x0003,0x1030); //圖像顯示方向爲左下起 行遞增 列遞增
LCD_WR_CMD(0x0210, StartX); //水平顯示區起始地址 0-239
LCD_WR_CMD(0x0211, StartX+x); //水平顯示區結束地址 0-239
LCD_WR_CMD(0x0212, StartY); //垂直顯示區起始地址 0-399
LCD_WR_CMD(0x0213, StartY+y); //垂直顯示區結束地址 0-399
LCD_WR_CMD(0x0200, StartX); //水平顯示區地址
LCD_WR_CMD(0x0201, StartY); //垂直顯示區地址
}
else if(Dir==1){
LCD_WR_CMD(0x0003,0x1018); //圖像顯示方向爲左下起 行遞增 列遞減
LCD_WR_CMD(0x0210, StartY); //水平顯示區起始地址 0-239
LCD_WR_CMD(0x0211, StartY+y); //水平顯示區結束地址 0-239
LCD_WR_CMD(0x0212, 399-(x+StartX)); //垂直顯示區起始地址 0-399
LCD_WR_CMD(0x0213, 399-StartX); //垂直顯示區結束地址 0-399
LCD_WR_CMD(0x200, StartY); //水平顯示區地址
LCD_WR_CMD(0x201, 399-StartX); //垂直顯示區地址
}
LCD_WR_REG(0x0202); //寫數據到顯示區
len=2*((uint16_t)(pic[2]<<8)+pic[3])*((uint16_t)(pic[4]<<8)+pic[5]); //計算出圖像所佔的字節數
while(i<(len+8)) { //從圖像數組的第9位開始遞增
temp=(uint16_t)( pic[i]<<8)+pic[i+1]; //16位總線, 需要一次發送2個字節的數據
LCD_WR_Data(temp); //將取出的16位像素數據送入顯示區
i=i+2; //取模位置加2,以爲獲取下一個像素數據
}
}
這是奮鬥給的原版例子,其中的註釋都給出了各行待會的功能,讓我們來看看他們具體是怎麼實現的
x=((uint16_t)(pic[2]<<8)+pic[3])-1; y=((uint16_t)(pic[4]<<8)+pic[5])-1;
爲什麼要這樣計算圖片的長和寬呢? 這時候就要看看圖片的數組了.圖片經過取模軟件(這裏用的是Image2LCD)把圖片變成16進制的數組,很長很長的一個數組,但是
我們這裏只關心它的前8個字符,這是400X240的一個圖片取模出來的結果(當然只是前面一小部分)
這是240X400的圖片的取模:
我想頭8位應該是固定的,而且240X400格式的照片前8位應該是一樣的,400X240格式的也應該是一樣的,這裏我只是自己下了兩張照片
取模的結果和奮鬥給的例子中的圖片是一樣的,所以我猜是一樣的,具體我也沒去研究.還有就是取模然間要設置得對,取模結果纔會和上面
一樣,顯示照片纔會正常,這個問題下面再說.好,回到上面的長度和寬度的分析:
這時候你可以拿起筆來計算一下了,以240X400爲例, x=((uint16_t)(pic[2]<<8)+pic[3])-1; y=((uint16_t)(pic[4]<<8)+pic[5])-1;
pic[2] << 8 即 0x00左移8位,還是0x00,然後加上0xF0(十進制240),所以x=240-1=239(爲了不超過屏幕範圍)
同理pic[4] <<8 等於0x100,然後加上0x90等於0x190(十進制400),所以y=400-1=399;
400X240的也是這樣算的...
然後接下來是顯示方向的問題,dir=0是豎屏(240x400),dir=1是橫屏(400x240),然後接下來就是寫數據了,上面已經有註釋了,這裏就不說了,不明白的可以看前一篇文章
len=2*((uint16_t)(pic[2]<<8)+pic[3])*((uint16_t)(pic[4]<<8)+pic[5]); 計算圖像所佔字節數,這裏我似懂非懂,不知道理解的對不對,這裏按我的理解是長X寬,這個容易懂,
爲什麼要乘於2,我想應該是求長和寬的時候是用了2個的字符合起來求的,所以這裏要分成1個字節就要乘於2(這些是瞎寫的,如果真的正確答案的朋友,就請幫忙解答下)
接下來是
while(i<(len+8)) { //從圖像數組的第9位開始遞增
temp=(uint16_t)( pic[i]<<8)+pic[i+1]; //16位總線, 需要一次發送2個字節的數據
LCD_WR_Data(temp);<span style="white-space:pre"> </span>//將取出的16位像素數據送入顯示區
i=i+2; //取模位置加2,以爲獲取下一個像素數據
i的初始值爲8,目的也就是爲了跳過前8個字符,這也說明了前8個字符應該不是照片的內容,應該是前綴.
好了,這就完了,接下來說說取模軟件的設置吧,不小心這東西也會讓你費很多事情的,這裏用的是Image2LCD
第一個注意的點是輸入的設置:最大寬度和最大高度要和你的照片相符,這張相片是400X240的
第二個注意的點是輸出圖像:一開始輸出圖像並不是(400,240)的,你要先設置最大寬度和最大高度以後,然後按上面的重新載入一下,它纔會輸出正確的大小格式,要不然圖像就不能正常顯示,或者是不能顯示.
第三個注意的點是高位在前:要勾上它,要不然圖像顯示就不正常了!
至於輸出多少位的圖片,是根據你的LCD接口方式來的.16位並口,就選擇16位真彩色
好了~這樣就可以了,開發板圖片就不傳了,手機爛拍照不好看.