实验2 中断和定时计数器实验
1.当单片机的INT0进入低电平触发方式,进入相应的中断服务程序,P0口做输出口,接8只发光二极管,点亮发光二级管,控制蜂鸣器响。当INT1为低电平时进入中断服务程序,发光二级管灭。
接线:将P0和JP1连接、P3和JP5连接
#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+P3;J12+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循环计时
接线方式:
1、P0接数码管J12,实现段选
2、译码器和数码管位选输入短接,J15+J16
3、P3控制发光二极管,P3+JP1
4、P2用来控制译码器的输入
**/
//========全局变量区============================================
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赋值,以确定T0和T1的工作方式。
TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
TL0=TL1=T_Low_50ms;
EA =1;//开启中断总允许
ET0 =ET1=1;
IT0 =IT0=1; //开启定时器0,1中断允许
TR0=TR1=1; // 使TR0或TR1置位,启动定时/计数器定时或计数
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;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
TL0=T_Low_50ms;
Count++;
}
/**
用定时器1实现数码管的前两位59s循环计时。
**/
void int1() interrupt 3//定时/计数器T1中断
{
TH1=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
TL1=T_Low_50ms;
Count_T1++;
}
//========中断函数结束==========================================
4、同时用两个定时器控制蜂鸣器发声,定时器0控制频率,定时器1控制同个频率持续的时间,间隔300ms依次输出1,10,50,100,200,400,800,1k(hz)的方波。
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
/**
同时用两个定时器控制蜂鸣器发声,
定时器0控制频率,定时器1控制同个频率持续的时间,
间隔300ms依次输出1,10,50,100,200,400,800,1Table_Index(hz)的方波。
**/
#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*50ms。1ms=1000us。Count_T1每次+1间隔50ms。20000/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赋值,以确定T0和T1的工作方式。
EA =1; //开启中断总允许
ET0 =ET1=1; //开启定时器0,1中断允许
TR0=TR1=1; // 使TR0或TR1置位,启动定时/计数器定时或计数
TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
TL0=TL1=T_Low_50ms;
}
int main(){
f = Table_F[0];
init();
while(1){
}
return0;
}
5. 利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”,到此保持住。
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
/**
利用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度往下递减直至765398并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HELLO”,到此保持住。
**/
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/**
接线方式:
1、P0接数码管J12,实现段选
2、译码器和数码管位选输入短接,J15+J16
3、P3控制发光二极管,P3+JP1
4、P2用来控制译码器的输入
**/
//=========全局变量区============================================
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赋值,以确定T0和T1的工作方式。
EA =1; //开启中断总允许
ET0 =ET1=1; //开启定时器0,1中断允许
TR0=TR1=1; // 使TR0或TR1置位,启动定时/计数器定时或计数
TH0=TH1=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
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;
}
//========函数区结束============================================
作者:kissazi2
出处:http://www.cnblogs.com/kissazi2/
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。