标题:
单片机双积分AD-数码管 Proteus仿真程序
[打印本页]
作者:
展乾741
时间:
2020-1-4 12:14
标题:
单片机双积分AD-数码管 Proteus仿真程序
使用两个运放组成积分电路,比较器电路,结合单片机定时器计数,测量ADC,并使用protues仿真实现
视频连接:
https://www.bilibili.com/video/av81800813/
51hei.png
(20.08 KB, 下载次数: 21)
下载附件
2020-1-4 16:38 上传
单片机源程序如下:
#include<reg52.h>
//#include<absacc.h>
//#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define GPIO_DIG P0 //传送数据的端口设为P0,以上端口根据实际硬件电路图可做修改
sbit S4=P2^3;
sbit S3=P2^2; //使能信号
sbit S2=P2^1; //读写控制信号
sbit S1=P2^0; //数据命令选择端口
sbit P30=P3^0;
sbit P31=P3^1;
sbit P33=P3^3;
uint ss,vin;
uchar lo,kl = 0;
//--定义全局变量--//
unsigned char code DIG_CODE[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//0、1、2、3、4、5、6、7、8、9的显示码
unsigned char DisplayData[4];
//用来存放要显示的4位数的值
/****************10MS延时函数******************************/
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 20;
j = 113;
do
{
while (--j);
} while (--i);
}
/****************1MS延时函数******************************/
void delay(unsigned int n)
{
unsigned int i,j;
for(j=n;j>0;j--)
for(i=112;i>0;i--);
}
void led_byte(unsigned int byte_data) //以十进制的方式显示一个字符变量
{
DisplayData[0] = ~DIG_CODE[(byte_data % 10000 /1000)]; //求千位数
DisplayData[0] |= 0x80; //小数点
DisplayData[1] = ~DIG_CODE[(byte_data%1000/100)]; //求百位数
DisplayData[2] = ~DIG_CODE[(byte_data%100/10)]; //求十位数
DisplayData[3] = ~DIG_CODE[(byte_data%10)]; //求个位数
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 使用数码管显示
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DigDisplay()
{
unsigned char i;
led_byte(vin);
for(i=0;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
S1=0;S2=1;S3=1;S4=1; break;//显示第0位
case(1):
S1=1;S2=0;S3=1;S4=1; break;//显示第1位
case(2):
S1=1;S2=1;S3=0;S4=1; break;//显示第2位
case(3):
S1=1;S2=1;S3=1;S4=0; break;//显示第3位
}
GPIO_DIG=DisplayData[i];//发送段码
delay(10); //扫描间隔时间设定
GPIO_DIG=0x00;//消隐
}
}
/**************数码管显示*************************/
void my_t0(void) interrupt 1 //定时器0中断用于固定时间对输入待测电压进行积分
{
TR0 = 0; //T0中断关 ///
TH0 = 0;
TL0 = 0;
lo++; ///
TF0 = 0; //清除T0中断标志 ///
TR0 = 1; //T0中断开
}
void my_int0(void) interrupt 0 //外部中断 用于反积分过程结束检测
{
EX0 = 0; //INT0中断关
TR0 = 0; //T0中断关
TF0 = 0; //清除T0中断标志
ss = TH0 * 256 + TL0;
if(ss == 5) ss = vin; //解决数据缓存溢出BUG
else {
// ss = ss/10 + lo*6553 ; //计算电压
// ss = ss/10 + lo*6553 + 37; //补偿系统误差
if((ss % 10000 /1000) < 4)
vin = ss/10 + lo*6553 + ss/1000; //补偿系统误差
else
vin = ss/10 + lo*6553 + ss/2000;
}
TH0 = 0;
TL0 = 0;
kl = 1;
lo = 0;
ss = 0;
EA = 0;
}
void main()
{
char i = 0;
P33 = 0;
P31 = 0; ///
P30 = 1;
kl = 0;
EA = 1; //中断开
ET0 = 1; //定时计数0中断开
//IP = 1; //定时0中断最高优先级 =2
TMOD = 0x01; //定时0,1模式1 2个16位定时/计数器
EX0 = 1; //INT0中断开
TCON=0x01; //INT0负边缘触发或低电平触发在此好象作用相同
IT0 = 1;
while(1)
{
if(kl == 1 && i == 20)
{
ss = 0;
lo = 0;
// vin = 0;
TR0 = 0;
P31 = 0;
P33 = 0;
P30 = 1; //选择放电 ///
delay(100);
kl = 0;
P30 = 0;
P33 = 0;
P31 = 1; //选择输入电压
Delay10ms();
TH0 = 0;
TL0 = 0;
P31 = 0;
P33 = 1; //选择比较电压
TF0 = 0; //清除T0中断标志
TR0 = 1; //定时计数0起动
EX0 = 1;
EA = 1;
}
i++;
if(i==21) i=0; //彻底完成第一次转换后进行下一次转换,防止互相干扰
// delay(1);
delay(1);
DigDisplay();
}
}
复制代码
51hei.png
(10.95 KB, 下载次数: 19)
下载附件
2020-1-4 16:38 上传
所有资料51hei提供下载:
单片机双积分AD-数码管.rar
(89.47 KB, 下载次数: 49)
2020-1-4 12:11 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
学习习鸭
时间:
2021-3-22 15:48
你好,可以问问你这个双积分程序的思路么?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1