主板介绍:P3^2~P^5为四个按键;P1^0~P1^7为8个LED灯

#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 typedef unsigned int uint; //对数据类型进行声明定义 typedef unsigned char u8; sbit k1=P3^5; //定义P31口是k1 sbit led=P1^0; //定义P10口是led /******************************************************************************* * 函 数 名 : delay * 函数功能 : 晶振11.0592M延时函数 *******************************************************************************/ void delay(uint z) { uint i,j; for(j=z;j>0;j--) for(i=112;i>0;i--); } /******************************************************************************* * 函 数 名 : keypros * 函数功能 : 按键处理函数,判断按键K1是否按下 *******************************************************************************/ void keypros() { if(k1==0) { delay(50); if(k1==0) //再次判断按键是否按下 led=~led; //led状态取反 } while(!k1); //检测按键是否松开 } /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main() { while(1) { keypros(); //按键处理函数 } }
计数器(计数器0用P3^4按钮,计数器1用P3^5按钮,不懂)

/*----------------------------------------------- 名称:计数器0 论坛:www.doflye.net 编写:shifang 日期:2009.5 修改:无 内容:通过外部按键计数进入中断执行LED取反 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit LED=P1^0; //定义LED端口 /*------------------------------------------------ 定时器初始化子程序(按钮P3^4控制,不知为什么) ------------------------------------------------*/ void Init_Timer0(void) { TMOD |= 0x01 | 0x04; //使用模式1,16位计数器,使用"|"符号可以在使用多个定时器时不受影响 TH0=0xFF; //给定初值 TL0=245; //从245计数到255 EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 } /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { Init_Timer0(); while(1); } /*------------------------------------------------ 定时器中断子程序 ------------------------------------------------*/ void Timer0_isr(void) interrupt 1 using 1 { TH0=0xFF; //重新给定初值 TL0=245; LED=~LED; //指示灯反相,可以看到闪烁 }

/*----------------------------------------------- 名称:计数器1 论坛:www.doflye.net 编写:shifang 日期:2009.5 修改:无 内容:通过外部按键计数进入中断执行LED取反 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit LED=P1^0; //定义LED端口 /*------------------------------------------------ 定时器初始化子程序 ------------------------------------------------*/ void Init_Timer1(void) { TMOD |= 0x10 | 0x40; //使用模式1,16位计数器,使用"|"符号可以在使用多个定时器时不受影响 TH1=0xFF; //给定初值 TL1=245; //从245计数到255 EA=1; //总中断打开 ET1=1; //定时器中断打开 TR1=1; //定时器开关打开 } /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { Init_Timer1(); while(1); } /*------------------------------------------------ 定时器中断子程序 ------------------------------------------------*/ void Timer1_isr(void) interrupt 3 { TH1=0xFF; //重新给定初值 TL1=245; LED=~LED; //指示灯反相,可以看到闪烁 }
中断定义:
当机器正在执行程序的过程中,一旦遇到一些异常或者特殊请求时,停止正在 执行的程序转入必要的处理,处理完毕后,立即返回断点继续执行。
51单片机中的中断源:
①外部中断
②定时器/计数器中断
③串口中断三类
单片机与外设数据传递方式
1.无条件传送: 不考虑外设状态信息,直接传送数据
2.查询传送: 不断查询外设状态信息,判断后决定是否传送数据
3.中断传送: 由外设主动向控制器提出申请的数据传送方式
4.DMA传送: 直接存储器存取,需要DMA控制器来完成而不需CPU干预
外部中断源
外部中断0 => 12号引脚(INT0/P3.2)
外部中断1 => 13号引脚(INT1/P3.3)
1、IE – 中断允许控制寄存器
2、TCON – 控制寄存器
EA 全局中断允许位,当此位是1时中断可用。(重要)
ET2 定时器/计数器2中断允许位
ES 串口中断允许位
ET1 定时器/计数器1中断允许位
EX1 外部中断1允许位
ET0 定时器/计数器0中断允许位
EX0 外部中断0允许位 (重要)
和定时器中断类似,使用外部中断需要开启全局中断允许位EA
,以及开启外部中断0允许位EX0
EA = 1; //开启总中断 EX0 = 1; //开启0号外部中断
TCON
TF1 定时器1溢出标志位
TR1 定时器1运行控制位
TF0 定时器0溢出标志位
TR0 定时器0运行控制位
IE1和IE0为状态位,即表示CPU对当前的中断执行状态,一般无需手动设置。需要设置的寄存器位是IT0
,以选择低电平信号触发还是负跳变信号触发。
低电平信号 :即该引脚电平信号为0时有效。
负跳变信号 :意思是电平从高跳至低时有效,即1→0的信号,而一直维持低电平则不会触发中断。
void initEx0() { //中断允许寄存器IE EA = 1; //开启总中断 EX0 = 1; //开启0号外部中断 //控制寄存器TCON IT0 = 1; //设置外部中断触发方式 //0 - 低电平触发 //1 - 负跳变触发 }
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 typedef unsigned char u8; //重新定义数据类型名 typedef unsigned int u16;//重新定义数据类型名 sbit key=P3^2; sbit led=P1^0; void delay(u16 num) { u16 x,y; for(x=num;x>0;x--) for(y=110;y>0;y++); } //外部中断1 void timer0() interrupt 0 { delay(10); if(key==0) led=~led; while(key); } void main()//主函数 { TCON |=0x01; IE=0x81; while(1) //主函数大循环 { } }
按钮外部中断0

/*----------------------------------------------- 名称:外部中断0电平触发 内容:通过中断接口P3.2连接的独立按键测试,按一次P1口的LED灯反向, 这里使用电平触发,所以一直按键不松开和一次按键效果不相同,按下会看到灯全部亮 说明中断一直在作用,用示波器看则是高频方波 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 /*------------------------------------------------ 外部中断程序 ------------------------------------------------*/ void ISR_Key(void) interrupt 0 using 1 { P1=~P1; //进入中断程序执行程序, //此时可以通过 EA=0指令暂时关掉中断 } typedef unsigned int uint; //对数据类型进行声明定义 void delay(uint i) { while(i--); } sbit btn=P3^2; sbit led=P1^0; /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { P1=0x55; //P1口初始值 EA=1; //全局中断开 EX0=1; //外部中断0开 IT0=0; //电平触发 while(1); }
先整理通用的代码,有些不知所以然

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include <intrins.h> //头文件包含 typedef unsigned char u8; //重新定义数据类型名 typedef unsigned short u16;//重新定义数据类型名 typedef unsigned long u32; //重新定义数据类型名 sbit PWM_OUT=P1^1; u8 idata PWM_Write_Byte[3]=0; //****************************祁绪电子 2020年5月*** // 定时器0初始化 晶振11059200,12T,输出50Hz的PWM,占空比0~255 // 定时器初值为:256-(11059200÷12÷50Hz÷256) = 184 = 0xB8 void PWM_Init(void) { TMOD &= 0xF0; //配置定时器工作模式 TMOD |= 0x02; //配置定时器工作模式 8位自动重装模式 TL0 = 0xB8;; //定时器初值 TH0 = 0xB8; //定时器重装初值 TR0 = 1; //启动定时器0 ET0=1; //允许定时器0申请中断 EA=1; //中断总闸闭合 } //****************************祁绪电子 2020年5月*** //定时器0的CPU处理函数,位置任意写都行 void PWM_Display_timer0() interrupt 1 { static u8 pwm_t=0; //局部变量,不丢失数据 if(pwm_t<PWM_Write_Byte[0]) { PWM_OUT=1; } else PWM_OUT=0; pwm_t++; } //***************************祁绪电子 2020年5月*** // PWM 数模变换数据分配 void PWM_Allot() { static u8 kkk=0; static u8 count=0; count++; if(count>150) { count=0; kkk++; PWM_Write_Byte[0]=kkk; //kkk为占空比自动增加 PWM_Write_Byte[1]=10; PWM_Write_Byte[2]=10; } } void main()//主函数 { PWM_Init(); while(1) //主函数大循环 { PWM_Allot(); } }
外部中断1电平触发

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit LED=P1^0; //定义LED端口 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { LED=0; //LED灯点亮 EA=1; //全局中断开 EX1=1; //外部中断0开 IT1=0; //琁T1=0表示电平触发 while(1) { //在此添加其他程序 } } /*------------------------------------------------ 外部中断程序 ------------------------------------------------*/ void ISR_INT1(void) interrupt 2 { if(!INT1) { DelayMs(10);//在此处可以添加去抖动程序,防止按键抖动造成错误 if(!INT1) while(!INT1);//等待按键释放 { LED=!LED; } } } /*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } }
外部中断0下降沿触发

/*----------------------------------------------- 名称:外部中断0边沿触发 论坛:www.doflye.net 编写:shifang 日期:2009.5 修改:无 内容:通过中断接口P3.2连接的独立按键测试,按一次P1口的LED灯反向, 这里使用边沿触发,所以一直按键不松开和一次按键效果相同,区 别于电平触发 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { P1=0x55; //P1口初始值 EA=1; //全局中断开 EX0=1; //外部中断0开 IT0=1; //边沿触发 while(1) { //在此添加其他程序 } } /*------------------------------------------------ 外部中断程序 ------------------------------------------------*/ void ISR_Key(void) interrupt 0 using 1 { P1=~P1; //s3按下触发一次,P1取反一次 }
外部中断1下降沿触发

/*----------------------------------------------- 名称:外部中断1电下降沿平触发 论坛:www.doflye.net 编写:shifang 日期:2009.5 修改:无 内容:通过中断接口P3.3连接的独立按键测试,按一次P1.0口的LED灯反向, 作用效果和中断0相同 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit LED=P1^0; //定义LED端口 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 /*------------------------------------------------ 主程序 ------------------------------------------------*/ main() { LED=0; //LED灯点亮 EA=1; //全局中断开 EX1=1; //外部中断1开 IT1=1; //IT1=1表示边沿触发 while(1) { //在此添加其他程序 } } /*------------------------------------------------ 外部中断程序 ------------------------------------------------*/ void ISR_INT1(void) interrupt 2 { if(!INT1) { DelayMs(10);//在此处可以添加去抖动程序,防止按键抖动造成错误 if(!INT1) //while(!INT1);//等待按键释放 { LED=!LED; } } } /*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); } /*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } }