#include <reg52.H>//器件配置文件 #include <intrins.h> // 变量声明 unsigned int timer=0; char num=0; unsigned char const discode[] ={0xA0,0xBB,0x62,0x2A,0x39,0x2C,0x24,0xB8,0x20,0x28,0x7F}; //数码管显示码0123456789- unsigned char disbuff[4]={0,0,0,0}; //距离信息 sbit W0=P2^4; sbit W1=P2^5; sbit W2=P2^6; sbit W3=P2^7; //超声波传感器接口 sbit TX = P2^2; sbit DIAN=P0^5; //0:小数点亮 1:不亮 sbit Feng= P2^0; //0:蜂鸣器报警 1:不报警 /*******************************/ //扫描数码管 void Display(void) { num++; if(num==1) { W0=1; P0=discode[disbuff[0]]; // 段码赋值 W3=0; // 显示个位 DIAN=0; // 点亮小数点 } else if(num==2) { W3=1; P0=discode[disbuff[1]]; W2=0; // 显示十位 } else if(num==3) { W2=1; P0=discode[disbuff[2]]; W1=0; // 显示百位 } else if(num>=4) { W1=1; P0=discode[disbuff[3]]; W0=0; // 显示千位 num=0; } } /*****************************************/ //定时器1 void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块 { TH1=0xf8; TL1=0x30; //定时2ms Display(); //扫描显示 timer++; //变量加 if(timer>=400) //400次就是800ms { timer=0; TX=1; //每800MS输出20微妙高电平 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); TX=0; } } /********************************************/ //主函数 void main(void) { TMOD=0x11; //设T0为方式1,GATE=1; TH1=0xf8; //2MS定时 TL1=0x30; ET1=1; //允许T1中断 TR1=1; //开启定时器 EA=1; //开启总中断 while(1) { } } 请告诉我详细编程思路
时间: 2023-07-23 12:06:45 浏览: 201
这是一段基于 8051 单片机的程序,实现了超声波测距并将距离显示在四位共阴数码管上。
程序的主要思路如下:
1. 定义了一个名为 discode 的数组,保存了数码管显示码,包括数字 0~9 和小数点 "-"。
2. 定义了一个名为 disbuff 的数组,用于保存距离信息,最多显示四位。
3. 定义了一个名为 Display 的函数,用于扫描数码管并显示距离信息。
4. 定义了一个名为 zd3 的中断函数,用于定时器1中断,每隔 2 毫秒扫描一次数码管,并计时 800 毫秒启动超声波模块进行一次测距。
5. 在主函数中初始化定时器和中断,并进入一个死循环,保证程序不会退出。
具体的实现细节可以结合代码注释进行理解。
相关问题
#include<reg52.h>#include<intrins.h>
这段代码包含了两个头文件,`#include<reg52.h>`和`#include<intrins.h>`,它们通常用于使用Atmel AVR系列微控制器(如8051)的C语言编程。
`reg52.h`是针对8051特定的头文件,它定义了该CPU的寄存器结构和一些宏,帮助程序员访问硬件资源。这个头文件可能包含了CPU的通用寄存器定义,如P0、P1、A、B等,以及中断相关的宏。
`intrins.h`是包含一些编译器特定的内联汇编指令的头文件,它允许在C代码中直接使用汇编指令,提高代码性能。比如,它可能提供了对定时器中断、串口通信等操作的低级控制。
下面是一个简单的示例,展示了如何使用这些头文件来设置定时器1并触发中断[^4]:
```c
#include <reg52.h>
#include <intrins.h>
void setup_timer1(void) {
TMOD = 0x01; // 设置定时器1为模式1,计数从高位开始
TH1 = 0xFD; // 设置高8位计数初值
TL1 = 0x0D; // 设置低8位计数初值
EA = 1; // 开启全局中断
ET1 = 1; // 启动定时器1中断
}
ISR(TIMER1_OVF_vect) { // 当定时器1溢出时触发的中断服务程序
// 在这里处理溢出事件
}
```
#include <reg52.H>//器件配置文件 #include <intrins.h> // 变量声明 unsigned int timer=0; char num=0; unsigned char const discode[] ={0xA0,0xBB,0x62,0x2A,0x39,0x2C,0x24,0xB8,0x20,0x28,0x7F}; //数码管显示码0123456789- unsigned char disbuff[4]={0,0,0,0}; //距离信息 sbit W0=P2^4; sbit W1=P2^5; sbit W2=P2^6; sbit W3=P2^7; //超声波传感器接口 sbit TX = P2^2; sbit DIAN=P0^5; //0:小数点亮 1:不亮 sbit Feng= P2^0; //0:蜂鸣器报警 1:不报警 /*******************************/ //扫描数码管 void Display(void) { num++; if(num==1) { W0=1; P0=discode[disbuff[0]]; // 段码赋值 W3=0; // 显示个位 DIAN=0; // 点亮小数点 } else if(num==2) { W3=1; P0=discode[disbuff[1]]; W2=0; // 显示十位 } else if(num==3) { W2=1; P0=discode[disbuff[2]]; W1=0; // 显示百位 } else if(num>=4) { W1=1; P0=discode[disbuff[3]]; W0=0; // 显示千位 num=0; } }
这段代码实现了一个数码管的扫描显示功能,使用了一个常量数组discode来存储数码管的显示码,使用了disbuff数组来存储要显示的数字。在Display函数中,通过改变W0-W3的值来选择要显示的位数,然后将对应的段码赋值给P0来实现数码管的显示。同时,还设置了DIAN和Feng来控制小数点和蜂鸣器的状态。
阅读全文