lcd.c源碼:
#define GPECON (*((volatile unsigned long *)0x7F008080))
#define GPEDAT (*((volatile unsigned long *)0x7F008084))
#define GPFCON (*((volatile unsigned long *)0x7F0080A0))
#define GPFDAT (*((volatile unsigned long *)0x7F0080A4))
#define GPICON (*((volatile unsigned long *)0x7F008100))
#define GPJCON (*((volatile unsigned long *)0x7F008120))
// display controller
#define MIFPCON (*((volatile unsigned long *)0x7410800C))
#define SPCON (*((volatile unsigned long *)0x7F0081A0))
#define VIDCON0 (*((volatile unsigned long *)0x77100000))
#define VIDCON1 (*((volatile unsigned long *)0x77100004))
#define VIDTCON0 (*((volatile unsigned long *)0x77100010))
#define VIDTCON1 (*((volatile unsigned long *)0x77100014))
#define VIDTCON2 (*((volatile unsigned long *)0x77100018))
#define WINCON0 (*((volatile unsigned long *)0x77100020))
#define VIDOSD0A (*((volatile unsigned long *)0x77100040))
#define VIDOSD0B (*((volatile unsigned long *)0x77100044))
#define VIDOSD0C (*((volatile unsigned long *)0x77100048))
#define VIDW00ADD0B0 (*((volatile unsigned long *)0x771000A0))
#define VIDW00ADD1B0 (*((volatile unsigned long *)0x771000D0))
#define VIDW00ADD2 (*((volatile unsigned long *)0x77100100))
#define WPALCON (*((volatile unsigned long *)0x771001A0))
#define WIN0_PALENTRY0 0x77100400
#define VSPW 9
#define VBPD 1
#define LINEVAL 271
#define VFPD 1
#define HSPW 40
#define HBPD 1
#define HOZVAL 479
#define HFPD 1
#define LeftTopX 0
#define LeftTopY 0
#define RightBotX 479
#define RightBotY 271
#define FRAME_BUFFER 0x54000000
unsigned int fb_base_addr;
unsigned int bpp;
unsigned int xsize;
unsigned int ysize;
void palette_init(void)
{
int i;
volatile unsigned long *p = (volatile unsigned long *)WIN0_PALENTRY0; //調(diào)色板地址
WPALCON |= (1<<9); // 允許CPU修改調(diào)色板
WPALCON &= ~(0x7);
WPALCON |= 1; // 調(diào)色板的數(shù)據(jù)格式: 24-bit ( 8:8:8 )
p[0] = 0x000000; //只初始化了調(diào)色板的前五格的顏色值
p[1] = 0x00ff00;
p[2] = 0xff0000;
p[3] = 0x0000ff;
p[4] = 0xffffff;
for (i = 0; i <256; i++) //用調(diào)色板以后顯存的bpp=8,8最大能表示256個地址,也就是調(diào)色板最大有256項
{
//p[i] = ;
}
WPALCON &= ~(1<<9); // 禁止CPU訪問調(diào)色板
}
void clean_screem(void)
{
int x;
int y;
int cnt = 0;
volatile unsigned char *p = (volatile unsigned char *)fb_base_addr;
for (x = 0; x <=HOZVAL; x++)
for (y = 0; y <= LINEVAL; y++)
p[cnt++] = 0;
}
void lcd_init(void)
{
// 1. 設(shè)置相關(guān)GPIO引腳用于LCD
GPICON = 0xaaaaaaaa; // gpi0~gpi15用作lcd_vd[0~15]
GPJCON = 0xaaaaaaa; // gpj0~gpi11用作lcd
//GPFCON &= ~(0x3<<28);
//GPFCON |= (1<<28); // GPF14用作背光使能信號
GPECON &= ~(0xf);
GPECON |= (0x1); // GPE0用作LCD的on/off信號
// 2. 初始化6410的display controller
// 2.1 hsync,vsync,vclk,vden的極性和時間參數(shù)
// 2.2 行數(shù)、列數(shù)(分辨率),象素顏色的格式
// 2.3 分配顯存(frame buffer),寫入display controller
MIFPCON &= ~(1<<3); // Normal mode
SPCON &= ~(0x3);
SPCON |= 0x1; // RGB I/F style
#if 0
VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6)); // RGB I/F, RGB Parallel format,
// vclk== 27MHz Ext Clock input / (CLKVAL+1) = 27/3 = 9MHz
VIDCON0 |= ((2<<6) | (1<<4) | (0x3<<2));
#else
VIDCON0 &= ~((3<<26) | (3<<17) | (0xff<<6) | (3<<2)); // RGB I/F, RGB Parallel format,
VIDCON0 |= ((14<<6) | (1<<4) ); // vclk== HCLK / (CLKVAL+1) = 133/15 = 9MHz
#endif
VIDCON1 &= ~(1<<7); // 在vclk的下降沿獲取數(shù)據(jù)
VIDCON1 |= ((1<<6) | (1<<5)); // HSYNC高電平有效, VSYNC高電平有效,
VIDTCON0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0);
VIDTCON1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0);
VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);
WINCON0 &= ~(0xf << 2);
WINCON0 |= (0x3<<2) | (1<<17); // 8 BPP (palletized), byte swap
VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1) / 4;
VIDW00ADD0B0 = FRAME_BUFFER;
VIDW00ADD1B0 = (((HOZVAL + 1)*1 + 0) * (LINEVAL + 1)) & (0xffffff);
// VBASEL = VBASEU + (LINEWIDTH+OFFSIZE) x (LINEVAL+1)
// = 0 + (480*1 + 0) * 272
// =
//VIDW00ADD2 = HOZVAL + 1;
// 設(shè)置調(diào)色板
palette_init();
pwm_set(2);
fb_base_addr = FRAME_BUFFER;
xsize = HOZVAL + 1;
ysize = LINEVAL + 1;
bpp = 8;
clean_screem();
}
void backlight_enable(void)
{
//GPFDAT |= (1<<14);
}
void backlight_disable(void)
{
//GPFDAT &= ~(1<<14);
}
void lcd_on(void)
{
GPEDAT |= (1<<0);
// 等待10 frame
}
void lcd_off(void)
{
GPEDAT &= ~(1<<0);
}
void displaycon_on(void)
{
VIDCON0 |= 0x3;
WINCON0 |= 1; //6410的lcd控制器有多個窗口,這里只使能了一個窗口
}
void displaycon_off(void)
{
VIDCON0 &= ~0x3;
WINCON0 &= ~1; //6410的lcd控制器有多個窗口,這里只使能了一個窗口
}
void lcd_enable(void)
{
// 使能LCD本身
lcd_on();
// 打開背光
//backlight_enable();
pwm_start();
// 使能display controller
displaycon_on();
}
void lcd_disable(void)
{
// 關(guān)閉背光
// 關(guān)閉LCD本身
// 關(guān)閉display controller
}
void draw_line(void)
{
//不用調(diào)色板的時候畫線傳入的是24位顏色值,用調(diào)色板以后傳入的是在調(diào)色板中的顏色索引值
DrawLine(0,0, 0,271, 0);
DrawLine(0,0, 479,0, 1);
DrawLine(0,0, 479,271, 2);
DrawLine(0,271, 479,0, 3);
DrawLine(0,271, 479,271, 1);
DrawLine(479,271, 479,0, 2);
DrawLine(0,136, 479,136, 3);
DrawLine(240,0, 240,271, 1);
}
void display_red(void)
{
volatile unsigned char *p = (volatile unsigned char *)FRAME_BUFFER;
int x, y;
int cnt = 0;
unsigned char colors[] = {0, 1, 2, 3};
static int color_idx = 0;
for (y = 0; y <= LINEVAL; y++)
{
for (x = 0; x <= HOZVAL; x++)
{
p[cnt++] =colors[color_idx] ; // red
}
}
color_idx++;
if (color_idx == 5)
color_idx = 0;
}
void lcd_test(void)
{
unsigned char c;
static int lcdon = 0;
static int blon = 0;
static int dispon = 0;
lcd_init();
while (1)
{
printf("********LCD TEST MENU********\n\r");
printf("[L] enable/disable LCD\n\r");
printf("[B] enable/disable back light\n\r");
printf("[C] enable/disable s3c6410 display controller\n\r");
printf("[D] display color\n\r");
printf("[I] draw line\n\r");
printf("[Q] quit\n\r");
do {
c = getc();
if (c == '\n' || c == '\r')
{
printf("\n\r");
}
else
{
putc(c);
}
} while (c == '\n' || c == '\r');
switch (c) {
case 'l':
case 'L':
{
if (lcdon)
{
lcd_off();
printf("LCD off\n\r");
}
else
{
lcd_on();
printf("LCD on\n\r");
}
lcdon = !lcdon;
break;
}
case 'b':
case 'B':
{
pwm_menu();
break;
}
case 'c':
case 'C':
{
if (dispon)
{
displaycon_off();
printf("Display controller off\n\r");
}
else
{
displaycon_on();
printf("Display controller on\n\r");
}
blon = !blon;
break;
}
case 'd':
case 'D':
{
display_red();
break;
}
case 'i':
case 'I':
{
draw_line();
break;
}
case 'q':
case 'Q':
{
return ;
break;
}
}
}
}
=====================================================================
framebuffer.c源碼:
// FILE: framebuffer.c
// 實現(xiàn)在framebuffer上畫點、畫線、畫同心圓、清屏的函數(shù)
#include "types.h"
#include "framebuffer.h"
extern unsigned int fb_base_addr;
extern unsigned int bpp;
extern unsigned int xsize;
extern unsigned int ysize;
//typedef UINT32 FB_24BPP[272][480];
// 畫點
// 輸入?yún)?shù):
// x、y : 象素坐標
// color: 顏色值
// 對于16BPP: color的格式為0xAARRGGBB (AA = 透明度),
// 需要轉(zhuǎn)換為5:6:5格式
// 對于8BPP: color為調(diào)色板中的索引值,
// 其顏色取決于調(diào)色板中的數(shù)值
void PutPixel(UINT32 x, UINT32 y, UINT32 color)
{
UINT8 red,green,blue;
switch (bpp){
case 24:
{
//bpp=24位,但是為了對齊會浪費一個字節(jié),一共4字節(jié)32位
UINT32 *addr = (UINT32 *)fb_base_addr + (y * xsize + x);
*addr = color;
break;
}
case 16:
{
UINT16 *addr = (UINT16 *)fb_base_addr + (y * xsize + x);
red = (color >> 19) & 0x1f;
green = (color >> 10) & 0x3f;
blue = (color >> 3) & 0x1f;
color = (red << 11) | (green << 5) | blue; // 格式5:6:5
*addr = (UINT16) color;
break;
}
case 8:
{
UINT8 *addr = (UINT8 *)fb_base_addr + (y * xsize + x);
*addr = (UINT8) color; // 調(diào)色板的索引值
break;
}
default:
break;
}
}
// 畫線
// 輸入?yún)?shù):
// x1、y1 : 起點坐標
// x2、y2 : 終點坐標
// color : 顏色值
// 對于16BPP: color的格式為0xAARRGGBB (AA = 透明度),
// 需要轉(zhuǎn)換為5:6:5格式
// 對于8BPP: color為調(diào)色板中的索引值,
// 其顏色取決于調(diào)色板中的數(shù)值
void DrawLine(int x1,int y1,int x2,int y2,int color)
{
int dx,dy,e;
dx=x2-x1;
dy=y2-y1;
if(dx>=0)
{
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 1/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 2/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 8/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 7/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
else //dx<0
{
dx=-dx; //dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
PutPixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
PutPixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}
// 繪制同心圓
void Mire(void)
{
UINT32 x,y;
UINT32 color;
UINT8 red,green,blue,alpha;
for (y = 0; y < ysize; y++)
for (x = 0; x < xsize; x++){
color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;
red = (color/8) % 256;
green = (color/4) % 256;
blue = (color/2) % 256;
alpha = (color*2) % 256;
color |= ((UINT32)alpha << 24);
color |= ((UINT32)red << 16);
color |= ((UINT32)green << 8 );
color |= ((UINT32)blue );
PutPixel(x,y,color);
}
}
// 將屏幕清成單色
// 輸入?yún)?shù):
// color: 顏色值
// 對于16BPP: color的格式為0xAARRGGBB (AA = 透明度),
// 需要轉(zhuǎn)換為5:6:5格式
// 對于8BPP: color為調(diào)色板中的索引值,
// 其顏色取決于調(diào)色板中的數(shù)值
void ClearScr(UINT32 color)
{
UINT32 x,y;
for (y = 0; y < ysize; y++)
for (x = 0; x < xsize; x++)
PutPixel(x, y, color);
}
#define FONTDATAMAX 2048
extern const unsigned char fontdata_8x8[FONTDATAMAX];
void lcd_putc(unsigned char c)
{
static int x = 0;
static int y = 0;
int i,j;
unsigned char line_dots;
// 獲得字模
unsigned char *char_dots = fontdata_8x8 + c * 8;
// 在framebuffer里描點
if (c == '\n')
{
//y = (y + 8) % 272;
y += 8;
if (y > 272)
y = 0;
return ;
}
else if (c == '\r')
{
x = 0;
return;
}
for (i = 0; i < 8; i++)
{
line_dots = char_dots[i];
for (j = 0; j < 8; j++)
{
if (line_dots & (0x80 >> j))
{
PutPixel(x+j, y+i, 1); // 調(diào)色板里面第1個條目的顏色值
}
else
{
PutPixel(x+j, y+i, 0); // 調(diào)色板里面第0個條目的顏色值
}
}
}
//x = (x + 8) % 480;
x += 8;
if (x > 480)
x = 0;
if (x == 0)
{
//y = (y + 8) % 272;
y += 8;
if (y > 272)
y = 0;
}
}
上一篇:自己寫bootloader之OK6410
下一篇:OK6410裸機之LCD顯
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 意法半導(dǎo)體推出用于匹配遠距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- API調(diào)用小記(Touchdesigner和ESP32)
- 關(guān)于ESP32/8266使用async-mqtt-client庫的一些基本介紹
- 正式發(fā)布本土化戰(zhàn)略,英飛凌猛攻中國市場
- 純視覺的自動駕駛會有哪些安全問題?
- 電池市場月報|2025年5月:穩(wěn)定增長,動力電池同比出口+30%
- 7納米以下汽車芯片測試的新挑戰(zhàn)!
- 英飛凌將CAPSENSE?集成到PSOC? HV MCU中 用于智能傳感器和執(zhí)行器
- 恩智浦與Rimac Technology聯(lián)合開發(fā)用于高級域和區(qū)域控制的集中式車輛架構(gòu)
- 佳能開發(fā)高動態(tài)范圍SPAD傳感器 有望應(yīng)用于自動駕駛和高級駕駛輔助系統(tǒng)
- 全固態(tài)電池生產(chǎn)線落地韓國
- 10 萬顆下線,車企很難拒絕4D成像雷達
- 自動駕駛毫米波雷達之間會相互干擾嗎?
- 曬出我使用MSP430編譯器的經(jīng)驗與技巧!
- 有獎直播|是德科技感恩月—遇見KeysightCare - 貴重儀器安全避坑指南
- Littelfuse 高效 • 可靠 • 精準的功率控制和電路保護方案在工業(yè)、交通、通訊、醫(yī)療及新能源中的應(yīng)用
- 新一輪EE_FPGA學(xué)習(xí)計劃開始啦!
- 免費申請測評 | Sipeed MAix BiT AIoT 開發(fā)套件,搭載K210、屏幕和攝像頭
- 看視頻贏京東卡 | PI無刷直流電機學(xué)習(xí)中心正式上線
- 【社區(qū)大講堂】ARM+DSP雙核處理器應(yīng)用程序開發(fā)
- 免費下載|TE 白皮書《暖通空調(diào)制冷系統(tǒng)中壓力傳感器的重要性》
- 諾基亞宣布和博通合作開發(fā)5G芯片
- T-Mobile出現(xiàn)重大網(wǎng)絡(luò)中斷!FCC正在展開調(diào)查
- 華天科技南京80億元封測項目進入試生產(chǎn)階段
- 日經(jīng):Arm中國換帥風波有伏筆
- 原材料價格回升,PCB大廠建滔漲價!
- Microchip解讀如何保障嵌入式物聯(lián)網(wǎng)的安全
- 美國研發(fā)碳納米管助推鋰電池 可提高電導(dǎo)率和倍率能力
- 指紋識別銀行卡市場漸熱,設(shè)計挑戰(zhàn)在哪里?
- Seeed Grove初學(xué)者套件深受好評
- 物聯(lián)網(wǎng)設(shè)備攻擊激增,在內(nèi)存設(shè)備中實現(xiàn)安全是關(guān)鍵