实验2 中断和定时计数器实验

1.当单片机的INT0进入低电平触发方式,进入相应的中断服务程序,P0口做输出口,接8只发光二极管,点亮发光二级管,控制蜂鸣器响。当INT1为低电平时进入中断服务程序,发光二级管灭。

接线:将P0JP1连接、P3JP5连接

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

sbit beer = P1 ^5;      //蜂鸣器

sbit button0 = P3 ^2;   //独立按键3

sbit button1 = P3 ^3;   //独立按键4

 

void int0() interrupt 0//外部中断0

{

    P0 =0;

    beer =0;

}

 

void int1() interrupt 2//外部中断1

{

    P0 =0xff;

    beer =1;

}

 

void init(){//初始化中断

    IT0 =0;

    IT1 =0;

    EA =1;       //开启中断总允许

    EX0 =1;   //外部中断0允许位

    EX1 =1;   //外部中断2允许位

}

 

int main(){

    init();

    while(1){}//让程序跑死

    return0;

}

 

 

2.选择外部中断0(P3.2),边沿触发,进入相应中断服务程序,在中断服务程序中,数码管显示加1,在0-9之间循环

 

接线:JP5+P3J12+P0

 

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

sbit button0 = P3 ^2;   //独立按键3

uchar Count=0;

 

//延时函数

