三星S6D1121主控彩屏(240*320*18bit,262K)驱动程序
這個是三星的主控S6D1121彩屏(240*320*18bit,262Kcr)的彩屏的驅動程序.
采用的是80System+16bit接口
不知道是什么原因, 這個主控網上很少有資料,我也是看了好久的DS才明白了一些(全英文, 基本沒中文資料, 反正是不好找到)
這是我接觸的第一塊彩屏哦~~
如果有用這個芯片的, 可能會有些方便, 也方便交流下使用經驗.
這里總共分4個文件:
common.c,common.h:一些公共的包含與定義,函數
s6d1121.c,s6d1121.h:主控芯片驅動程序
//common.h - 一些公用的定義,函數等 #ifndef __COMMON_H__ #define __COMMON_H__#include <reg52.h> #include <intrins.h>typedef unsigned int uint; typedef unsigned char uchar;void delay_us(uint us); void delay_ms(uint ms);#endif// !__COMMON_H__
//common.c #include "common.h"void delay_ms(uint ms) {uchar k;while(ms--){for(k=125; k>0; k--){_nop_();}} }void delay_us(uint us) {while(us--){_nop_();} }
//s6d1121.h //S6D1121.h //S6D1121驅動程序 //應用層請不要調用 //應調用GDI接口 // //女孩不哭 QQ:191035066 //2012-11-05#ifndef __S6D1121_H__ #define __S6D1121_H__#include "common.h"void LCD_SetAddress(uint x, uint y, uint width, uint height); void LCD_WriteBus(uint dat); void LCD_WriteCmdWithData(uchar cmd, uint value); void LCD_WriteData(uint dat); void LCD_WriteCmd(uchar cmd); uint LCD_ReadBus(void); uint LCD_ReadData(void); void LCD_Init(void);#endif// !__S6D1121_H__
//s6d1121.c /* 文件:S6D1121.c* 功能:三星S6D1121主控彩屏驅動程序* 版本:1.0* 作者:女孩不哭* Q--Q:191035066* 時間:2012-11-05* 說明:這里是底層驅動程序,用戶不應該隨便調用* 請調用編寫的圖形接口程序* 參考:http://www.elecfreaks.com/wiki/index.php?title=2.4%22_TFT_LCD:_TFT01-2.4*/#include "common.h" #include "s6d1121.h"//I/O口定義,除*_RST外,均Active Low sbit LCD_RST= P2^0; //復位 sbit LCD_CS = P2^1; //片選 sbit LCD_RD = P2^2; //讀取 sbit LCD_WR = P2^3; //寫入 sbit LCD_RS = P2^4; //寄存器/數據選擇//數據總線端口定義 //如果使用16位總線,需要宏定義:BUS_16 //當使用8位總線時,僅*_HI有效 #define LCD_DATA_PORT_HI P0 #define LCD_DATA_PORT_LOW P1//初始化,初始化之前 //MCU應該延時一段時間 //以使電源穩定 void LCD_Init(void) {LCD_RST = 1;delay_ms(5);LCD_RST = 0;delay_ms(5);LCD_RST = 1;LCD_CS = 1;LCD_RD = 1;LCD_WR = 1;delay_ms(5);LCD_CS = 0;//片選使能//詳細的說明見一開始的網址LCD_WriteCmdWithData(0x11,0x2004);LCD_WriteCmdWithData(0x13,0xcc00);LCD_WriteCmdWithData(0x15,0x2600);LCD_WriteCmdWithData(0x14,0x252a);LCD_WriteCmdWithData(0x12,0x0033);LCD_WriteCmdWithData(0x13,0xcc04);delay_ms(1);LCD_WriteCmdWithData(0x13,0xcc06);delay_ms(1);LCD_WriteCmdWithData(0x13,0xcc4f);delay_ms(1);LCD_WriteCmdWithData(0x13,0x674f);LCD_WriteCmdWithData(0x11,0x2003);delay_ms(1);LCD_WriteCmdWithData(0x30,0x2609);LCD_WriteCmdWithData(0x31,0x242c);LCD_WriteCmdWithData(0x32,0x1F23); LCD_WriteCmdWithData(0x33,0x2425); LCD_WriteCmdWithData(0x34,0x2226); LCD_WriteCmdWithData(0x35,0x2523); LCD_WriteCmdWithData(0x36,0x1C1A); LCD_WriteCmdWithData(0x37,0x131D); LCD_WriteCmdWithData(0x38,0x0B11); LCD_WriteCmdWithData(0x39,0x1210); LCD_WriteCmdWithData(0x3A,0x1315); LCD_WriteCmdWithData(0x3B,0x3619); LCD_WriteCmdWithData(0x3C,0x0D00); LCD_WriteCmdWithData(0x3D,0x000D); LCD_WriteCmdWithData(0x16,0x0007); LCD_WriteCmdWithData(0x02,0x0013); LCD_WriteCmdWithData(0x03,0x0003); LCD_WriteCmdWithData(0x01,0x0127); delay_ms(1); LCD_WriteCmdWithData(0x08,0x0303); LCD_WriteCmdWithData(0x0A,0x000B); LCD_WriteCmdWithData(0x0B,0x0003); LCD_WriteCmdWithData(0x0C,0x0000); LCD_WriteCmdWithData(0x41,0x0000); LCD_WriteCmdWithData(0x50,0x0000); LCD_WriteCmdWithData(0x60,0x0005); LCD_WriteCmdWithData(0x70,0x000B); LCD_WriteCmdWithData(0x71,0x0000); LCD_WriteCmdWithData(0x78,0x0000); LCD_WriteCmdWithData(0x7A,0x0000); LCD_WriteCmdWithData(0x79,0x0007); LCD_WriteCmdWithData(0x07,0x0053); LCD_WriteCmdWithData(0x79,0x0000);LCD_WriteCmd(0x22);LCD_CS = 1;//關閉片選delay_ms(50);LCD_CS = 0; }/* 函數:寫命令* 參數:uchar cmd:寄存器地址* 返回:(無)* 說明:RS為低為寫寄存器*/ void LCD_WriteCmd(uchar cmd) {LCD_RS = 0;//寫命令模LCD_WriteBus((uint)cmd); }/* 函數:寫數據值* 參數:uint dat:16位的數據* 返回:(無)* 說明:RS應為高*/ void LCD_WriteData(uint dat) {LCD_RS = 1;//寫數據LCD_WriteBus(dat); }/*uint LCD_ReadData(void) {LCD_RS = 1;return LCD_ReadBus(); }uint LCD_ReadBus(void) {uint ret=0; #ifdef BUS_16LCD_RD = 0;LCD_RD = 1;ret = LCD_DATA_PORT_HI;ret <<= 8;ret |= LCD_DATA_PORT_LOW; #elseLCD_RD = 0;LCD_RD = 1;ret = LCD_DATA_PORT_HI;ret <<= 8;LCD_RD = 0;LCD_RD = 1;ret |= LCD_DATA_PORT_HI; #endifreturn ret; }*//* 函數:寫寄存器* 參數:* uchar cmd:寄存器地址(8位)* uint value:寫給寄存器的值(16位)* 返回:(無)*/ void LCD_WriteCmdWithData(uchar cmd, uint value) {LCD_WriteCmd((uchar)cmd); //寫寄存器地址LCD_WriteData(value); //寫寄存器值 }//把命令/數據向總線寫入 void LCD_WriteBus(uint dat) { #ifdef BUS_16 //16位總線模式LCD_DATA_PORT_HI = (uchar)(dat>>8);LCD_DATA_PORT_LOW = (uchar)dat;LCD_WR = 0;LCD_WR = 1; //S6D1121在每次的WR的上升沿讀取數據 #else//此時僅高字節有效//先寫高字節,再寫低字節LCD_DATA_PORT_HI = (uchar)(dat>>8);LCD_WR = 0;LCD_WR = 1;LCD_DATA_PORT_HI = (uchar)dat;LCD_WR = 0;LCD_WR = 1; #endif }/** 函數:設定寫入數據的區域* 參數:* int x:X坐標(范圍:0~239)* int y:Y坐標(范圍:0~319)* uint width:寬* uint height:高* 返回:(無)* 說明:(x1,y1; x2,y2)兩點構成一個矩形* 設定好區域后,在下一個指令前應該寫緩沖區*/ void LCD_SetAddress(uint x, uint y, uint width, uint height) {LCD_WriteCmdWithData(0x46, (x+width-1)<<8|x); //一次性設定x1,x2(高)LCD_WriteCmdWithData(0x47, y+height-1); //y2LCD_WriteCmdWithData(0x48, y); //y1LCD_WriteCmdWithData(0x20, x); //設定RAM開始寫的地址LCD_WriteCmdWithData(0x21, y);LCD_WriteCmd(0x22); //設定好寫寄存器,開始寫 }XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
上一篇隨筆貼出了驅動程序, 這篇文章的代碼主要就是針對上層的調用了, 但是, 其實, 只要是底層的驅動程序能能夠工作了, 圖形設備接口應該就可以隨便移植的咯~
一般彩屏的操作方式應該都是差不多的吧?
說明下, 本人不是很擅長圖形方面的算法設計,? 有些程序采用了大師們寫的程序, 有些則是我自己寫的(寫得很差), 不過還是能夠實現功能的哈~
我測試程序時是用的死太慘的51單片機測試的, ROM比較小, 只有60KB(整個字庫有大約225KB), 完全沒法裝進去的, 所以就把要用的保存進去了, 所以會有ascii.c/.h文件的存在, 當然, 如果后來會用SD/MMC/U盤, 那就太好了, 不過, 很遺憾的是, SD卡我一直沒有能夠成功讀取~ 慢慢來吧.
代碼文件:
ascii.c/ascii.h:字庫文件
common.c/common.h:一些公共的頭文件/類型聲明等等(和前面那篇隨筆是一樣的,沒貼出)
gdi.c/gdi.h:圖形設備接口的實現
有了這四個文件, 再加上前面的驅動程序, 把她們放到一個項目下, 就可以寫程序調用了哈, 很方便的說~
//ascii.h #ifndef __ASCIII_H__ #define __ASCIII_H__uchar* asc_get_char(uchar uch); uchar* asc_get_word(uchar* word); uchar* asc_tpow(void);#endif// !__ASCIII_H__
//ascii.c #include "common.h"//這個是two's pow(2的次方), 其實沒什么必要的, 可以忽略 uchar code t_p[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//這個是標準ASCII字符對應的像素值了 //應該有注意到, 我這里是寬8*高12的, 而我卻在上下各加 //兩個空行, 形成了寬8*高16的字符, 這樣做的目的主要是為了方便 //因為我的中文字庫是用的16*16(不是很小) //是我從別人那里直接拷過來的, 看起來字體不是很好看 //這個是不需要程序獲取的, 程序只需做的是調用asc_get_char(your_char) //來得到一個字符數組的偏移就行了 uchar code ascii[][12] = { /* */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* ! */{0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00}, /* " */{0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* # */{0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00}, /* $ */{0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00}, /* % */{0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00}, /* & */{0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00}, /* ' */{0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* ( */{0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00}, /* ) */{0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00}, /* * */{0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00}, /* + */{0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00}, /* , */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80}, /* - */{0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00}, /* . */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00}, /* / */{0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00}, /* 0 */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00}, /* 1 */{0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00}, /* 2 */{0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00}, /* 3 */{0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00}, /* 4 */{0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00}, /* 5 */{0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00}, /* 6 */{0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00}, /* 7 */{0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00}, /* 8 */{0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00}, /* 9 */{0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00}, /* : */{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00}, /* ; */{0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00}, /* < */{0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00}, /* = */{0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, /* > */{0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00}, /* ? */{0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00}, /* @ */{0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00}, /* A */{0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00}, /* B */{0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00}, /* C */{0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00}, /* D */{0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00}, /* E */{0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00}, /* F */{0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00}, /* G */{0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00}, /* H */{0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00}, /* I */{0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00}, /* J */{0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00}, /* K */{0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00}, /* L */{0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00}, /* M */{0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00}, /* N */{0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00}, /* O */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00}, /* P */{0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00}, /* Q */{0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00}, /* R */{0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00}, /* S */{0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00}, /* T */{0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00}, /* U */{0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00}, /* V */{0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00}, /* W */{0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00}, /* X */{0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00}, /* Y */{0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00}, /* Z */{0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00}, /* [ */{0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00}, /* \ */{0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00}, /* ] */{0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00}, /* ^ */{0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* _ */{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC}, /* ` */{0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* a */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00}, /* b */{0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00}, /* c */{0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00}, /* d */{0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00}, /* e */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00}, /* f */{0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00}, /* g */{0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38}, /* h */{0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00}, /* i */{0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00}, /* j */{0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0}, /* k */{0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00}, /* l */{0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00}, /* m */{0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00}, /* n */{0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00}, /* o */{0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00}, /* p */{0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0}, /* q */{0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C}, /* r */{0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00}, /* s */{0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00}, /* t */{0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00}, /* u */{0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00}, /* v */{0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00}, /* w */{0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00}, /* x */{0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00}, /* y */{0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0}, /* z */{0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00}, /* { */{0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00}, /* | */{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10}, /* } */{0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00}, /* ~ */{0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} };//用了一個結構體來索引 //因為沒有足夠的空間來保存字庫 //所以就不能按照平常的區位碼來索引漢字的代碼了 //which[3]:保存一個中文漢字,what[32]:保存的代碼 //生成方式:http://www.cnblogs.com/nbsofer/archive/2012/11/01/2749026.html //同樣是內部使用, 外部程序只需要調用 asc_get_word(相對于*_char而言)(見下) struct wmap_s{uchar which[3];uchar what[32]; } code wmap[] = {{"我",{0x04,0x80,0x0E,0xA0,0x78,0x90,0x08,0x90,0x08,0x84,0xFF,0xFE,0x08,0x80,0x08,0x90,0x0A,0x90,0x0C,0x60,0x18,0x40,0x68,0xA0,0x09,0x20,0x0A,0x14,0x28,0x14,0x10,0x0C}},{"的",{0x10,0x40,0x10,0x40,0x22,0x44,0x7F,0x7E,0x42,0x84,0x43,0x04,0x42,0x04,0x42,0x84,0x7E,0x64,0x42,0x24,0x42,0x04,0x42,0x04,0x42,0x04,0x7E,0x04,0x42,0x28,0x00,0x10}},{"是",{0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x04,0xFF,0xFE,0x01,0x00,0x09,0x20,0x09,0xF0,0x09,0x00,0x15,0x00,0x23,0x06,0x40,0xFC}},{"現",{0x00,0x08,0x09,0xFC,0xFD,0x08,0x11,0x28,0x11,0x28,0x11,0x28,0x11,0x28,0x7D,0x48,0x11,0x48,0x11,0x48,0x10,0x40,0x1C,0xA0,0xF0,0xA0,0x41,0x22,0x02,0x22,0x0C,0x1E}},{"在",{0x02,0x00,0x02,0x00,0x02,0x04,0xFF,0xFE,0x04,0x00,0x04,0x40,0x08,0x40,0x08,0x50,0x13,0xF8,0x30,0x40,0x50,0x40,0x90,0x40,0x10,0x40,0x10,0x44,0x17,0xFE,0x10,0x00}},{"時",{0x00,0x08,0x04,0x08,0x7E,0x08,0x44,0x08,0x47,0xFE,0x44,0x08,0x44,0x08,0x7C,0x88,0x44,0x48,0x44,0x48,0x44,0x08,0x44,0x08,0x7C,0x08,0x44,0x48,0x00,0x28,0x00,0x10}},{"間",{0x20,0x04,0x1B,0xFE,0x08,0x04,0x40,0x24,0x4F,0xF4,0x48,0x24,0x48,0x24,0x48,0x24,0x4F,0xE4,0x48,0x24,0x48,0x24,0x48,0x24,0x4F,0xE4,0x48,0x24,0x40,0x14,0x40,0x08}},{"溫",{0x00,0x08,0x43,0xFC,0x32,0x08,0x12,0x08,0x83,0xF8,0x62,0x08,0x22,0x08,0x0B,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x20,0x00}},{"度",{0x01,0x00,0x00,0x84,0x3F,0xFE,0x22,0x20,0x22,0x28,0x3F,0xFC,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x22,0x20,0x21,0x40,0x20,0x80,0x43,0x60,0x8C,0x1E,0x30,0x04}},{"初",{0x20,0x00,0x10,0x00,0x10,0x04,0x05,0xFE,0xFC,0x44,0x08,0x44,0x10,0x44,0x34,0x44,0x58,0x44,0x94,0x44,0x10,0x44,0x10,0x84,0x10,0x84,0x11,0x04,0x12,0x28,0x14,0x10}},{"始",{0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x80,0xFC,0x88,0x25,0x04,0x27,0xFE,0x24,0x02,0x24,0x04,0x49,0xFE,0x29,0x04,0x11,0x04,0x29,0x04,0x45,0x04,0x85,0xFC,0x01,0x04}},{"化",{0x08,0x80,0x08,0x80,0x08,0x80,0x10,0x88,0x10,0x98,0x30,0xA0,0x50,0xC0,0x90,0x80,0x11,0x80,0x12,0x80,0x14,0x80,0x10,0x80,0x10,0x82,0x10,0x82,0x10,0x7E,0x10,0x00}}, };//函數:asc_get_word(uchar* pword) //用來獲取一個中文漢字的代碼保存位置偏移 //如果不存在, 返回NULL了(這里直接用0代替了) uchar* asc_get_word(uchar* pword) {uint k;uint len = sizeof(wmap)/sizeof(wmap[0]);for(k=0; k<len; k++){if(wmap[k].which[0] == pword[0] &&wmap[k].which[1] == pword[1]){return &wmap[k].what[0];}}return 0; }//同上, 不過這個是用來獲取ASCII字符的 //應該注意到的是:我是根據標準ASCII的順序來索引ASCII字符的 //所以,上面的ASCII字符代碼表不能再添加/刪除 //當然, 中文字庫不存在這個限制 //使用:傳入一個ASCII字符,返回編碼的偏移(沒有的話返回0) uchar* asc_get_char(char uch) {char idx;idx = (uch-32);//從空格算起, 控制字符就沒用了,回車在其它程序中已經單獨處理if(idx<0 || idx>sizeof(ascii)/sizeof(ascii[0]))return 0;return &ascii[idx][0]; }//返回2的次方, 用得著的時候就用吧 //比如: uchar* tp = asc_tpow(); //tp[0]=2^7,tp[1]=2^6, ... uchar* asc_tpow(void) {return &t_p[0]; }
//gdi.h #ifndef __GDI_H__ #define __GDI_H__#include "common.h" #include "s6d1121.h"//顏色描述表(前景色, 背景色) typedef struct color_table_s{uint fgc;uint bgc; }color_table;//很有用的rgb(r,g,b) 宏 rgb(紅,綠,藍) #define rgb(r,g,b) ((uint)(\((uint)(uchar)(r)<<8 & 0xf800|(uchar)(r)>>7)|\((uint)(uchar)(g)<<3 & 0x7e00)|\((uint)(uchar)(b)>>2 | (uchar)(b)>>7)))//function prototype //函數的說明直接見各函數 void rectangle(int left, int top, int width, int height, uint color); void line(int x1, int y1, int x2, int y2, uint color); void triangle(int x1, int y1, int x2, int y2, int x3, int y3, uint color); void set_pixel(uint x, uint y, uint color); void fill_rect(uint left, uint top, uint width, uint height, uint color); void clear_screen(uint color); void char_out(int x, int y, char ch, uint fgc, uint bgc); void word_out(int x, int y, uchar* pword, uint fgc, uint bgc); void text_out(int x, int y, uchar* str, uint fgc, uint bgc, color_table* pct); int cirpot(int x0,int y0,int x,int y,uint color); void circle(int x0,int y0,int r,uint color); float sin(float rad); uchar* itoa(int x);//some useful function macros //一些有用的宏,主要是用于把應用層的程序和驅動層的程序隔離 //其實還是是調用的該驅動層的函數 /* 設定待寫入/讀取數據的緩沖區:X坐標,Y坐標,寬,高 */ #define set_area(x,y,width,height) LCD_SetAddress((x),(y),(width),(height)) /* 在 set_area 調用后, 寫入數據的操作 */ #define set_data(dat) LCD_WriteData((dat)) //初始化彩屏 #define init_lcd LCD_Init //清屏 #define clr_scr clear_screen //設定彩屏主控內部寄存器的值(不應該暴露給應用層的,以后再更新,必然的) #define set_reg(reg,value) LCD_WriteCmdWithData((reg),(value)) #endif// !__GDI_H__
//gdi.c #include "common.h" #include "gdi.h" #include "s6d1121.h" #include "ascii.h"//用來把指定的整數轉換為字符串 //保存在靜態變量buf中并返回給調用者 //顯示0還是顯示空格在于自己了 uchar* itoa(int x) {static uchar buf[6];buf[0] = x/10000+'0';x %= 10000;buf[1] = x/1000+'0';x %= 1000;buf[2] = x/100+'0';x %= 100;buf[3] = x/10+'0';x %= 10;buf[4] = x+'0';buf[5] = 0;return &buf[0]; }//畫矩形的函數 //參數:左上角的X坐標,左上角的Y坐標, 寬, 高, 顏色(有一些常用的顏色應該被定義, //下次再修改, 51的刷屏速度忍無可忍) void rectangle(int left, int top, int width, int height, uint color) {int x2,y2;x2 = left+width-1;y2 = top+height-1;//必須保存在有效范圍內if(left<0 || top<0 || x2>239 || y2>319)return;//看到了吧, 實現就是轉換成畫直線//所以:最關鍵的怎樣畫點,直線line(left, top, x2, top, color);line(x2, top, x2, y2, color);line(x2, y2, left, y2, color);line(left, y2, left, top, color); }//畫三角形, 參數為三個坐標點+顏色 //其實還是是轉換成畫三條直線 void triangle(int x1, int y1, int x2, int y2, int x3, int y3,uint color) {line(x1,y1,x2,y2, color);line(x2,y2,x3,y3, color);line(x1,y1,x3,y3, color); }//畫直線, 可憐這是我自己寫的算法, 效率太低了 //而且,如果不仔細讀讀代碼, 很難明白的 //以后還是換成大師們已經寫好了的吧 //參數:兩點成線, 不用多說, 當然, 顏色有要有的 //畫線就是轉換成畫點,所以關鍵是怎么畫點,set_pixel再介紹 void line(int x1, int y1, int x2, int y2, uint color) {int w,h;//記錄長寬float rate1,rate2;//高與寬的比率int xaxis, yaxis, k; int ffalling = 0;//直線是否為下降沿if(x1>x2){k = x1; x1 = x2; x2 = k;k = y1; y1 = y2; y2 = k;}w = x2-x1+1;//get horizontal distanceh = y2-y1;//get vertical distanceif(h<0) h = -h;h = h+1;rate1 = (float)h/w;//根據相似三角形計算坐標rate2 = (float)w/h;if(w>h){//寬大于高ffalling = y1-y2;if(y1 == y2)ffalling = 0;for(k=0; k<w; k++){if(ffalling<0){//+0.5是作四四舍五入yaxis = y2-(uint)((w-k)*rate1+0.5)+1;}else if(ffalling>0){yaxis = y1-(uint)(k*rate1+0.5)+1;}else{yaxis = y1;}set_pixel(k+x1,yaxis, color);}}else{ //h>wffalling = y1-y2;if(x1==x2)ffalling = 0;for(k=0; k<h; k++){if(ffalling<0){xaxis = x1+(uint)(k*rate2+0.5)+1;}else if(ffalling>0){xaxis = x1+((h-k)*rate2+0.5)+1;}else{xaxis = x1;}set_pixel(xaxis, (y1<y2?y1:y2)+k, color);} } }//這個就是畫點函數了 //set_area,set_data 完工 void set_pixel(uint x, uint y, uint color) {if(x>239 || y>319) return;set_area(x, y, 1, 1);set_data(color); }//填充一塊矩形為指定顏色 void fill_rect(uint left, uint top, uint width, uint height, uint color) {uint a,b;if(left>239 || top>319) return;if(left+width-1>239) width = 239-left+1;//clip x borderif(top+height-1>319) height = 319-top+1;//clip y borderset_area(left, top, width, height);for(a=0; a<height; a++){for(b=0; b<width; b++){set_data(color);}} }//用 顏色 color 清屏 void clear_screen(uint color) {uint i,j;set_area(0,0,240,320);for(i=0;i<320;i++){for (j=0;j<240;j++){set_data(color);}} }//在指定位置輸出一個ASCII字符 //屬于內部調用函數 //參數:X坐標,Y坐標,字符,前景色,背景色 //如果不知道是怎樣寫字的, 看去看看我那篇 //介紹字庫的使用的文章吧(在前面) void char_out(int x, int y, char ch, uint fgc, uint bgc) {char k,i;uchar* pch = 0;uchar* t_p = asc_tpow();pch = asc_get_char(ch);if(!pch) return;//我的字庫是8*12的//但是我把它轉換成了8*16set_area(x, y, 8, 16);//所以我先寫三行空白行for(k=0; k<24; k++){set_data(bgc);}for(k=0; k<12; k++){for(i=0; i<8; i++){set_data(*pch&t_p[i]?fgc:bgc);}pch++;}//再寫一行空白行,用背景色填充for(k=0; k<8; k++){set_data(bgc);} }//前面是輸出ASCII字符 //這個是在指定位置輸出指定的漢字 //屬于內部調用函數 //參數:X坐標,Y坐標,一個漢字的數組(uchar數組,3個字符,2個最好,節約嘛),前景色,背景色 void word_out(int x, int y, uchar* pword, uint fgc, uint bgc) {uchar xx,k,yy;uchar* pch = 0;uchar* t_p = asc_tpow();//"漢字兩個都>=0xa0, 不然就是錯的"if(pword[0]<0xa0 || pword[1]<0xa0)return;pch = asc_get_word(pword);if(!pch) return;//"需要檢測x+15,y+15是否出界,則k應為實際打印的行/列數"//"并設定一個參數為是否依然打印不能完整打印的char/word"set_area(x,y,16,16);//16*2*8:32個字節就這樣寫進去咯for(k=0; k<16; k++){//16行for(yy=0; yy<2; yy++){//一行2個字節(16位)for(xx=0; xx<8; xx++){//一個字節8個位set_data(*pch&t_p[xx]?fgc:bgc);}pch++;}} }//這個都是真正的輸出文本的函數的 //參數:X坐標,Y坐標,字符串指針,前景色,背景色,顏色索引表(可選) //說明:如果x,y均等于-1,則程序在上一次的結尾接著輸出 //僅可用的控制字符:'\n',換行 void text_out(int x, int y, uchar* str, uint fgc, uint bgc, color_table* pct) {uchar* pch = str;uint k;uint fgcolor, bgcolor;//保存最近一次調用時的坐標static uchar lastx=0;static uint lasty=0;//判斷是否為接著輸出if(x==-1 && y==-1){x = lastx;y = lasty;}if(!pch) return;//遍歷每個字符調用// char_out 進行字符輸出// word_out 進行中文輸出for(;*pch;){if(pct){fgcolor = pct->fgc;bgcolor = pct->bgc;}else{fgcolor = fgc;bgcolor = bgc;}if(*pch >= 0xa0){//wordword_out(x, y, pch, fgcolor, bgcolor);x += 16;//more 8 pixels than charspch++;}else if(*pch == '\n'){//換行處理x = 0;y += 16;}else{//charchar_out(x, y, *pch, fgcolor, bgcolor);x += 8;}pch++;//check if return//word to next line//這里是當輸出的漢字/字符不能完全顯示是的處理(換行)if(/*x==240*/(*pch>=0xa0&&x>224) || x>232){//to next lineif(*pch){set_area(x,y,240,320);for(k=0; k<16*(239-x+1); k++){set_data(bgcolor);}}x = 0;y += 16;}if(/*y==320*/y>304){//is bottomif(*pch){set_area(x,y,240,320);for(k=0; k<240*(319-y+1); k++){set_data(bgcolor);} }y = 0;}if(pct) pct++;}lastx = x;lasty = y; }/* float sin(float rad) {float x1 = rad;float x3 = x1*rad*rad;float x5 = x3*rad*rad;float x7 = x5*rad*rad;return x1/1-x3/6+x5/120-x7/5040; } */ /*float cos(float rad) {}*///畫圓函數 //大師寫的哦~ 膜拜 //基本沒看懂 //不記得名字了, 好像是叫Bruce...畫圓算法 void circle(int x0,int y0, int r,uint color) { int x,y,d; x=0; y=(int)r; d=(int)(3-2*r); while(x<y){ cirpot(x0,y0,x,y,color); if(d<0){ d+=4*x+6; }else{ d+=4*(x-y)+10; y--; } x++; } if(x==y) cirpot(x0,y0,x,y,color); }int cirpot(int x0,int y0,int x,int y,uint color) { set_pixel((x0+x),(y0+y), color); set_pixel((x0+y),(y0+x), color); set_pixel((x0+y),(y0-x), color); set_pixel((x0+x),(y0-y), color); set_pixel((x0-x),(y0-y), color); set_pixel((x0-y),(y0-x), color); set_pixel((x0-y),(y0+x), color); set_pixel((x0-x),(y0+y), color); return 0; } /*int abs(int a, int b) {if(a>b) return a-b;else return b-a; }*/
就這樣吧~ ?晚安~
總結
以上是生活随笔為你收集整理的三星S6D1121主控彩屏(240*320*18bit,262K)驱动程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: antd页面多表单校验
- 下一篇: android11更新了什么,一加8安卓