[转载]轻松玩转LCD12864-基于AVR单片机的LCD12864串行显示
原文鏈接:?http://bbs.elecfans.com/forum.php?mod=viewthread&tid=282698&extra=&highlight=12864&page=1
?參考帖子:http://home.eeworld.com.cn/my/space-uid-159112-blogid-40752.html
http://v.youku.com/v_show/id_XNDYwOTM2Njc2.html
LCD12864是一種常用的圖形液晶顯示模塊,顧名思義,就是可以在水平方向顯示128個點,在豎直方向顯示64個點。通過對控制芯片寫入數據,可以控制點的亮滅,從而顯示字符、數字、漢字或者自定義的圖形。盡管LCD12864有各個不同廠家生產的產品,控制芯片和引腳定義也不盡相同,但是控制原理都大同小異。本文是對我個人使用LCD12864的經驗做一個總結,希望能對入門者起到拋磚引玉的作用。 就以深圳市亞晶達電子有限公司生產的YJD12864C-1為例,我不想深究顯示屏的內部結構,單講講各個引腳的作用以及數據讀寫時的時序。 上圖是YJD12864C-1的實物圖,從右往左,1腳到20腳的定義如下: 1:VSS,接地端 2:VDD,電源正,接+5V 3:VO,對比度調整,一般接+5V就行了 4:D/I(CS*),片選,也叫使能,接+5V 5:R/W(SID*),數據輸入端 6:E(SCLK*),時鐘輸入端 7~14:DB0 ~ DB7,并行數據總線 15:PSB,串并模式選擇,串行模式下接地,并行模式下接+5V 16:NC,空引腳,不需要連接 17:RSTB,復位端,低電平有效,一般接+5V就行了 18:VEE,空引腳,不需要連接 19:BLA,背光正極,接+5V 20: BLK,背光負極,接地 在實際編程時,有串行、并行兩種模式可以選擇。個人覺得,并行模式占用單片機引腳多(11個),優點是速度快(一次傳8位數據,速度自然快),串行模式占用引腳少(2個),速度慢點。我喜歡使用串行模式,AVR單片機的時鐘頻率最快可達20MHZ(不用除以12),經過實測,從頭到尾刷一次屏大約只需0.1s,這在很多場合已經夠用了。由于并行模式用的少,不熟悉,下面只講串行模式。 在串行模式下,硬件的連接為:1、15、20接地,2、3、4、17、19接+5V,5接單片機SPI輸出(下圖第6腳),6接單片機SPI時鐘信號輸出(下圖第8腳)。 ATMEGA324引腳圖 下面介紹程序: 1、底層數據通信程序:包括SPI設置,SPI發送單字節,LCD寫數據,LCD初始化 // #define F_CPU 8//時鐘頻率8MHZ #include<ioavr.h> #include"delay.h" // 上面是開頭部分,其中delay.h內容如下: #ifndef __IAR_DELAY_H #define __IAR_DELAY_H #include <intrinsics.h> #define??delay_us(x)? ?__delay_cycles((unsigned long)(x * F_CPU)) #define??delay_ms(x)? ?__delay_cycles((unsigned long)(x * F_CPU*1000UL)) #define??delay_s(x)? ? __delay_cycles((unsigned long)(x * F_CPU*1000000UL)) #endif // SPI設置: void SPI_MasterInit(void) { DDRB=(1<<7)|(1<<5)|(1<<4);//(1<<5)|(1<<7);//設置MOSI和SCK?為輸出 SPCR = (1<<6)|(1<<4);// 1<<SPE 1<<MSTR??使能SPI,主機模式 SPSR = 1<<0;// 1<<SPI2X倍速 } // SPI發送單字節: void SPI_MasterTransmit(char cData) { SPDR = cData; while(!(SPSR & (1<<7)));//1<<SPIF } LCD寫數據: void LCD_Write (char RS,char content)//RS=1發數據RS=0發命令 {? ?? ???charStart,High4,Low4; Start=0xf8|(RS<<1); High4=content&0xf0; Low4=(content<<4)&0xf0; SPI_MasterTransmit(Start);//發送開始字節,前面5個1,倒數第二位RS SPI_MasterTransmit(High4);//發送數據高4位 SPI_MasterTransmit(Low4);//發送數據低4位 delay_us(300); } // LCD初始化 void LCD_INIT() { LCD_Write(0,0x30); /*30---基本指令動作*/ LCD_Write(0,0x01); /*清屏,地址指針指向00H*/ LCD_Write(0,0x06); /*光標的移動方向*/ LCD_Write(0,0x0c); /*開顯示,關游標*/ } // 2、應用層程序,包括漢字顯示,字符顯示,圖形顯示等等 漢字顯示: 分4行,一行可顯示8個漢字,每個漢字占16*16個格 void Show_Chinese(char x0,char y0,chark,char *chn) //x0,y0為顯示位置x0: 0~3,?y0: 0~7,?k為漢字個數,?chn為漢字數組 { charadr,i; switch(x0) { case0: adr = 0x80 + y0;break; //在第1行y列顯示 case1: adr = 0x90 + y0;break; //在第2行y列顯示 case 2: adr = 0x88 + y0;break; //在第3行y列顯示 case3: adr = 0x98 + y0;break; //在第4行y列顯示 default:; } LCD_Write(0,adr); for(i=0;i<2*k;i++) LCD_Write(1,chn); } // 顯示字符串: 分4行,一行可顯示16個漢字,每個漢字占8*16個格 void Show_String(char x0,char y0,chark,char *chn) //x0,y0為顯示位置x0: 0~8,?y0:0~3,?k為字符串個數,?chn為字符串 { ? ?? ?? ?charadr,i; ? ?? ?? ?switch(x0) ? ?? ?? ?{ ? ?? ?? ?? ?? ?? ? case0: adr = 0x80 + y0;break; //在第1行y列顯示 ? ?? ?? ?? ?? ?? ? case1: adr = 0x90 + y0;break; //在第2行y列顯示 ? ?? ?? ?? ?? ?? ? case2: adr = 0x88 + y0;break; //在第3行y列顯示 ? ?? ?? ?? ?? ?? ? case3: adr = 0x98 + y0;break; //在第4行y列顯示 ? ?? ?? ?? ?? ?? ? default:; ? ?? ?? ?} ? ?? ?? ?LCD_Write(0,0x30); ? ?? ?? ?LCD_Write(0,adr); ? ?? ?? ?for(i=0;i<k;i++) ? ?? ?? ?LCD_Write(1,chn); } // 顯示數字: void Show_Number(char x0,char y0,charnum)//顯示兩位數字 //x0,y0為顯示位置x0: 0~8,?y0:0~3,顯示數字位數可調 { ? ?? ?? ?charadr; ? ?? ?? ?switch(x0) ? ?? ?? ?{ ? ?? ?? ?? ?? ?? ? case0: adr = 0x80 + y0;break; //在第1行y列顯示 ? ?? ?? ?? ?? ?? ? case1: adr = 0x90 + y0;break; //在第2行y列顯示 ? ?? ?? ?? ?? ?? ? case2: adr = 0x88 + y0;break; //在第3行y列顯示 ? ?? ?? ?? ?? ?? ? case3: adr = 0x98 + y0;break; //在第4行y列顯示 ? ?? ?? ?? ?? ?? ? default:; ? ?? ?? ?} ? ?? ?? ?LCD_Write(0,0x30); ? ?? ?? ?LCD_Write(0,adr); ? ?? ?? ?//LCD_Write(1,num/100%10+'0'); //上句不注釋則顯示3位數字,要顯示更多位可以此類推,不過要注意num的字長 LCD_Write (1,num/10%10+'0'); ? ? LCD_Write(1,num%10+'0'); } // 顯示圖片: char lcd_x,lcd_y; void Show_Image(char *p) //水平掃描 //P含128*64/8=1024字節 //可用字模軟件獲得任意圖片的水平掃描碼 { ? ?? ?? ?chari,j,k; ? ?? ?? ?lcd_x=0x9f; ? ?? ?? ?lcd_y=0x80; ? ?? ?? ?LCD_Write(0,0x34); ? ?? ?? ?for(i=0;i<2;i++)//分為上下兩屏 ? ?? ?? ?{ ? ?? ?? ?? ?? ?? ? for(j=0;j<32;j++) ? ?? ?? ?? ?? ?? ? { ? ?? ?? ?? ?? ?? ?? ?? ?? ? LCD_Write(0,lcd_y+j); ? ?? ?? ?? ?? ?? ?? ?? ?LCD_Write (0,lcd_x); ? ?? ?? ?? ?? ?? ?? ?? ?? ? for(k=0;k<16;k++)//寫入顯示數據 ? ?? ?? ?? ?? ?? ?? ?? ?{ LCD_Write (1,*p++); } ? ?? ?? ?? ?? ?? ? } ? ?? ?? ?? ?? ?? ? lcd_x=0x87; ? ?? ?? ?} ? ?? ?? ?LCD_Write(0,0x36); ? ?? ?? ?LCD_Write(0,0x30); } 圖片模式下清屏: void Clear_Gcrom() { ? ?? ?? ?chari,j,k; ? ?? ? lcd_x=0x80; ? ?? ? lcd_y=0x80; ? ?? ? LCD_Write (0,0x34); ? ?? ?? ?for(i=0;i<2;i++) ? ?? ?? ?{ ? ?? ?? ?? ?? ?? ? for(j=0;j<32;j++) ? ?? ?? ?? ?? ?? ? { ? ?? ?? ?? ?? ?? ?? ?? ?? ? LCD_Write(0,lcd_y+j); ? ?? ?? ?? ?? ?? ?? ?? ?LCD_Write (0,lcd_x); ? ?? ?? ?? ?? ?? ?? ?? ?? ? for(k=0;k<16;k++){ LCD_Write (1,0x00); } ? ?? ?? ?? ?? ?? ? } ? ?? ?? ?lcd_x=0x88; ? ?? ?? ?} ? ?? ?? ?LCD_Write(0,0x36); ? ?? ?? ?LCD_Write(0,0x30); } 顯示兩字節,LCD12864每次至少刷新16格: void Show_2Byte(char x,char y,chardat1,char dat2)// x:0~7 y:0~63 { if(y<32)//下屏 ??{ ? ?x+=8; ? ?y=31-y; ??} else//上屏 ??{ ? ?y=63-y; ??} LCD_Write (0,0x34); LCD_Write (0,0x80+y);//y:0~31 LCD_Write (0,0x80+x);//x:0~15 LCD_Write (1,dat1); LCD_Write (1,dat2); LCD_Write (0,0x36); LCD_Write (0,0x30); } 刷新1行: void Show_Hang(char y,char p[64][16]) //顯示一行?y:0~63 { ? ?? ?? ?chark,y0=y;?? ? ?? ?? ?lcd_y=0x80; ? ?? ?? ?LCD_Write(0,0x34); ? ?? ?? ?if(y<32) ? ?? ? { ? ?? ?? ?lcd_x=0x80+8;//下屏 ? ?? ?? ?y=31-y; ? ?? ? } ? ?? ? else ? ?? ? { ? ?? ?? ?lcd_x=0x80;//上屏 ? ?? ?? ?y=63-y; ? ?? ?? ?} ? ?? ?? ?//LCD_Write(0,0x80+0);//y1:0~31 ? ?? ? //LCD_Write (0,0x80+0);//x1:0~15 ? ?? ? LCD_Write (0,lcd_y+y); ? ?? ? LCD_Write (0,lcd_x); ? ?? ?? ?for(k=0;k<16;k++)//寫入顯示數據 ? ?? ? { LCD_Write (1,p[y0][k]); } ? ?? ?? ?LCD_Write(0,0x36); ? ?? ?? ?LCD_Write(0,0x30); } 有了以上函數就可以輕松玩轉LCD12864了,注意在main函數中應先執行初始化程序: void main()
{
SPI_MasterInit();?
LCD_INTI ();
while(1)
{
}
}
最后是我用ATMEGA324PA單片機和LCD12864做的一個貪吃蛇游戲,見開頭視頻。
全部程序如下:
/***********************************************************************
LCD12864貪吃蛇
貪吃蛇游戲(不死版)
單片機:ATMEGA324PA
編程軟件:IAR
編程語言:C++
屏幕:LCD12864
按鍵:上下左右
***********************************************************************/
<main.cpp>:
#define F_CPU 8
#include"delay.h"
#include <stdlib.h>
#include <math.h>
#include<ioavr.h>
#include "function.h"
#define K0 PINA_Bit0
#define K1 PINA_Bit1
#define K2 PINA_Bit2
#define K3 PINA_Bit3
#define K4 PINA_Bit4
#define K5 PINA_Bit5
class Point{
public:
??char x;//x:0~127
??char y;//y:0~63
??Point(){};
??Point(char m,char n){x=m;y=n;}
??bool operator==(Point &a)
??{
? ? if(x==a.x&&y==a.y)return true;
? ? else return false;
??}
??//char Get_x(){return x;}
??//char Get_y(){return y;}??
};
class Snake{
public:
??char length;
??Point body[64];//頭:body[0]尾:body[length-1] 其余:空
??Point food;
??Snake()
??{
? ? length=3;
? ? for(char i=0;i<64;i++)body=Point(0,0);
? ? body[0]=Point(64,33);
? ? body[1]=Point(64,32);
? ? body[2]=Point(64,31);
??}
??void Go_ahead();
??//void Go_back();
??void Turn_left();
??void Turn_right();
??void Turn_up();
??void Turn_down();
??void Generate_food();
??void Eat();
??void Restart();
??bool Near_food();
??char Get_direction();
??void Refresh(Point p);
};
void Snake::Go_ahead()
{
??Point temp=body[0],temp1=body[length-1];
??char v=Get_direction();
??switch(v)
??{
??case 0:
? ? if(body[0].y==63)Restart();
? ? else body[0].y++;break;
??case 1:
? ? if(body[0].y==0)Restart();
? ? else body[0].y--;break;
??case 2:
? ? if(body[0].x==0)Restart();
? ? else body[0].x--;break;?
??case 3:
? ? if(body[0].x==127)Restart();
? ? else body[0].x++;break;
??default:break;
??}
??if(body[0].x==food.x&&body[0].y==food.y)
??{
? ? length++;
? ? for(char i=length-1;i>1;i--)
? ? {
? ?? ?body=body[i-1];
? ? }
? ? body[1]=temp;
? ? Generate_food();
??}
??else?
??{
? ? for(char i=length-1;i>1;i--)
? ? {
? ?? ?body=body[i-1];
? ? }
? ? body[1]=temp;
??}
??Refresh(body[0]);
??Refresh(temp1);
}
void Snake::Turn_left()
{
??Point temp1=body[length-1];
??for(char i=length-1;i>0;i--)
??{
? ? body=body[i-1];
??}
??if(body[0].x==0)Restart();
??else body[0].x--;?
??Refresh(body[0]);
??Refresh(temp1);
}
void Snake::Turn_right()
{
??Point temp1=body[length-1];
??for(char i=length-1;i>0;i--)
??{
? ? body=body[i-1];
??}
??if(body[0].x==127)Restart();
??else body[0].x++;
??Refresh(body[0]);
??Refresh(temp1);?
}
void Snake::Turn_up()
{
??Point temp1=body[length-1];
??for(char i=length-1;i>0;i--)
??{
? ? body=body[i-1];
??}
??if(body[0].y==63)Restart();
??else body[0].y++;
??Refresh(body[0]);
??Refresh(temp1);
}
void Snake::Turn_down()
{
??Point temp1=body[length-1];
??for(char i=length-1;i>0;i--)
??{
? ? body=body[i-1];
??}
??if(body[0].y==0)Restart();
??else body[0].y--;
??Refresh(body[0]);
??Refresh(temp1);??
}
void Snake::Generate_food()
{
??char x,y,i=0;
??while(i!=length)
??{ x=rand()%128;
? ? y=rand()%64;
? ? food=Point(x,y);
? ? for(i=0;i<length;i++)
? ? {
? ?? ?if(food==body)break;
? ? }
??}
??Refresh(food);
}
bool Snake::Near_food()
{
??bool k;
??if(body[0].x==food.x&&body[0].y==food.y)
? ? k=true;
??else k=false;
??return k;
}
void Snake::Eat()
{
??for(char i=length;i>0;i--)
??{
? ? body=body[i-1];
??}
??body[0]=food;
??length++;
??Generate_food();
}
//enum direction{up,down,left,right}
char Snake::Get_direction()
{
??char i;
??if(body[0].x==body[1].x)
??{
? ? if(body[0].y>body[1].y){i=0;}
? ?? ?else i=1;
??}
??else
??{
? ? if(body[0].x>body[1].x){i=3;}
? ?? ?else i=2;
??}
??return i;
}
void Snake::Refresh(Point p)
{
??char temp1=0,temp2=0,a,b,c;??
??for(char i=0;i<2;i++)
??{
? ? a=p.x-p.x%8;
? ? if((p.x/8)%2==0)
? ? {
? ?? ?b=a+8;
? ?? ?c=b+8;
? ? }
? ? else
? ? {
? ?? ?b=a;
? ?? ?a-=8;
? ?? ?c=b+8;
? ? }
? ? for(char i=0;i<length;i++)
? ? {
? ?? ?if(body.y==p.y)
? ?? ?{
? ?? ???if(body.x>=a&&body.x<b)temp1|=(1<<7-body.x%8);
? ?? ???if(body.x>=b&&body.x<c)temp2|=(1<<7-body.x%8);
? ?? ?}
? ?? ?if(food.y==p.y)
? ?? ?{
? ?? ???if(food.x>=a&&food.x<b){temp1|=(1<<7-food.x%8);}
? ?? ???if(food.x>=b&&food.x<c){temp2|=(1<<7-food.x%8);}
? ?? ?}? ?? ?
? ? }
? ? Show_2Byte(p.x/16,p.y,temp1,temp2);
??}
}
void WDT_off(void)
{
??__disable_interrupt();
??__watchdog_reset();
??/* Clear WDRF in MCUSR */
??MCUSR &= ~(1<<WDRF);
??/* Write logical one to WDCE and WDE */
??/* Keep old prescaler setting to prevent unintentional time-out */
??WDTCSR |= (1<<WDCE) | (1<<WDE);
??/* Turn off WDT */
??WDTCSR = 0x00;
??__enable_interrupt();
}
void WDT_Prescaler_Change(void)
{
??__disable_interrupt();
??__watchdog_reset();
??/* Start timed equence */
??WDTCSR |= (1<<WDCE) | (1<<WDE);
??/* Set new prescaler(time-out) value = 64K cycles (~16 ms) */
??WDTCSR = (1<<WDE);
??__enable_interrupt();
}
void Snake::Restart()
{??
??//WDT_Prescaler_Change();
}
void main()
{
??WDT_off();
??Snake Snake1;
??DDRB=0xff;
??PORTA=0x00;
??DDRA=0x00;
??SPI_MasterInit();
??LCD_INIT();
??Clear_Gcrom();
??Snake1.Generate_food();
??while(1)
??{
? ? {
? ?? ?delay_ms(50);
? ?? ?Snake1.Go_ahead();
? ?? ?if(!K2)
? ?? ?{
? ?? ???Snake1.Turn_left();
? ?? ?}
? ?? ?if(!K3)
? ?? ?{
? ?? ???Snake1.Turn_up();
? ?? ?}
? ?? ?if(!K4)
? ?? ?{
? ?? ???Snake1.Turn_right();
? ?? ?}
? ?? ?if(!K5)
? ?? ?{
? ?? ???Snake1.Turn_down();
? ?? ?}? ?? ?
? ?? ?//if(Snake1.body[0].x<0||Snake1.body[0].x>127||Snake1.body[0].y<0||
Snake1.body[0].y>63)
? ?? ?//Snake1.Die();
? ? }
??}
}
///
<LCD12864.c>:
#define F_CPU 8
#include<ioavr.h>
#include"delay.h"
void SPI_MasterInit(void)
{
??/* Set MOSI and SCK output, all others input */
??//DDRB =(1<<7)|(1<<5)|(1<<4);//(1<<5)|(1<<7);
??/* Enable SPI, Master, set clock rate fck/16 */
??SPCR = (1<<6)|(1<<4);//|(1<<1)|0x01;//1<<SPE 1<<MSTR 1<<SPR1//128分頻
??SPSR = 1<<0;//SPI2X倍速
}
void SPI_MasterTransmit(char cData)
{
??/* Start transmission */
??SPDR = cData;
??/* Wait for transmission complete */
??while(!(SPSR & (1<<7)));//1<<SPIF
}
void LCD_Write (char RS,char content)
{? ?? ???char Start,High4,Low4;
? ?? ???Start=0xf8|(RS<<1);
? ?? ???High4=content&0xf0;
? ?? ???Low4=(content<<4)&0xf0;
? ?? ???//SS=1;
? ?? ???SPI_MasterTransmit(Start);
? ?? ???SPI_MasterTransmit(High4);
? ?? ???SPI_MasterTransmit(Low4);
? ?? ???//SS=0;
? ?? ???delay_us(300);
}
/*-----------------------------------*/
void LCD_INIT(void)
{
? ?? ???LCD_Write (0,0x30); /*30---基本指令動作*/?
? ?? ???LCD_Write (0,0x01); /*清屏,地址指針指向00H*/
? ?? ???LCD_Write (0,0x06); /*光標的移動方向*/
? ?? ???LCD_Write (0,0x0c); /*開顯示,關游標*/
}
/*--------------清DDRAM------------------*/
void ClearRam(void)
{
? ?? ???LCD_Write (0,0x30);
? ?? ???LCD_Write (0,0x01);
}
char lcd_x,lcd_y;
void Clear_Gcrom()?
{
? ?? ???char i,j,k;?
? ?? ???lcd_x=0x80;?
? ?? ???lcd_y=0x80;?
? ?? ???LCD_Write (0,0x34);?
? ?? ???for(i=0;i<2;i++)?
? ?? ???{?
? ?? ?? ?? ?? ? for(j=0;j<32;j++)?
? ?? ?? ?? ?? ? {
? ?? ?? ?? ?? ?? ?? ?? ?LCD_Write (0,lcd_y+j);?
? ?? ?? ?? ?? ?? ?? ?? ?LCD_Write (0,lcd_x);?
? ?? ?? ?? ?? ?? ?? ?? ?for(k=0;k<16;k++) { LCD_Write (1,0x00); }?
? ?? ?? ?? ?? ? }?
? ?? ???lcd_x=0x88;?
? ?? ???}?
? ?? ???LCD_Write (0,0x36);?
? ?? ???LCD_Write (0,0x30);?
}
void Show_2Byte(char x,char y,char dat1,char dat2)// x:0~7 y:0~63
{
??if(y<32)//下屏
??{
? ? x+=8;
? ? y=31-y;
??}
??else//上屏
??{
? ? y=63-y;
??}
??LCD_Write (0,0x34);
??LCD_Write (0,0x80+y);//y:0~31
??LCD_Write (0,0x80+x);//x:0~15
??LCD_Write (1,dat1);
??LCD_Write (1,dat2);
??LCD_Write (0,0x36);?
??LCD_Write (0,0x30);?
}
void Show_Hang(char y,char p[64][16]) //顯示一行 y:0~63
{?
? ?? ???char k,y0=y;??
? ?? ???lcd_y=0x80;?
? ?? ???LCD_Write (0,0x34);?
? ?? ???if(y<32)
? ?? ???{
? ?? ?? ? lcd_x=0x80+8;//下屏
? ?? ?? ? y=31-y;
? ?? ???}
? ?? ???else?
? ?? ???{
? ?? ?? ? lcd_x=0x80;//上屏
? ?? ?? ? y=63-y;
? ?? ???}?
? ?? ???//LCD_Write (0,0x80+0);//y1:0~31
? ?? ???//LCD_Write (0,0x80+0);//x1:0~15
? ?? ???LCD_Write (0,lcd_y+y);
? ?? ???LCD_Write (0,lcd_x);?
? ?? ???for(k=0;k<16;k++) //寫入顯示數據?
? ?? ???{ LCD_Write (1,p[y0][k]); }?
? ?? ???LCD_Write (0,0x36);?
? ?? ???LCD_Write (0,0x30);?
}?
//
<delay.h>:
#ifndef __IAR_DELAY_H
#define __IAR_DELAY_H
#include <intrinsics.h>
#define? ?delay_us(x)? ?__delay_cycles ((unsigned long)(x * F_CPU))?
#define? ?delay_ms(x)? ?__delay_cycles ((unsigned long)(x * F_CPU*1000UL))
#define? ?delay_s(x)? ? __delay_cycles ((unsigned long)(x * F_CPU*1000000UL))
#endif?
//
<function.h>:
#ifndef _FUNCTION_INCLUDED
#define _FUNCTION_INCLUDED
extern void Show_Hang(char y,char p[64][16]); //顯示一行 y:0~63
extern void LCD_INIT(void);
extern void Clear_Gcrom();
extern void ClearRam(void);
extern void SPI_MasterInit(void);
extern void Show_2Byte(char x,char y,char dat1,char dat2);// x:0~7 y:0~63
#endif
轉載于:https://www.cnblogs.com/watson8544/p/5581330.html
總結
以上是生活随笔為你收集整理的[转载]轻松玩转LCD12864-基于AVR单片机的LCD12864串行显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用的命令安装
- 下一篇: python (16) 如何在linux