void delay_1ms(uint x){

    uint i=x;

    uint j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(uchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

 

void int0() interrupt 0//外部中断0

{

    Count++;

}

 

void init(){//初始化中断

    IT0 =1;

    EA =1;    //开启中断总允许

    EX0 =1;   //外部中断0允许位

}

 

int main(){

    init();       //初始化

    while(1){

       if(Count==10){

           Count=0;

       }else{

           display(Count);

       }

    }

    return0;

}

3实验板上完成如下功能:用定时0实现8个发光二极管以1s间隔闪烁,用定时器1实现数码管的前两位59s循环计时。

#include <reg51.h>

#define uint unsigned int

#define uchar unsigned char

/**

用定时0实现8个发光二极管以1s间隔闪烁,用定时器1实现数码管的前两位59s循环计时。

1、定时器0的初始化

2、时钟1s的计算

3、定时器1循环计时

接线方式:

1P0接数码管J12,实现段选

2、译码器和数码管位选输入短接,J15+J16

3P3控制发光二极管,P3+JP1

4P2用来控制译码器的输入

**/

 

//========全局变量区============================================

uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

uint T_High_50ms=(65536-45872)/256;

uint T_Low_50ms=(65536-45872)%256;

uchar Count,Count_T1,Count_1s;//Count用来记录每50ms的计数,Count_T1用来记录1s的次数

//========全局变量区结束========================================

 

//========函数区================================================

 

//延时

void delay_1ms(uint x){

    uint i=x;

    uint j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

 

/**

    在数码管上显示对应的值

**/

void display(unsignedchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

/**

    控制数码管显示后3位,并分解计数值

**/

void DisplayNumByOrder(uint Count){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(0);

       low=1; mid=0; high=1;  display(0);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

/**

    初始化

**/

void init(){//初始化中断

 

    TMOD=0x01;        // TMOD赋值,以确定T0T1的工作方式。

    TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0TL0TH1TL1

    TL0=TL1=T_Low_50ms;

    EA =1;//开启中断总允许

    ET0 =ET1=1; 

    IT0 =IT0=1;  //开启定时器0,1中断允许

    TR0=TR1=1;     // 使TR0TR1置位,启动定时/计数器定时或计数

    Count=Count_T1=Count_1s=0;//计数

}

 

void main(){

    init();

    while(1){

       if(Count==20){//定时器0 1s时间到

           Count=0;  //开始下一轮1s的计时

           P3=~P3;

       }

       if(Count_T1==20){//定时器1 1s时间到

           Count=0;

           Count_1s++;  

       }

       if(Count_1s==60){

           Count_1s=0;

       }

       DisplayNumByOrder(Count_1s);//在数码管上显示对应的数值

    }

}

 

//========函数区结束============================================

 

//========中断函数区============================================

/**

    用定时0实现8个发光二极管以1s间隔闪烁

**/

void int0() interrupt 1//定时/计数器T0中断

{

 

    TH0=T_High_50ms;// 计算初值,并将其写入TH0TL0TH1TL1

    TL0=T_Low_50ms;

    Count++;

}

 

/**

    用定时器1实现数码管的前两位59s循环计时。

**/

void int1() interrupt 3//定时/计数器T1中断

{

    TH1=T_High_50ms;// 计算初值,并将其写入TH0TL0TH1TL1

    TL1=T_Low_50ms;

    Count_T1++;

}

 

//========中断函数结束==========================================

4、同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔300ms依次输出11050,100200,400,800,1khz)的方波。

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

 

/**

同时用两个定时器控制蜂鸣器发声,

定时器0控制频率,定时器1控制同个频率持续的时间,

间隔300ms依次输出11050,100200,400,800,1Table_Indexhz)的方波。

**/

 

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

 

uchar code Table_F[]={1,10,50,100,200,400,800,1000};  //频率表

 

uint Count_T0 =0;

uchar Table_Index =0;  //频率表下标

uint Count_T1 =0;

sbit beep = P1 ^5;     

uint f;                //频率

uint T_High_50ms=(65536-45872)/256;

uint T_Low_50ms=(65536-45872)%256;

 

 

void timer0() interrupt 1

{

    Count_T0++;

    if(Count_T0 ==6){//间隔300ms

       Table_Index++;

       if(Table_Index ==8)

           Table_Index =0;

       f = Table_F[Table_Index];      

       Count_T0 =0;

    }

    TL0 = T_High_50ms;     //50MS

    TH0 = T_Low_50ms;

}

//控制输出的频率

//1

void timer1() interrupt 3

{

    /*因为1=20*50ms1ms=1000usCount_T1每次+1间隔50ms20000/f 1秒内要有多少个50ms

    */

    Count_T1++;

    if(Count_T1 ==20000/ f){//20000=1000*20

       beep =~beep;

       Count_T1 =0;

    }

    TL1 = T_High_50ms;

    TH1 = T_Low_50ms;

}

 

void init(){

    TMOD=0x01;    // TMOD赋值,以确定T0T1的工作方式。

    EA =1;           //开启中断总允许

    ET0 =ET1=1;  //开启定时器0,1中断允许

    TR0=TR1=1;     // 使TR0TR1置位,启动定时/计数器定时或计数

    TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0TL0TH1TL1

    TL0=TL1=T_Low_50ms;

}

 

int main(){

    f = Table_F[0];

    init();

    while(1){

    }

    return0;

}

5. 利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”,到此保持住。

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

 

/**

利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”,到此保持住。

**/

 

#include <reg51.h>

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

/**

 

接线方式:

1P0接数码管J12,实现段选

2、译码器和数码管位选输入短接,J15+J16

3P3控制发光二极管,P3+JP1

4P2用来控制译码器的输入

**/

//=========全局变量区============================================

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

uint code CharTable[]={0x3f,0x38,0x38,0x79,0x76};//数字的编码

uint water_led_table[]={~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80};

uint Count_T0,Count_T1,Count_3s,Water_Led_Index =0;

uchar Switch=1;//用来控制显示字母和控制流水灯

ulong Counter=765432;

uint T_High_50ms=(65536-45872)/256;

uint T_Low_50ms=(65536-45872)%256;

//=========全局变量区结束========================================

 

 

//========中断函数区============================================

void timer0() interrupt 1

{

    Count_T0++;

}

 

void timer1() interrupt 3

{

    //利用动态扫描和定时器1在数码管上显示出从765432开始

    //1/10秒的速度往下递减直至765398并保持显示此数

    Count_T1++;

}

 

//========中断函数区结束==========================================

 

 

//========函数区================================================

/**

    是否需要递减

**/

void IsMinus(){

    if(Counter>(ulong)765398){

       Counter--;

    }else{

       Switch=0;//3秒后显示Hello,流水灯关闭

    }

}

//延时

void delay_1ms(uint x){

    uint i=x;

    uint j;

    for(;i>0;--i){ 

       for(j=110;j>0;--j);

    }

}

 

/**

    在数码管上显示对应的值

**/

void display(unsignedchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

/**

    显示字母

**/

void displayChar(unsignedchar Num)

{

    P0=CharTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

/**

    控制数码管显示后6位,显示Hello

**/

void DisplayNumByOrder(ulong Count){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(Count%1000000/100000);

       low=1; mid=1; high=0;  display(Count%100000/10000);

       low=0; mid=0; high=1;  display(Count%10000/1000);

       low=1; mid=0; high=1;  display(Count%1000/100);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

/**

    控制数码管显示后6位,并分解计数值

**/

void DisplayHello(){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  displayChar(4);

       low=0; mid=0; high=1;  displayChar(3);

       low=1; mid=0; high=1;  displayChar(2);

       low=0; mid=1; high=1;  displayChar(1);

       low=1; mid=1; high=1;  displayChar(0);

}

/**

    初始化

**/

void init(){

    TMOD=0x11;    // TMOD赋值,以确定T0T1的工作方式。

    EA =1;           //开启中断总允许

    ET0 =ET1=1;  //开启定时器0,1中断允许

    TR0=TR1=1;     // 使TR0TR1置位,启动定时/计数器定时或计数

    TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0TL0TH1TL1

    TL0=TL1=T_Low_50ms;

}

/**

    显示方式的选择

**/

void DisplayStyle(){

    if(Count_3s<6){

           DisplayNumByOrder(Counter);//在数码管上显示对应的数值

       }else{

           DisplayHello();

       }  

}

/**

    流水灯

**/

void WaterLed(){

    P3=water_led_table[Water_Led_Index];

    if(Water_Led_Index==8){

       Water_Led_Index=0;

    }else{

       Water_Led_Index++;

    }

   

}

 

/**

    等待3

**/

void WaitingFor3s(){

    if(Switch==0){

       Count_3s++;

    }

}

int main(){

   

    init();

    while(1){

       if(Count_T0 ==10&&Count_3s<6){//计时中断0 间隔500ms循环移动数码管

           WaterLed();

           Count_T0 =0;

           WaitingFor3s();

      

           TL0 = T_High_50ms;     //50MS 

           TH0 = T_Low_50ms;

       }else{

           P3=0xff;//流水灯关闭

       }

       if(Count_T1 ==2&&Switch){//计时中断1  LED显示

           IsMinus();

           Count_T1=0;

           TL1 = T_High_50ms;

           TH1 = T_Low_50ms;

       }

       DisplayStyle();

    }

    return0;

}

//========函数区结束============================================

posted @ 2013-07-05 21:49  陈哈哈  阅读(3782)  评论(0编辑  收藏  举报