首先聲明下,這并不是什么高科技,只是一個沒有什么技術含量的單片機流水燈而已,文字記錄下來為了以后能夠更好學習進步。歡迎拍磚。
話說“計軸復零監(jiān)測裝置”完成之后,領導希望做一塊演示板,以此來打動評委及現(xiàn)場觀眾。
說下我們的構思及要求:
1、當“按鍵1”按下后,“1”藍色LED燈依次點亮,保持點亮狀態(tài)。
2、當“按鍵2”按下后,“ 2” 藍色LED燈依次點亮,完了,“1” 藍色LED燈滅掉。
4、“ 3”紅色LED點亮1秒后,滅。
5、“4”黃色LED依然點亮。
6、“ 5”八段管計數(shù)加1。
7、“ 6” 紅色LED點亮3秒后,滅。
8、“ 7”綠色、藍色LED燈依次點亮。
9、“8”屏幕顯示。
當這圖畫好后,接下來就是焊硬件,由圖紙到實物。
背面的接線圖:
其實,那時候我心里沒底的,超過40個LED,哪怕是個別并聯(lián)后,還是超過89C51單片機的32個IO口,更何況八段管已經(jīng)占用P0口,這樣算下來,LED能用的就只有P1、2、3四個,24個燈位了。
其實,最開始我也想到要用寄存器來擴展IO口,尤其是八段管,但苦于功力不足,74HC164寄存器驅動八段管的程序沒有調試成功,于是不得不降低要求,直接用P0口來。
非常抱歉,由于當時時間關系,所以實際上演示板的電路圖我是沒有畫的(直到現(xiàn)在也沒有畫出來),而是直接焊電路板的。
八段管與單片機的連接電路圖大概如下:
程序如下:
//--------------定義八段管顯示------------------
chartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x02,0xf8,0x00,0x10};
int n=0;
P0=0xc0; // 初始顯示0
while(1)
{
if(k1==0) //判斷按鍵按下
{
delay(30);
if(k1==0)
++n; //N加1
if(n==10) //如果N等于10,N為0
n=0;
P0=tab[n]; //將段碼送P0口
}
}
八段管的問題解決了,接下來就是LED燈,一共47個LED燈,由于“4”、“7”部分LED燈是可以并聯(lián)顯示,所以,我還是要解決38個LED的顯示。另外還需要2個按鍵、1個信號觸發(fā)“8”顯示屏,于是就變成22個IO口和38個LED燈。這樣不得不用到寄存器了。華強北跑了一趟,買到的是74HC164。
有了寄存器,只需要2個IO口就可以擴展連接8個LED,整個電路中,我一共用了3個74HC164,終于解放了緊張的IO口。
上電……調試,這里LED燈連接方式是共陽極,那么就需要74HC164依然輸出低電平,二進制就是“0111 1111”換算成16進制為“0x7f”。
程序如下:
//--------------第一個74LS164函數(shù)-----------------
void In_164(uchar dat) //送數(shù)據(jù)進74LS164
{
uchar i;
for(i=0;i<8;i++)
{
dat=dat>>1; //移位8位
DS1=CY; //溢出位給數(shù)據(jù)端
SCLK1=0; //時鐘脈沖
_nop_();
_nop_();
SCLK1=1;
_nop_();
_nop_();
SCLK1=0;
}
}
void LS3(void)
{
uchar temp=0x7f;
uchar i;
{
for(i=0;i<8;i++)
{
In_164(temp);
Delay_1ms(90); //延時1s
temp=(temp<<1)|(temp>>7); //循環(huán)移位
}
}
}
又有新的問題出現(xiàn),由于74HC164平時是輸出低電平的,故,只要一上電,LED全部點亮,執(zhí)行程序后是依次滅燈。哎,幾經(jīng)周折,終于找到解決方法----直接在執(zhí)行程序前先輸出一串高電平……沒想到我還是那么的聰明……嘻嘻
//-------------- 74LS164輸出高電平-----------------
void LS1(void)
{
uchar temp=0xff;
uchar i;
{
for(i=0;i<8;i++)
{
In_164(temp);
Delay_1ms(20); //延時1s
temp=(temp<<1)|(temp>>7); //循環(huán)移位
}
}
}
至此,收工,主程序如下:
//--------------主函數(shù)-----------------
void main()
{
intn=0;
P0=0xc0; // 初始顯示0
{LS1();}
{LS3();}
{LS5();}
while(1)
{
if(k1==0) //如果第一個按鍵按下
{
delay(30); //延時去抖
if(k1==0) //再判斷是否按下
{
la1 = 0; //藍色LED0點亮
delay(90); //調用延時程序
la2 = 0;
delay(90);
la3 = 0;
while(k1==0); //等待按鍵松開
}
}
if(k2==0) //如果第二個按鍵按下
{
delay(30); //延時去抖
if(k2==0) //再判斷是否按下
{
la4 = 0;
delay(90);
la4 = 1; //藍色LED4滅
la5 =0;
delay(90);
la5 = 1;
la6 =0;
delay(90);
la6 = 1;
la7 =0;
delay(90); /
la7 = 1;
la8 =0;
delay(90);
la8 = 1;
la1 = 1;
la2 = 1;
la3 = 1; //藍色LED全部滅
ho1 =0; //紅色LED點亮
delay(2000);
ho1 = 1;
hu1 = 0;
delay(90); //調用延時程序
hu1 = 1;
hu2 = 0;
delay(90);
hu2 = 1;
hu3 = 0;
delay(90);
hu3 = 1;
hu4 = 0;
delay(90);
hu4 = 1;
hu5 = 0;
delay(90);
hu5 = 1;
{LS2();LS1();}
++n; //N加1
if(n==10) //如果N等于10,N為0
n=0;
P0=tab[n]; //將段碼送P0口
ho2=0; //置P0口為低電平
delay(2000); //調用延時程序
ho2 = 1;
{LS4();LS3();LS6();LS5();}
da1 =0;
delay(100);
da1 = 1;
}
while(k2==0); //等待按鍵松開
}
}
}