標(biāo)題:
LCD12864顯示程序和模擬時鐘
[打印本頁]
作者:
蛀牙算法
時間:
2016-3-20 23:00
標(biāo)題:
LCD12864顯示程序和模擬時鐘
效果圖如下所示:
7.jpg
(58.3 KB, 下載次數(shù): 181)
下載附件
2016-3-21 01:11 上傳
8.jpg
(18.9 KB, 下載次數(shù): 193)
下載附件
2016-3-21 01:11 上傳
注:沒怎么發(fā)過帖子,所以不知道怎么跟大家講這些東西,能用代碼的直接粘代碼了。因?yàn)樽约焊杏X這些東西很好玩,所以想跟大家分享一下,如果有什么不懂,可以留言
一些資料:
code1模擬時鐘.rar
(44.46 KB, 下載次數(shù): 190)
2016-3-21 01:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
LCD12864是個好東西,之前介紹了用LCD12864顯示一個簡易的動畫,以及用LCD12864做一個俄羅斯方塊游戲,今天再介紹一點(diǎn)其他的好玩的東西-----用LCD12864做一個模擬指針式時鐘。用LCD12864做一個模擬指針式時鐘,其實(shí)主要用的是LCD12864(ST7920)的繪圖功能:
1.利用圓心坐標(biāo)和半徑畫一個圓作為表盤
2.利用兩點(diǎn)間畫線功能畫出時分秒指針。
讓我們一起來做一個LCD12864模擬指針式時鐘,Let\'s GO!!
LCD12864的底層驅(qū)動很簡單,利用時序圖可以輕松解決,這部分就跳過了。所以,我們首先要解決的是如何畫圓。我在查找資料時,發(fā)現(xiàn)有好幾種方法,我使用的是這種:
/****************************************
對稱法畫圓的8個鏡像點(diǎn)
*****************************************/
void CircleDot(unsigned char x,unsigned char y,char xx,char yy,unsigned char Color)//內(nèi)部函數(shù),對稱法畫圓的8個鏡像點(diǎn)
{
Lcd_PutPixel((x+yy),(y+xx),Color);//第 1 個 8 分圓
Lcd_PutPixel((x+xx),(y+yy),Color);//第 2 個 8 分圓
Lcd_PutPixel((x-xx),(y+yy),Color);//第 3 個 8 分圓
Lcd_PutPixel((x-yy),(y+xx),Color);//第 4 個 8 分圓
Lcd_PutPixel((x-yy),(y-xx),Color);//第 5 個 8 分圓
Lcd_PutPixel((x-xx),(y-yy),Color);//第 6 個 8 分圓
Lcd_PutPixel((x+xx),(y-yy),Color);//第 7 個 8 分圓
Lcd_PutPixel((x+yy),(y-xx),Color);//第 8 個 8 分圓
}
/******************************************
向LCD指定圓心坐標(biāo)畫一個半徑為r的指定顏色的圓
*******************************************/
void Lcd_Circle(unsigned char x,unsigned char y,unsigned char r,unsigned char Color)//中點(diǎn)法畫圓
{//中點(diǎn)法畫圓
unsigned char xx,yy;
char deltax,deltay,d;
xx=0;
yy=r;
deltax=3;
deltay=2-r-r;
d=1-r;
CircleDot(x,y,xx,yy,Color);//對稱法畫圓的8個鏡像點(diǎn)
while (xx
{
if (d<0)
{
d+=deltax;
deltax+=2;
xx++;
}
else
{
d+=deltax+deltay;
deltax+=2;
deltay+=2;
xx++;
yy--;
}
CircleDot(x,y,xx,yy,Color);//對稱法畫圓的8個鏡像點(diǎn)
}
}
利用畫圓函數(shù)可以先畫出時鐘的表盤,下一步,我們得再畫出時分秒的指針。畫時分秒的指針其實(shí)用到的是任意兩點(diǎn)間畫一條線這個功能,如何實(shí)現(xiàn)呢?答案是:布蘭森漢姆(Bresenham)算法畫線!在畫線、畫圓中經(jīng)常會用到Bresenham算法,Bresenham算法是什么?如果你感興趣的話,可以先搜一下,網(wǎng)上關(guān)于這個的介紹很多很多,我就不介紹了,上代碼:
/*******************************************
向LCD指定起始坐標(biāo)和結(jié)束坐標(biāo)之間畫一條指定顏色的直線
********************************************/
void Lcd_Line(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char Color)
{
unsigned int x,y;
unsigned int d_x,d_y;//d_x=x2-x1;d_y=y2-y1;
int err=0;
unsigned char temp=0;
if(y2
{
x=x1;
y=y1;
x1=x2;
y1=y2;
x2=x;
y2=y;
}
d_y=y2-y1;
if (d_y==0)
{
if (x1>x2)
{
x=x1;
x1=x2;
x2=x;
}
for (x=x1;x<=x2;x++)
Lcd_PutPixel(x,y1,Color);
}
else
{
if(x2>=x1)
{
temp=1;
d_x=x2-x1;
}
else
d_x=x1-x2;
x=x1;
y=y1;
Lcd_PutPixel(x,y,Color);
if(temp&&(d_y<=d_x))
while(x!=x2)
{
if(err<0)
{
x=x+1;
err=err+(y2-y);
}
else
{
x=x+1;
y=y+1;
err=err+(y2-y)-(x2-x);
}
Lcd_PutPixel(x,y,Color);
}
else if(temp&&(d_y>d_x))
while(y!=y2)
{
d_x=x2-x;
d_y=y2-y;
if(err<0)
{
x=x+1;
y=y+1;
err=err+d_y-d_x;
}
else
{
y=y+1;
err=err-d_x;
}
Lcd_PutPixel(x,y,Color);
}
else if(!temp&&(d_y<=d_x))
while(x!=x2)
{
d_x=x-x2;
d_y=y2-y;
if(err<0)
{
x=x-1;
err=err+d_y;
}
else
{
x=x-1;
y=y+1;
err=err+d_y-d_x;
}
Lcd_PutPixel(x,y,Color);
}
else if(!temp &&(d_y>d_x))
{
while(y!=y2)
{
d_x=x-x2;
d_y=y2-y;
if(err<0)
{
x=x-1;
y=y+1;
err=err+d_y-d_x;
}
else
{
y=y+1;
err=err-d_x;
}
Lcd_PutPixel(x,y,Color);
}
}
}
}
有了畫線的方法,我們還不能畫出時分秒指針,因?yàn)楫嬀需要起點(diǎn)坐標(biāo)和末點(diǎn)坐標(biāo)。指針是從圓心這一點(diǎn)指向這一刻時間的一條線,起點(diǎn)坐標(biāo)有了,就是圓盤的圓心坐標(biāo),但是末點(diǎn)坐標(biāo)不知道。比如1秒,秒針由圓心坐標(biāo)指向1秒的位置,這個1秒的位置在哪??我們可以由圓心坐標(biāo)和半徑,以及時間的角度算出:
/***************************************************
函數(shù)名稱:LcdTimeX(uint8 Length,uint8 Angle)
函數(shù)功能:計(jì)算指針的X坐標(biāo)
輸入?yún)?shù):circle_x:圓心橫坐標(biāo)
Length :半徑長度
Angle :角度
輸出參數(shù): x坐標(biāo)
****************************************************/
unsigned char Lcd_TimeX(unsigned char circle_x,unsigned char Length,unsigned char Angle)
{
unsigned char x;
if((Angle>0) && (Angle<=15))
{
x = circle_x + Length * (sin(PI * Angle / 30));
}
else if(Angle > 15 && Angle <= 30)
{
x = circle_x + Length * cos((PI * Angle) / 30 - (PI / 2 ));
}
else if(Angle > 30 && Angle <= 45)
{
x = circle_x - Length * sin((PI * Angle) / 30- PI);
}
else
{
x = circle_x-Length * cos((PI * Angle) / 30 - ((3 * PI) / 2));
}
return x;
}
/***************************************************
函數(shù)名稱:LcdTimeY(uint8 Length,uint8 Angle)
函數(shù)功能:計(jì)算指針的Y坐標(biāo)
輸入?yún)?shù):circle_y:圓心縱坐標(biāo)
Length :半徑長度
Angle :角度
輸出參數(shù): Y坐標(biāo)
****************************************************/
unsigned char Lcd_TimeY(unsigned char circle_y,unsigned char Length,unsigned char Angle)
{
unsigned char y;
if((Angle>0) && (Angle<=15))
{
y = circle_y - Length * (cos(PI * Angle / 30));
}
else if(Angle > 15 && Angle <= 30)
{
y = circle_y + Length * sin((PI * Angle) / 30 - (PI / 2 ));
}
else if(Angle > 30 && Angle <= 45)
{
y = circle_y + Length * cos((PI * Angle) / 30- PI);
}
else
{
y = circle_y - Length * sin((PI * Angle) / 30 - ((3 * PI) / 2));
}
return y;
}
好了,所有的東西都準(zhǔn)備齊全了,開工!!
先畫表盤:
void init_Point_Clock() //初始化表盤
{
unsigned char i;
Lcd_Circle(32,32,31,1);//畫圓 圓心坐標(biāo)(32,32) 半徑31
for(i=0;i<60;i++)
{
if((i%5)==0) //畫刻度
{
Lcd_Line(Lcd_TimeX(32,30,i),Lcd_TimeY(32,30,i),Lcd_TimeX(32,27,i),Lcd_TimeY(32,27,i),1);
}
}
}
我用的是定時器做的,這一時刻的時間與上一時刻不一樣時,把上一時刻的指針消除掉,顯示這一時刻的指針
//【0】:上一時刻時間
//【1】:這一時刻時間
struct POINT_CLOCK
{
unsigned char hour;
unsigned char minute;
unsigned char second;
}Point_Time[2];
/*========================================================================
*name:Display_Pointer(struct POINT_CLOCK AA,unsigned char color)
*function:顯示時、分、秒指針
*參 數(shù):結(jié)構(gòu)體: 時分秒
* color: 0不顯示 1:顯示
*注:秒針長24
分針長17
秒針長12
=========================================================================*/
void Display_Pointer(struct POINT_CLOCK AA,unsigned char color) //指針顯示
{
Lcd_Line(Lcd_TimeX(32,24,AA.second),Lcd_TimeY(32,24,AA.second),32,32,color);
Lcd_Line(Lcd_TimeX(32,17,AA.minute),Lcd_TimeY(32,17,AA.minute),32,32,color);
Lcd_Line(Lcd_TimeX(32,12,AA.minute/10+5*(AA.hour%12)),Lcd_TimeY(32,12,AA.minute/10+5*(AA.hour%12)),32,32,color);
}
/*========================================================================
*name:Display_PointClock(struct POINT_CLOCK AA,unsigned char color)
*function:顯示時、分、秒指針
*參 數(shù):結(jié)構(gòu)體0:存放上一個時分秒 》》》兩者不同時,刷新顯示
結(jié)構(gòu)體1:存放這一個時分秒 》》》
*
* color:0不顯示 1:顯示
=========================================================================*/
void Display_PointClock() //指針式時鐘顯示
{
if(Point_Time[0].second!=Point_Time[1].second) //秒刷新
{
Lcd_Line(Lcd_TimeX(32,24,Point_Time[0].second),Lcd_TimeY(32,24,Point_Time[0].second),32,32,0);
}
if(Point_Time[0].minute!=Point_Time[1].minute) //分刷新
{
Lcd_Line(Lcd_TimeX(32,17,Point_Time[0].minute),Lcd_TimeY(32,17,Point_Time[0].minute),32,32,0);
}
if((Point_Time[0].minute/10+5*(Point_Time[0].hour%12))!=(Point_Time[1].minute/10+5*(Point_Time[1].hour%12))) //時刷新顯示
{
Lcd_Line(Lcd_TimeX(32,12,Point_Time[0].minute/10+5*(Point_Time[0].hour%12)),Lcd_TimeY(32,12,Point_Time[0].minute/10+5(Point_Time[0].hour%12)),32,32,0);
}
Display_Pointer(Point_Time[1],1); //現(xiàn)在的指針式時鐘顯示
Point_Time[0]=Point_Time[1];
}
復(fù)制代碼
作者:
姜萬孟55
時間:
2016-5-20 11:12
該程序lcd12864與單片機(jī)是如何接線的
作者:
qwerrt
時間:
2017-4-12 12:01
伙計(jì)有沒有電路連接圖!
作者:
a76315592
時間:
2017-6-7 11:34
樓主大大 請問 能在iAR做嗎?主函數(shù)怎么寫 不太懂這些
作者:
藍(lán)廊坊市
時間:
2018-3-11 20:30
感謝感謝
作者:
zy!!
時間:
2020-1-5 15:31
請問樓住這個數(shù)字的時鐘顯示的驅(qū)動在哪個地方
作者:
songxia8013
時間:
2020-3-1 15:47
這發(fā)的文件不對!上面寫著ST7920,結(jié)果上來的壓縮包里面是CS1,CS2,這樓主糊弄人的吧?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1