用單片機定時器本人是一名電子愛好者,用業余時間自學的單片機,原來只是想玩玩而已,不過現在才發現自己不知不覺已深陷其中,不能自拔,大家是否有同感?
在網上買的幾塊錢的3.8寸12864液晶屏,不帶字庫
image003.jpg (309.38 KB, 下載次數: 135)
下載附件
2019-12-22 10:10 上傳
YXD12864G04引腳定義.jpg (148.3 KB, 下載次數: 149)
下載附件
2019-12-22 10:10 上傳
接口定義.jpg (16.05 KB, 下載次數: 157)
下載附件
2019-12-22 10:10 上傳
萬年歷接口定義.jpg (107.52 KB, 下載次數: 173)
下載附件
2019-12-22 10:10 上傳
用3D打印的外殼,元件不多,沒用PCB直接焊接,單片機被我搞成這樣
IMG_20191029_052700.jpg (273.35 KB, 下載次數: 156)
下載附件
2019-12-22 10:10 上傳
完成后的成品前面
萬年歷-前.jpg (161.95 KB, 下載次數: 161)
下載附件
2019-12-22 10:10 上傳
背面
IMG_20191222_103233.jpg (175.83 KB, 下載次數: 140)
下載附件
2019-12-22 10:35 上傳
運行效果
IMG_20191222_090738.jpg (255.63 KB, 下載次數: 146)
下載附件
2019-12-22 10:10 上傳
IMG_20191222_100328.jpg (240.27 KB, 下載次數: 157)
下載附件
2019-12-22 10:10 上傳
https://v.youku.com/v_show/id_XNDQ3ODM1MTA0NA==.html?spm=a2h0k.11417342.soresults.dposter
程序自己加了些注釋,水平有限,應該有不少錯誤,希望大家能夠多多指教。
代碼:
主程序:
/******************************************************************************
Copyright 2007
All rights reserved.
文件名 :12864.c
模塊名稱:
功能概要:C51寫的公歷轉農歷,并驅動12864(KS0108)漢字液晶顯示。
取代版本:0.0.1
修改人 :pulan
完成日期:2007.07.08
升級說明:create
CPU: stc89c58 主頻:11.0592M
液晶型號: 生產廠家: 驅動芯片:KS0108
硬件連接:
---------------------------------------------------------------
|DB0-----P0.0 | DB4-----P0.4 | RW-------P2.2 |
|DB1-----P0.1 | DB5-----P0.5 | RS-------P2.1 |
|DB2-----P0.2 | DB6-----P0.6 | E -------P2.5 |
|DB3-----P0.3 | DB7-----P0.7 | Vo接1k電阻到地
---------------------------------------------------------------
******************************************************************************/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include "shijian.c"
void main(void)
{
initial();
while(1)
{
read_temp();
ds1820disp();
verify_time(); //確認時間正確性
key();
if(setflag==0)
disp_time(); //這里調用顯示時間程序
}
}
顯示驅動
/******************************************************************************
Copyright 2007
All rights reserved.
文件名 :12864.c
模塊名稱:
功能概要:C51寫的公歷轉農歷,并驅動12864(KS0108)漢字液晶顯示。
取代版本:0.0.1
修改人 :pulan
完成日期:2007.07.08
升級說明:create
CPU: stc89c58 主頻:11.0592M
液晶型號: 生產廠家: 驅動芯片:KS0108
硬件連接:
---------------------------------------------------------------
|DB0-----P0.0 | DB4-----P0.4 | RW-------P2.2 |
|DB1-----P0.1 | DB5-----P0.5 | RS-------P2.1 |
|DB2-----P0.2 | DB6-----P0.6 | E -------P2.5 |
|DB3-----P0.3 | DB7-----P0.7 | Vo接1k電阻到地
---------------------------------------------------------------
******************************************************************************/
#define uchar unsigned char
sbit LCD_csa=P2^7; //定義左屏開關
sbit LCD_csb=P2^6; //定義右屏開關
sbit LCD_rs =P2^5; //定義數據或指令,1=數據,0=指令
sbit LCD_rw =P2^4; //定義讀或寫? 1=讀, 0=寫
sbit LCD_e =P2^3; //定義使能操作, 1=能, 0=否
//sbit LCD_rst = P2^0; //定義復位
sfr LCD_db=0x80; //定義數據端口
/******************************************************************************************
* 函數名稱 :lcd_busy
* 功能描述 :判別LCD12864忙否?不忙才跳出此程序
* 參數 : 參數名稱: 輸入/輸出? 類型 描述
*
* 返回值 :
* 作者 :
* 創建日期 :2006-12-19
* 全局變量 :
* 全局靜態變量:
* 局部靜態變量:
*----------------------------------------修改歷史------------------------------------------
* 當前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void lcd_busy(void)
{
LCD_rs=0;
LCD_rw=1;
LCD_db=0xff;
while (1)
{
LCD_e=1;
if (LCD_db<0x80) //如果要進行簡單的軟件調試,可在這句前面加"//"跳過
break;
LCD_e=0;
}
LCD_e=0;
}
/******************************************************************************************
* 函數名稱 :set_xy
* 功能描述 :設置顯示位置! X,Y分別代表橫縱坐標!
* 參數 : 參數名稱: 輸入/輸出? 類型 描述
******************************************************************************************/
void set_xy(unsigned char x,unsigned char y)
{
if (x>=64) {LCD_csa=0;LCD_csb=1;}
else {LCD_csa=1;LCD_csb=0;} //判別是左半屏,還是右半屏
lcd_busy();
LCD_rs=LCD_rw=0;
LCD_db=0x40|x; //列地址賦值,x取值0----64
LCD_e=1;LCD_e=0;
lcd_busy();
LCD_rs=LCD_rw=0;
LCD_db=0xb8|y; //頁面地址賦值,y取值0----8
LCD_e=1;LCD_e=0;
LCD_db=0xff;
}
/******************************************************************************************
* 函數名稱 :lw
* 功能描述 :在指定的位置顯示數據
* 參數 : 參數名稱: 輸入/輸出? 類型 描述
******************************************************************************************/
void lw(uchar x,uchar y,uchar dd)
{
set_xy(x,y);
lcd_busy();
LCD_rs=1;
LCD_rw=0;
LCD_db=dd; //數據送顯
LCD_e=1;
LCD_e=0;
LCD_db=0xff;
}
/******************************************************************************************
* 函數名稱 :lcd_init
* 功能描述 :顯示初始化
* 參數 : 參數名稱: 輸入/輸出? 類型 描述
******************************************************************************************/
#pragma disable
void lcd_init(void)
{
unsigned char x,y;
/*開顯示*/
// LCD_rst=0;
// Delay12864(100);
// LCD_rst=1;
// Delay12864(100);
LCD_e=LCD_rs=LCD_rw=0;
LCD_csa=LCD_csb=0;
LCD_csa=1; //選擇左半屏顯示
LCD_db=0x3f; //打開左半屏顯示
LCD_e=1;LCD_e=0;LCD_csa=0;
LCD_csb=1; //選擇右半屏顯示
LCD_db=0x3f; //打開右半屏顯示
LCD_e=1;LCD_e=0;LCD_csb=0;
/*0行開始顯示*/
LCD_csa=1;lcd_busy();
LCD_rs=LCD_rw=0;LCD_db=0xc0; //設置左半屏起始行,是第一行
LCD_e=1;LCD_e=0;LCD_csa=0;
LCD_csb=1;lcd_busy();
LCD_rs=LCD_rw=0;LCD_db=0xc0; //設置右半屏起始行,是第一行
LCD_e=1;LCD_e=0;LCD_csb=0;
for (y=0;y<8;y++)
{
for (x=0;x<128;x++) lw(x,y,0); //全屏清零顯示
}
}
按鍵程序:
#include<reg52.h>
#include<delayms.h>
#include"xs.c"
sbit set =P3^7; //設置
sbit key1=P3^6; //加
sbit key2=P3^5; //減
sbit key3=P3^4; //蜂鳴開關
sbit key4=P3^3; //背光開關
uchar setflag=0; //按鍵計數
sbit bl=P2^0; //背光控制端
sbit bz=P2^1; //蜂鳴控制端
void key() //按鍵程序
{
if(set==0) //如果設置鍵按下
{
delayms(5); //延時消抖
if(set==0) //再次確認設置鍵按下
{
setflag++; //按鍵計數加1
while(!set); //等待按鍵松開
switch(setflag)
{
case 1:// TR0=0; //定時器0關閉
dashuzi(4,2,10,0); //顯示時與分中間的冒號
dashuzi(10,2,10,0); //顯示分與秒中間的冒號
dispmiao(sec,1); //秒反顯
break;
case 2: dispmiao(sec,0); //秒正顯
dispfen(min,1); //分反顯
break;
case 3: dispfen(min,0); //分正顯
dispshi(hour,1);// //時反顯
break;
case 4: dispshi(hour,0); //時正顯
dispri(day,1); //日反顯
break;
case 5: dispri(day,0); //日正顯
dispyue(month,1); //月反顯
break;
case 6: dispyue(month,0); //月正顯
dispnian(year,1); //年反顯
break;
case 7: setflag=0; //按鍵計數變為0
dispnian(year,0); //年正顯
// TR0=1; //定時器0啟動
break;
default:;
}
}
}
if(setflag!=0) //如果按鍵計數不為0
{
if(key1==0) //如果加鍵按下
{
delayms(5); //延時消抖
if(key1==0) //再次確認加鍵按下
{
while(!key1); //等待加鍵松開
switch(setflag)
{
case 1:// sec++; //秒加1
// if(sec==60)
sec=0; //如果秒加到60,秒歸0
dispmiao(sec,1); //調用秒反顯
break;
case 2: min++; //分加1
if(min==60) min=0; //如果分加到60,分歸0
dispfen(min,1); //調用分反顯
break;
case 3: hour++; //小時加1
if(hour==24) hour=0; //如果小時加到24,小時歸0
dispshi(hour,1); //調用小時反顯
break;
case 4: day++; //日加1
if(day==32) day=1; //如果日加到32,日變為1
dispri(day,1); //調用日反顯
break;
case 5: month++; //月加1
if(month==13) month=1;//如果月加到13
dispyue(month,1); //調用月反顯
break;
case 6: year++; //年加1
if(year==100) year=0; //如果年加到100,年歸0
dispnian(year,1); //調用年反顯
break;
default:;
}
}
}
if(key2==0) //如果減鍵按下
{
delayms(5); //延時消抖
if(key2==0) //再次確認減鍵按下
{
while(!key2) ; //等待減鍵松開
switch(setflag)
{
case 1:// sec--; //秒減1
// if(sec<0)
sec=0;//59; //如果秒小于0,秒變為59
dispmiao(sec,1); //調用秒反顯
break;
case 2: min--; //分減1
if(min<0) min=59; //如果分小于0,分變為59
dispfen(min,1); //調用分反顯
break;
case 3: hour--; //小時減1
if(hour<0) hour=23; //如果小時小于0,小時變為23
dispshi(hour,1); //調用小時反顯
break;
case 4: day--; //日減1
if(day==0) day=31; //如果日減到0,日變為31
dispri(day,1); //調用日反顯
break;
case 5: month--; //月減1
if(month==0) month=12;//如果月減到0,月變為12
dispyue(month,1); //調用月反顯
break;
case 6: year--; //年減1
if(year<0) year=99; //如果年小于0,年變為99
dispnian(year,1); //
break;
default:;
}
}
}
}
if(setflag==0&&key3==0) //走時狀態且蜂鳴開關按下時
{
delayms(5); //延時消抖
if(setflag==0&&key3==0) //再次確認走時狀態且蜂鳴開關按下時
{
while(!key3); //等待蜂鳴開關松開
bz=~bz; //蜂鳴輸出取反
}
}
if(setflag==0&&key4==0) //走時狀態且背光開關按下時
{
delayms(5); //延時消抖
if(setflag==0&&key4==0) //再次確認走時狀態且背光開關按下時
{
while(!key4); //等待背光開關松開
bl=~bl; //背光輸出取反
}
}
}
下面是完整程序和仿真:
★★3-帶農歷萬年歷.zip
(118.95 KB, 下載次數: 249)
2019-12-22 10:11 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
隨后再加上鬧鐘和整點報時。
|