|
其實早有想寫一寫這方面的東西了,要不是雜事情多,應該早出來報告了。
言歸正傳吧,不知道是什么原因使我喜歡上了單片機,以前的時候,覺得單片機是那么神秘,但是實踐證明:只要有興趣就沒有學不會的東西,當然學會容易,學好就要下一番功夫了。
話說那是2012年末臨近放寒假的時候,某一日在網上溜達看到了單片機,于是乎就買了個單片機的開發板全散件(那時候只知道是單片機散件,不大明白為啥叫開發板)。幾天的時間就回來了,晚上就把它給焊接好了,憑借多年的焊接經驗,一次成功,跟成品板看不出區別(你是看不出來的,你不能跟我比啊!呵呵,不要臉一下)。平時沒有時間去研究,一晃就到了假期,所以就天天查資料學習,您還別說,一旦進去就陷進去了,里面真是別有洞天啊。不客氣的說,假期的十多天時間,比我當學生的時候學的都踏實和牢固深刻。
下面是我用單片機做的簡單的時鐘,最初是用單片機本身的定時功能進行計時的,軟件調整誤差,精度可以做的很高,但是斷電需要再調整,用計時芯片的話可以斷電記憶,但是要保證計時精準就要高精度的晶振,這也是個矛盾。我先沒有用時鐘芯片,對于初學者還是合適的,能夠很快入門,了解單片機的結構,定時器的編寫,數碼管的顯示原理,等等。我用的是c語言,以前有點基礎,加之其可移植性好,上手容易等優點,所以就沒有去學難啃的匯編語言。后面我又加了個時鐘芯片(DS1302),這個芯片精度不高,家用還湊合,以后換成887高精度的芯片就相當實用了。這些對于程序的編寫也有提高。
結構:
上下兩塊洞洞板,兩邊有排陣接插的,同時兼顧傳導信號,上板是數碼管,下板是單片機。板子是10x16cm的,一位數碼管3x4.4cm,共陽極的。單片機stc89c52,12M的晶振,數碼管是7位的,所以其小數點不亮,我外接了兩個led做秒閃爍用,一秒一眨眼的。如果采用8段數碼管,可以用數碼管的點做秒閃爍,即小時的個位點和分鐘的十位點(數碼管倒置安排形成8.8:8.8樣式)同時閃爍,效果會更好,這個我在開發板上已經修改成功,以后用8段數碼管就采用這種方式。板子的5v供電用USB接口。3位按鍵調節時間,其一為時分選擇,其二加,其三為減。
總結:
最滿意的是洞洞板的背面布線,完全手工,很滿意,也很漂亮的。其實一開始也是有點彎路,后來發現了一個小軟件:Sprint-Layout 6.0 這個軟件對我等初學者真是個福音啊,完全可以安著洞洞板的界面來設計電路(直接在設計界面上設置洞洞板的孔間距 2.54mm),對照原理圖直接安放元件,連線即可,雖然有些原理圖的樣子,但是直接對照即可進行實物連線。對于連線我用細銅線,就是包皮的粗電線里的一根細的,點焊,不要全部拖錫,這樣的好處是美觀,不易粘連。
其次就是單片機的c語言,有位老鳥說的真好:其實就是if來if去的!不過進來以后還真能發現,就這么if來if去的,也充滿了邏輯性,充滿了美感,有興趣的童鞋們也進來發掘一下體驗一下其內在的美吧。
我借鑒的 代碼:(沒有驅動時鐘芯片DS1302的),其實我找了很多,覺得此程序很精煉,真的不錯,里面有我改動的地方,因為最初是移植到我的開發板上的。說到開發板,其實就是燒寫程序方便,做實驗方便的板子,一旦成功可以在另外的板子上單獨焊接專用的元件,開發出成品。比如我就用了洞洞板,當然也可以用覆銅板加工,會更美觀。
/**** 本程序中,晶振為12MHz, ****/
/**** 時間控制采用定時中斷控制方式。 ****/
/**** 模式和時間調整采用查詢方式。 ****/
#include<reg52.h>
sbit P13=P1^3; //分個位控制端
sbit P12=P1^2; //分十位控制端
sbit P11=P1^1; //時個位控制端
sbit P10=P1^0; //時十位控制端
sbit led=P2^7; //秒閃爍 led
sbit key0=P3^7; //模式設置
sbit key1=P3^6; //加
sbit key2=P3^5; //減
unsigned char hour,min,sec,T50ms;
unsigned char modstate; //模式狀態
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//段碼 (0--9、黑屏)
//unsigned char code tablemin[]={0xc0,0xcf,0xa4,0x86,0x8b,0x92,0x90,0xc7,0x80,0x82};//秒十位倒置編碼
void init(); //初始化子程序聲明 /
void delay500us(unsigned char X); //延時子程序聲明
void display(); //顯示子程序聲明
void display001(); //顯示“時”子程序聲明
void display002(); //顯示“分”子程序聲明
void keyscan(); //按鍵識別子程序聲明
void main()
{
init();
while(1)
{
keyscan();
}
}
void init() //初始化子程序
{
TMOD=0x01;
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
ET0=1;
EA=1;
TR0=1;
}
void delay500us(unsigned char X)
{
unsigned char i,j;
for(i=X;i>0;i--)
for(j=248;j>0;j--);
}
void timer0() interrupt 1 //timer0中斷服務子程序,定時時間為50ms,本程序加了10us的時間修正量
{
TMOD=0x01;
TH0=(65536-49990)/256;
TL0=(65536-49990)%256;
T50ms++;
if(T50ms>=20)
{
T50ms=0;
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)hour=0;
}
}
}
}
void display()
{
P1=0xff;
P0=table[hour/10];
P10=0;
delay500us(5);
P1=0xff;
P0=table[hour%10];
P11=0;
delay500us(5);
P1=0xff;
P0=table[min/10];
P12=0;
delay500us(5);
P1=0xff;
P0=table[min%10];
P13=0;
delay500us(5);
if(T50ms<=10)led=0;
if(T50ms>10)led=1;
}
void display001()
{
P1=0xff;
P0=table[hour/10];
P10=0;
delay500us(10);
P1=0xff;
P0=table[hour%10];
P11=0;
delay500us(10);
}
void display002()
{
P1=0xff;
P0=table[min/10];
P12=0;
delay500us(10);
P1=0xff;
P0=table[min%10];
P13=0;
delay500us(10);
}
void keyscan() //按鍵識別鐘程序
{
while(modstate==0)
{
display();
if(key0==0)
{
display();
if(key0==0)modstate++; //這兩句加在一起為延時10ms軟件防抖設計。
while(key0==0)display001(); //等待按鍵釋放。
}
}
//****************************************************************************//
while(modstate==1)
{
display001();
if(key0==0)
{
display001();
if(key0==0)modstate++; //這兩句加在一起為延時10ms軟件防抖設計。
while(key0==0)display002(); //等待按鍵釋放。
}
if(key1==0)
{
display001();
if(key1==0)
{
hour++;
if(hour>=24)hour=0;
while(key1==0)display001();
}
}
if(key2==0)
{
display001();
if(key2==0)
{
hour--;
if(hour>=24)hour=0;
while(key2==0)display001();
}
}
}
//****************************************************************************//
while(modstate==2)
{
display002();
if(key0==0)
{
display002();
if(key0==0)modstate=0; //這兩句加在一起為延時10ms軟件防抖設計。
while(key0==0)display(); //等待按鍵釋放。
}
if(key1==0)
{
display002();
if(key1==0)
{
min++;
if(min>=60)min=0;
while(key1==0)display002();
}
}
if(key2==0)
{
display002();
if(key2==0)
{
min--;
if(min>=60)min=0;
while(key2==0)display002();
}
}
}
}
好了,先看實物圖吧:














|
|