1. 程式人生 > >微控制器實驗 之 廣告流水燈中斷控制

微控制器實驗 之 廣告流水燈中斷控制

實驗內容:

1.利用定時/計數器T0從P1.0輸出週期為1s的方波,讓發光二極體以1hz閃爍,設晶振頻率為12MHz

2.利用定時/計數器T1產生定時時鐘,由P1口控制8個發光二極體,使8個指示燈依次一個一個閃爍,每盞燈的閃爍頻率為10次/秒,8個燈依次閃爍一遍後迴圈。

3.用定時器以間隔500ms在6位數碼管上依次顯示0、1、2、3……、F(自己設計電路)

4.中斷巢狀

INT0、INT1同時存在,P1為輸出口,INT1優先順序高於INT0,均為電平觸發。

主程式8個發光二極體上下移動12輪,再閃爍12次;INT0的中斷服務程式控制P1口的8個發光二極體閃爍13次,INT1的中斷服務程式控制P1口的8個發光二極體上下移動10輪。其中,上下移動一次所用時間為100ms,閃爍一次所用時間為50ms,所有定時用中斷處理,不允許用軟體定時。

5.同時用兩個定時器控制蜂鳴器發聲,定時器0控制頻率,定時器1控制同個頻率持續的時間,間隔300ms依次輸出1、10、50、100、200、400、800、1k(hz)的方波。

模擬圖:


1.原始碼:#include<reg52.h>
#define uchar unsigned char
sbit LED = P1^0;
uchar T_0 = 0;
void main()
{
TMOD=0x01;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
EA=1;
  ET0=1;

TR0=1;
while(1);
}
void LED_FLASH()interrupt 1

TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
T_0++;
if(T_0==50)
{
T_0=0;
LED=~LED;
}

}

2.原始碼:

#include <reg52.h>   
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned char
uchar T_0=0;
uchar a;
void delay(uint z)
{
uint j,k;
for(j=z;j>0;j--)
for(k=110;k>0;k--);
}
void main()
{
TMOD=0x10;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
EA=1;
ET1=1;
TR1=1;
a=0xfe;
while(1)
{
if(T_0==5)
{
T_0=0;
P1=a;
delay(500);
P1=0xff;
delay(50);
a=_crol_(a,1);
}
}
}
void LED_FLASH() interrupt 3

TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
T_0++;

}

3.原始碼:

#include<reg52.h>
#define uchar unsigned char
sbit LED = P0^0; 
uchar T_0 = 0;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0-F
uchar a=0;
void main()
{
uchar b;
b=0x01;
TMOD=0x01;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
EA=1;
  ET0=1;
TR0=1;
while(1)
{if(T_0==25)
{
T_0=0;
P2=b;
P0=table[a];
a++;
if(a==16)
a=0;
}
}
}
void LED_FLASH()interrupt 1

TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
T_0++;

}

這是實物除錯的程式碼,模擬圖就自行設計吧。

4.原始碼:

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar num,aa,bb;
uint i,j,led,m,n,k,ge,shi,bai,qian,wan,shiwan,x,y;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};     //0~F
uchar code place[]={0xe3,0xe7,0xeb,0xef,0xf3,0xf7};//138譯碼器000~005
void delayms(uint);
void display();
void main()
{
TMOD=0xdd;
IT0=1;          //外部中斷低電平觸發
IT1=1;
EX0=1;//允許外部中斷
EX1=1;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET1=1;
TR1=1;
ET0=1;
TR0=1;  
while(1)
{     led=0xfe; 
for(k=0;k<11;k++)   //流水燈12次
{
for(m=0;m<7;m++)   //流水燈往下流
{
P2=led;
delayms(6);
led=_crol_(led,1); 
}
for(n=0;n<7;n++)   //流水燈往上流
{
P2=led;
delayms(6);
led=_cror_(led,1);
}
display();
}
for(i=0;i<11;i++)//閃爍12次
{
P2=0x00;
delayms(25);
P2=0xff;
delayms(25);
display();
}
};
}
void display()
{
    ge++;
P2=0xf7;
P0=table[ge];
  if(ge==9)
  {
ge=0;
shi++;
P2=0xf3;
P0=table[shi];

if(shi==9)
{
shi=0;
bai++;
}
}
}
void delayms(uint xms)    
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void T0_time() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
for(x=0;x<12;x++)//閃爍13次
{
P1=0x00;
delayms(25);
P1=0xff;
delayms(25);
display();
}
}
void T1_time() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
led=0xfe; 
for(y=0;y<9;y++)   //Á÷Ë®µÆ10´Î
{
for(m=0;m<7;m++)   //Á÷Ë®µÆÍùÏÂÁ÷
{
P1=led;
delayms(6);
led=_crol_(led,1); 
}
for(n=0;n<7;n++)   //Á÷Ë®µÆÍùÉÏÁ÷
{
P1=led;
delayms(6);
led=_cror_(led,1);
}
}
display();

}

5.原始碼:

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1 = P3^0;
uint code table[]={4000,400,80,40,20,10,5,4};//8種頻率
uchar Fre_0=0,Fre_1=0,i=0,T_0=0,b=0;
void main()
{
Fre_0=20000;
TMOD=0x11; //TMOD叫做計數器模式控制暫存器,01為方式1,功能為16位定時器
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
TH1=(65536-Fre_0)/256;
TL1=(65536-Fre_0)%256;
EA=1;//開總中斷
ET0=1;//啟動定時器0或1的中斷
//(這兩個條件允許了系統響應中斷)
ET1=1;
TR0=1;//啟動定時器
TR1=1;
LED1=1;
while(1)//等待中斷
{
if(Fre_1>=0)
{TR0=0;
LED1=~LED1;
if(T_0>14)
T_0=0;
i++;
if(i>7)
i=0;
TR0=1;
}
}
}
void LED_FLASH1() interrupt 1//缺少了interrupt會無法執行函式,這個要由後面的引數n指明中斷號

TH0=(65536-250)/256;
TL0=(65536-250)%256;
b++;
if(b>table[i]+1)
Fre_1++;
}
void LED_FLASH0() interrupt 3//缺少了interrupt會無法執行函式,這個要由後面的引數n指明中斷號
{
TH1=(65536-20000)/256;
TL1=(65536-20000)%256;
T_0++;

}

具體到模擬圖或者實物除錯都會有些許差異,還可對程式碼中的並行串列埠P0-P3做相應的調整,這個具體問題具體分析。