s3c2440 lcd 显示图片裸机程序
因为前面的裸机程序非常的简单,就不写博了。
程序的流程:
1,初始化C SP
2,关看门狗
3,初始化SDRAM
4,读出 NAND FLASH 中的 包含图片的程式放到SDRAM里面
5,跳转到SDRAM 执行
因为 2440 自动只读取4K 到 SRAM ,在里面放了图片,自然就不够用了。 就多了一步放到 SDRAM 里面去。
我并没有直接复制教程上面的程式,那个上面比较复杂。用到了c 的 库文件。
教程中只是画线,画圆线很简单。
刚一开始,我是使用 24BPP 开发的,这样遇到的问题还比较多。
图片要转为 C 语言的 头文件。我看网上有很多人在找软件转,还有个用 C的在LINUX 下转的。 找了一个软件吧,MFC 做的,竟然不支持 24BPP 。
只能自己做了。用 python 来编写。 链接在这里:http://www.cnblogs.com/ningci/p/5203053.html
16BPP:
//lcd 控制器 typedef struct{ unsigned long LCDCON1; unsigned long LCDCON2; unsigned long LCDCON3; unsigned long LCDCON4; unsigned long LCDCON5; unsigned long LCDSADDR1; unsigned long LCDSADDR2; unsigned long LCDSADDR3; unsigned long REDLUT; unsigned long GREENLUT; unsigned long BLUELUT; unsigned long DITHMODE; unsigned long TPAL; } LCD; LCD * lcd = (LCD *)0x4d000000; #define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPCUP (*(volatile unsigned long *)0x56000028) #define GPCCON (*(volatile unsigned long *)0x56000020) #define GPDUP (*(volatile unsigned long *)0x56000038) #define GPDCON (*(volatile unsigned long *)0x56000030) #define GPGUP (*(volatile unsigned long *)0x56000068) #define GPGCON (*(volatile unsigned long *)0x56000060) #define HCLK 100000000 #define LCD_WIDTH 480 #define LCD_HEIGHT 272 #define LCD_CLKVAL 4 #define LCD_TFT 3 #define LCD_24BBP 0xd #define LCD_16BBP 0xc #define LCD_EN_OFF 0 #define LCD_EN_ON 1 #define LCD_VBPD 1 #define LCD_LINEVAL (LCD_HEIGHT - 1) #define LCD_VFPD 1 #define LCD_VSPW 9 #define LCD_HBPD 1 #define LCD_HOZVAL (LCD_WIDTH - 1) #define LCD_HFPD 1 #define LCD_HSPW 40 #define LCD_INVVLINE 1 #define LCD_INVVFRAME 1 #define LCD_FRAMEBUFFER 0x30400000 //4M对齐的地址 void wait(s) { while(s--); } void init_lcd() { //LCD_PWREN GPGUP = 0xffffffff; // 禁止内部上拉 GPGCON = 3<<8; GPCUP = 0xffffffff; // 禁止内部上拉 GPCCON = 0xaaaaaaaa; // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND GPDUP = 0xffffffff; // 禁止内部上拉 GPDCON = 0xaaaaaaaa; // GPIO管脚用于VD[23:8] //GPB0 KEYBOARD //背光开 GPBCON &= ~(3); GPBCON |= 1; //HCLK 100M LCD CLK 9M 100/9/2-1=4 //默认是不启用状态 lcd->LCDCON1 = LCD_CLKVAL<<8 | LCD_TFT<<5 | LCD_16BBP<<1 | LCD_EN_OFF; lcd->LCDCON2 = LCD_VBPD<<24 | LCD_LINEVAL<<14 | LCD_VFPD<<6 | LCD_VSPW; lcd->LCDCON3 = LCD_HBPD<<19 | LCD_HOZVAL<<8 | LCD_HFPD; lcd->LCDCON4 = LCD_HSPW; //8bpp BSWP 1 16bpp HWSWP 1 24bpp 0 0 lcd->LCDCON5 = 1<<11 | LCD_INVVLINE<<9 | LCD_INVVFRAME<<8 | 1; //地址分开来存放 31:22位 右移即可 21:1 位 使用 & 上21个1 高位不 7 就是清空了 lcd->LCDSADDR1 = (LCD_FRAMEBUFFER>>22)<<21 | ((LCD_FRAMEBUFFER>>1) & 0x1fffff); //24bpp 占4个长度 16bpp 2个长度 8bpp 1个长度 lcd->LCDSADDR2 = ((LCD_FRAMEBUFFER + LCD_WIDTH * LCD_HEIGHT*2)>>1) & 0x1fffff; lcd->LCDSADDR3 = LCD_WIDTH ; lcd->TPAL = 0; } void lcd_on() { //背光开 GPBDAT |= 1; lcd->LCDCON1 |= LCD_EN_ON; lcd->LCDCON5 |= 0x3<<2; } void lcd_off() { //背光关 GPBDAT &= 0; lcd->LCDCON1 &= LCD_EN_OFF; lcd->LCDCON5 &= ~(0x3<<2); } void show_img(unsigned short *img) { int i=0; //显存地址 unsigned short * frame_buf = (volatile unsigned short *)LCD_FRAMEBUFFER; for(i=0;i<(480*272);i++) { *frame_buf = *img; frame_buf++; img++; } } #include "img1.h" int main() { init_lcd(); lcd_on(); show_img(&img1); return 0; }
在内存上直接写颜色值就能在屏幕上显示了。
下面是显示效果图: