從零開始,記錄每天學(xué)單片機(jī),菜鳥一枚,勿噴!
最簡單,點(diǎn)亮第一個LED,綠燈。P0^0置0即可。看程序:
#include
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
sbit LED_on=P0^0;
void main()
{
ADDR0=0;
ADDR1=1;
ADDR2=1;//因?yàn)長ED正極是利用三極管9012和138的Y6口,所以Y6口必須為0,所以A0,A1,A2分別為0.1.1
ADDR3=1;
ADDR4=0;//138使能端,E1,E2低電平有效,E3高電平有效。
while(1)
{
LED_on=0;
}
}
LED點(diǎn)亮后,接下來就使它有間隔的亮,需要加個延時,單片機(jī)可以利用的延時有兩種!一種可以在程序上設(shè)計(jì),利用循環(huán)函數(shù),當(dāng)?shù)揭欢〞r間后跳出來,但不精確。另外一種可以利用單片機(jī)的定時器中斷,到我們需要的時間后就中斷。嗯,這里我先利用簡單的,就是第一種。程序:
#include
#define uchar unsigned char
#define uint unsigned int
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
sbit LED_on=P0^0;
void delay(uint x) //延時子程序。
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void main()
{
ADDR0=0;
ADDR1=1;
ADDR2=1; //因?yàn)長ED正極是利用三極管9012和138的Y6口,所以Y6口必須為0,所以A0,A1,A2分別為0.1.1
ADDR3=1;
ADDR4=0;//138使能端,E1,E2低電平有效,E3高電平有效。
while(1)
{
LED_on=0;
delay(100);
LED_on=1;
delay(100);
}
}
先放一邊,接下來就是簡單的走馬燈程序:
#include
#define uchar unsigned char
#define uint unsigned int
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
void delay(uint x) //延時子程序。
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void main()
{
uchar cnt=0; //LED指針
ADDR0=0;
ADDR1=1;
ADDR2=1; //因?yàn)長ED正極是利用三極管9012和138的Y6口,所以Y6口必須為0,所以A0,A1,A2分別為0.1.1
ADDR3=1;
ADDR4=0; //138使能端,E1,E2低電平有效,E3高電平有效。
while(1)
{
P0=~(0x01<
delay(100);
cnt++;
if(cnt>=8)
{
cnt=0;
}
}
}
現(xiàn)在利用定時器0進(jìn)行定時,就是LED之間隔一秒亮,我使用的是12M的晶振,一個時鐘周期就是1/12*106,一個機(jī)械周期是12個時鐘周期,1ms等于x個機(jī)械周期,算出x等于1000,65536減去1000再用16進(jìn)制表示得FC18,所以我們的定時器初定值為 TH0=0xFC,TL0=0x18.程序如下:
#include
#define uchar unsigned char
#define uint unsigned int
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
void main()
{
uchar cnt=0; //LED指針
uint T=0; //定時器溢出次數(shù)
ADDR0=0;
ADDR1=1;
ADDR2=1; //因?yàn)長ED正極是利用三極管9012和138的Y6口,所以Y6口必須為0,所以A0,A1,A2分別為0.1.1
ADDR3=1;
ADDR4=0; //138使能端,E1,E2低電平有效,E3高電平有效。
TMOD=0x01; //定時器選擇工作模式1
TH0=0xFC;
TL0=0x18; //賦予初值
TR0=1; //開定時器0
while(1)
{
if(TF0==1)
{
TF0=0;
T++;
TH0=0xFC;
TL0=0x18; //重新賦值
}
if(T>=1000)
{
T=0;
P0=~(0x01<
cnt++;
if(cnt>=8)
{
cnt=0;
}
}
}
}
LED可以衍生到數(shù)碼管,我暫時使用的是4個共陰的數(shù)碼管,分別接到38譯碼器的Y0,Y1,Y2,Y3口,首先令一個數(shù)碼管靜態(tài)顯示,我們在數(shù)碼管看到的1,2,3,4.....9,0,是利用數(shù)碼管的相對應(yīng)LED組合而成,因?yàn)槭枪碴?,所以?dāng)我們P0口給“1”的時候,LED亮??匆韵鲁绦?,我想實(shí)現(xiàn)的功能是秒數(shù)計(jì)數(shù):
#include
#define uchar unsigned char
#define uint unsigned int
uchar LedChar[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//數(shù)碼管輸出0,1,2,3,4,5,6,7,8,9
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
void main()
{
uchar cnt=0; //秒數(shù)指針
uint T=0; //定時器溢出次數(shù)
P0=0x00; //初始化不顯示
ADDR0=1;
ADDR1=1;
ADDR2=0; //因?yàn)閿?shù)碼管陰極是138的Y4口,所以Y3口必須為0,所以A0,A1,A2分別為1.1.0
ADDR3=1;
ADDR4=0; //138使能端,E1,E2低電平有效,E3高電平有效。
TMOD=0x01; //定時器選擇工作模式1
TH0=0xFC;
TL0=0x18; //賦予初值
TR0=1; //開定時器0
while(1)
{
if(TF0==1)
{
TF0=0;
T++;
TH0=0xFC;
TL0=0x18; //重新賦值
}
if(T>=1000)
{
T=0;
P0=LedChar[cnt];
cnt++;
if(cnt>=10)
{
cnt=0;
}
}
}
}
有靜態(tài)顯示,自然有動態(tài)顯示,因?yàn)閱纹瑘?zhí)行指令的時候是一條一條的執(zhí)行,那我們是是如何實(shí)現(xiàn)4個數(shù)碼管同時顯示呢,其實(shí)是利用人的錯覺,但閃爍間隔為10mS時,我們是不會感覺閃爍的,根據(jù)這個原理,我們讓4個數(shù)碼管同時顯示:
#include
#define uchar unsigned char
#define uint unsigned int
uchar LedChar[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//數(shù)碼管輸出0,1,2,3,4,5,6,7,8,9
uchar Ledsta[]={0x00,0x00,0x00,0x00};
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ADDR4=P1^4;
uint T=0;
void main()
{
uint cnt=0; //秒數(shù)指針
uint T=0; //定時器溢出次數(shù)
P0=0x00; //初始化不顯示
EA=1; //中斷總開關(guān)
ADDR3=1;
ADDR4=0; //138使能端,E1,E2低電平有效,E3高電平有效。
TMOD=0x01; //定時器選擇工作模式1
TH0=0xFC;
TL0=0x18; //賦予初值
TR0=1; //開定時器0
ET0=1; //定時器中斷0開關(guān)
while(1)
{
if(T>=1000)
{
cnt++;
Ledsta[0]=LedChar[cnt%10];
Ledsta[1]=LedChar[cnt/10%10];
Ledsta[2]=LedChar[cnt/100%10];
Ledsta[3]=LedChar[cnt/1000%10];
}
}
}
void InterruptTimer0() interrupt 1
{
static uchar i=0;
T++;
TH0=0xFC;
TL0=0x18;
switch(i)
{
case 0: ADDR0=1;ADDR1=1;ADDR2=0;i++;P0=Ledsta[0];break;
case1: ADDR0=0;ADDR1=1;ADDR2=0;i++;P0=Ledsta[1];break;
case2: ADDR0=1;ADDR1=0;ADDR2=0;i++;P0=Ledsta[2];break;
case3: ADDR0=0;ADDR1=0;ADDR2=0;i=0;P0=Ledsta[3];break;
default:break;
}
}