因為這段特殊時期的原因,沒辦法回學(xué)校拿硬件,自然也就沒辦法調(diào)試,雖然硬件電路都搭好了,但沒法調(diào)試也就意味著不知道程序編寫是否有問題,所以就想著在protues上把硬件電路搭起來調(diào)試程序,因為單片機用的是stc的所以protues中直接用AT的就行了,但是到了12864液晶屏這部分就犯難了,protues庫中的液晶屏有好多種,而自己不確定用哪一種。最直接的方法就是問百度,但是百度上大多都是并行接口的方式搭建的電路,而我的實際電路用的是串行的(大家都懂得,實際電路中I/O口除非必要能省就省)。
無奈之下,只能自己研究,然后用了一兩個小時把問題的關(guān)鍵破解了,成功的實現(xiàn)串行通信控制12864液晶屏。不知道是這個太簡單了還是并行通信在這一問題上太過主流了,網(wǎng)上很少有這部分教程,所以今天就做個記錄。
實際電路中用的是一款國產(chǎn)的液晶屏,protues中用的是HDG1286F這個系列的液晶屏。經(jīng)過一番思考,很快就找到了問題的關(guān)鍵,驅(qū)動IC,LCD顯示的方式都是點陣這個沒什么好區(qū)別的,唯一有區(qū)別的是驅(qū)動IC,于是便找到了HDG12864F所使用的驅(qū)動IC-SED1565的數(shù)據(jù)手冊。
取下面兩款液晶屏來說,parallel data input是并行數(shù)據(jù)輸入,selectable lnterface是可選接口的意思,也就是說選擇parallel data input也就是第三款只能是并行接口,選擇selectable lnterface第四款才能有串并行選擇。這兩款的區(qū)別在硬件上就是第四款多了個P/S引腳。如下圖是數(shù)據(jù)手冊中對于P/S引腳的描述。
。
這里也給出兩款液晶屏在引腳上的對應(yīng)關(guān)系(串行模式下),如下圖所示,左邊是仿真中的引腳資料,右邊是實際硬件的液晶引腳資料。
protues中實際接線圖如下所示,懸空部分為不需要接的。
下邊附上液晶屏的初始化函數(shù)以及數(shù)字顯示函數(shù)
單片機源程序如下:
- #include <12864.h>
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- //小四號 ,縱向倒序
- sbit rs=P1^2; //RS
- sbit reset=P2^0; //RST
- sbit cs1=P2^1; //CS
- sbit sid=P2^2; //D7
- sbit sclk=P2^3; //D6
- unsigned char code LCD_charNumber[11][7]=
- {
- {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00},//0
- {0x00,0x00,0x42,0x7F,0x40,0x00,0x00},//1
- {0x00,0x42,0x61,0x51,0x49,0x46,0x00},//2
- {0x00,0x21,0x41,0x45,0x4B,0x31,0x00},//3
- {0x00,0x18,0x14,0x12,0x7F,0x10,0x00},//4
- {0x00,0x27,0x45,0x45,0x45,0x39,0x00},//5
- {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00},//6
- {0x00,0x01,0x01,0x79,0x05,0x03,0x00},//7
- {0x00,0x36,0x49,0x49,0x49,0x36,0x00},//8
- {0x00,0x06,0x49,0x49,0x29,0x1E,0x00},//9
- {0x00,0x66,0x16,0x08,0x34,0x33,0x00}, /*% 有待修改65*/
- };
- unsigned char code beijinghanzi[14][16]={ //背景漢字,微軟雅黑,小四號
- {0x40,0x42,0xC6,0x0C,0x08,0x00,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x7C,0x00},
- {0x00,0x00,0x7F,0x20,0x10,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x30,0x08}, //“記”字代碼
- {0x00,0x40,0x42,0x52,0x52,0x52,0x52,0x52,0xD2,0x52,0x52,0x52,0x7E,0x40,0x40,0x40},
- {0x00,0x10,0x11,0x11,0x0A,0x48,0x44,0x44,0x3F,0x06,0x0C,0x0A,0x12,0x11,0x20,0x00}, //“錄”字代碼
- {0x00,0x00,0xFE,0x02,0x02,0x12,0x22,0x42,0x82,0xC2,0x62,0x12,0x0A,0x02,0x02,0x00},
- {0x00,0x00,0x3F,0x20,0x28,0x24,0x22,0x23,0x21,0x21,0x23,0x26,0x24,0x20,0x20,0x00}, //“區(qū)”字代碼
- {0x00,0x30,0x18,0xCC,0x22,0x00,0x2C,0x52,0x52,0x52,0x52,0x52,0x52,0x7E,0x00,0x00},
- {0x00,0x02,0x01,0x7E,0x00,0x08,0x19,0x29,0x09,0x89,0x89,0x89,0xFF,0x09,0x09,0x08}, //“得”字代碼
- {0x80,0x80,0x40,0x20,0x10,0x0C,0x02,0x00,0x00,0x02,0x0C,0x10,0x20,0x40,0x80,0x00},
- {0x00,0x80,0x41,0x41,0x21,0x1F,0x01,0x81,0x81,0x81,0x81,0x7D,0x02,0x00,0x00,0x00}, //“分”字代碼
- {0x80,0x80,0x80,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xBE,0x80,0x80},
- {0x20,0x20,0x3F,0x2A,0x2A,0x2A,0x2A,0x7F,0x62,0x46,0x2A,0x32,0x32,0x2A,0x46,0x40}, //“最”字代碼
- {0x04,0x04,0x04,0x74,0x54,0x54,0x54,0x56,0x56,0x54,0x54,0x54,0x74,0x04,0x04,0x04},
- {0x00,0x7F,0x01,0x01,0x3D,0x15,0x15,0x15,0x15,0x15,0x5D,0x41,0x41,0x41,0x7F,0x00}, //“高”字代碼
- };
- unsigned char code defen[6][16]={
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//空白
- {0x00,0x10,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x10,0x18,0x14,0x12,0x11,0x10,0x00},//"2"
- {0x00,0x80,0x40,0x20,0x10,0xF8,0x00,0x00,0x03,0x02,0x02,0x02,0x02,0x1F,0x02,0x00},//"4"
- {0x00,0xE0,0x90,0x88,0x88,0x88,0x00,0x00,0x00,0x0F,0x10,0x10,0x10,0x10,0x0F,0x00},//"6"
- {0x00,0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x00,0x0F,0x10,0x10,0x10,0x10,0x0F,0x00},//"8"
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//空白
- };
- unsigned char code maohao[]={0x00,0x00,0x30,0x30,0x00,0x00};//冒號
- //*****************MS**************//
- void delay(int i)
- { int j,k;
- for(j=0;j<i;j++)
- for(k=0;k<990;k++);
- }
- //*****************US****************//
- void delay1(int i)
- { int j,k;
- for(j=0;j<i;j++)
- for(k=0;k<10;k++);
- }
- //***************寫命令************//
- void transfer_command(int data1)
- { char i;
- cs1=0;
- rs=0;
- for(i=0;i<8;i++)
- { sclk=0;
- if(data1&0x80) sid=1;
- else sid=0;
- delay1(5);
- sclk=1;
- delay1(5);
- data1=data1<<=1;
- }
- }
- //****************寫數(shù)據(jù)*************//
- void transfer_data(int data1)
- { char i;
- cs1=0;
- rs=1;
- for(i=0;i<8;i++)
- { sclk=0;
- if(data1&0x80) sid=1;
- else sid=0;
- sclk=1;
- data1=data1<<=1;
- }
- }
- //*****************清屏****************//
- void clear_screen(void)
- { unsigned char i,j;
- for(i=0;i<9;i++)
- { cs1=0;
- transfer_command(0xb0+i);
- transfer_command(0x10);
- transfer_command(0x00);
- for(j=0;j<132;j++) transfer_data(0x00);
- }
- }
- //***************LCD 初始化**************//
- void initial_lcd(void)
- { reset=0; /*低電平復(fù)位*/
- delay(20);
- reset=1; /*復(fù)位完畢*/
- delay(20);
- transfer_command(0xe2); /*軟復(fù)位*/
- delay(5);
- transfer_command(0x2c); /*升壓步聚 1*/
- delay(5);
- transfer_command(0x2e); /*升壓步聚 2*/
- delay(5);
- transfer_command(0x2f); /*升壓步聚 3*/
- delay(5);
- transfer_command(0x23); /*粗調(diào)對比度,可設(shè)置范圍 0x20~0x27*/
- transfer_command(0x81); /*微調(diào)對比度*/
- transfer_command(0x1f); /*微調(diào)對比度的值,可設(shè)置范圍 0x00~0x3f*/
- transfer_command(0xa2); /*1/9 偏壓比(bias)*/
- transfer_command(0xc0); /*行掃描順序:從上到下,0是上下,8是下上*/
- transfer_command(0xa1); /*列掃描順序:從左到右,0是左右,1是右左*/
- transfer_command(0xa6); /*正反顯示,7是高亮顯示,6是暗顯示*/
- transfer_command(0x60); /*起始行:第一行開始*/
- transfer_command(0xaf); /*開顯示*/
- }
- //==================顯示分數(shù)===============//
- void lcd12864_disp(uchar num,uchar num2)
- { char i,n;
- if(num2==0) n = 3;
- else n=0;
- num = num/2;
- transfer_command(0x13); //設(shè)置列地址的高4位
- transfer_command(0x00); //設(shè)置列地址的低4位
- transfer_command(0xb2+n); //設(shè)置頁地址
- for(i=0;i<8;i++) transfer_data(defen[num][i]);
- transfer_command(0x13); //設(shè)置列地址的高4位
- transfer_command(0x00); //設(shè)置列地址的低4位
- transfer_command(0xb3+n); //設(shè)置頁地址
- for(i=8;i<16;i++) transfer_data(defen[num][i]);
-
- }
- //*********************顯示數(shù)組***************//
- void lcd12864_disp1(int num,unsigned int LINE_start,unsigned char ROW_start)
- //要顯示的數(shù)字------- 第幾行(0-7)開始----第幾個列字符位置開始(0-17)
- { unsigned int byte;
- unsigned char column_add_L,column_add_H;
- LINE_start = 0xb0 + LINE_start;
- ROW_start = ROW_start * 7; //+1
- column_add_L =ROW_start&0x0f;
- column_add_H =((ROW_start>>4)&0x0f)+0x10;
- cs1 = 0;
- transfer_command(LINE_start); //設(shè)置頁地址
- transfer_command(column_add_H); //設(shè)置列地址的高4位
- transfer_command(column_add_L); //設(shè)置列地址的低4位
- for(byte=0;byte<7;byte++) transfer_data(LCD_charNumber[num] [byte] );
- }
- void back(void)
- { uchar i,j;
- //顯示“記錄區(qū)”三字
- for(j=0;j<6;j++){
- transfer_command(0x14); //設(shè)置列地址的高4位
- transfer_command(0x00); //設(shè)置列地址的低4位
- transfer_command(0xb2+j); //設(shè)置頁地址
- for(i=0;i<16;i++) transfer_data(beijinghanzi[j][i]);}
- //顯示“得分:”字樣
- transfer_command(0x10); //設(shè)置列地址的高4位
- transfer_command(0x08); //設(shè)置列地址的低4位
- transfer_command(0xb2); //設(shè)置頁地址
- for(i=0;i<16;i++) transfer_data(beijinghanzi[6][i]);
- for(i=0;i<16;i++) transfer_data(beijinghanzi[8][i]);
- for(i=0;i<6;i++) transfer_data(maohao[i]);
- transfer_command(0x10); //設(shè)置列地址的高4位
- transfer_command(0x08); //設(shè)置列地址的低4位
- transfer_command(0xb3); //設(shè)置頁地址
- for(i=0;i<16;i++) transfer_data(beijinghanzi[7][i]);
- for(i=0;i<16;i++) transfer_data(beijinghanzi[9][i]);
- for(i=0;i<6;i++) transfer_data(maohao[i]);
- //顯示“最高:”字樣
- transfer_command(0x10); //設(shè)置列地址的高4位
- transfer_command(0x08); //設(shè)置列地址的低4位
- transfer_command(0xb5); //設(shè)置頁地址
- for(i=0;i<16;i++) transfer_data(beijinghanzi[10][i]);
- for(i=0;i<16;i++) transfer_data(beijinghanzi[12][i]);
- for(i=0;i<6;i++) transfer_data(maohao[i]);
- transfer_command(0x10); //設(shè)置列地址的高4位
- transfer_command(0x08); //設(shè)置列地址的低4位
- transfer_command(0xb6); //設(shè)置頁地址
- for(i=0;i<16;i++) transfer_data(beijinghanzi[11][i]);
- for(i=0;i<16;i++) transfer_data(beijinghanzi[13][i]);
- for(i=0;i<6;i++) transfer_data(maohao[i]);
- //顯示各通道分值
- lcd12864_disp1(8,0,2);
- lcd12864_disp1(6,0,4);
- lcd12864_disp1(4,0,6);
- lcd12864_disp1(2,0,8);
- lcd12864_disp1(2,0,10);
- lcd12864_disp1(4,0,12);
- lcd12864_disp1(6,0,14);
- lcd12864_disp1(8,0,16);
- }
復(fù)制代碼 |