【51单片机】【protues仿真】基于51单片机压力测量仪系统
目录
一、主要功能
二、使用步骤
三、硬件资源
四、软件设计
五、实验现象
一、主要功能
1、数码管显示测量压力值
2、测量范围15kpa-115kap
3、步进值0.1
二、使用步骤
基于51单片机的压力测量仪设计通常包含压力传感器,数码管显示模块,按键模块。
三、硬件资源
1、51单片机核心模块
2、压力传感器
3、数码管显示模块
四、软件设计
#include <AT89X52.h>
#include <intrins.h>
#include <stdio.h>
#define R24C04ADD 0xA1
#define W24C04ADD 0xA0
//ADC0832的引脚
sbit ADCS =P2^2; //ADC0832 chip seclect
sbit ADDI =P2^4; //ADC0832 k in
sbit ADDO =P2^4; //ADC0832 k out
sbit ADCLK =P2^3; //ADC0832 clock signal
sbit SDA = P2 ^ 1; //数据线
sbit SCL = P2 ^ 0; //时钟线
bit bAck; //应答标志 当bbAck=1是为正确的应答
unsigned char dispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f}; //位扫描
unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff}; //共阳数码管字段码
unsigned char dispbuf[4];
unsigned int temp;
unsigned char getdata; //获取ADC转换回来的值
void delay_1ms(void) //12mhz delay 1.01ms
{
unsigned char x,y;
x=3;
while(x--)
{
y=40;
while(y--);
}
}
void display(void) //数码管显示函数
{
char k;
for(k=0;k<4;k++)
{
P1 = ~dispbitcode[k];
P0 = dispcode[dispbuf[k]];
if(k==1) //加上数码管的dp小数点
P0&=0x7f;
delay_1ms();
}
}
//发送一个字节的数据
void SendByte(unsigned char c)
{
unsigned char BitCnt;
for(BitCnt = 0;BitCnt < 8;BitCnt++)
{
if((c << BitCnt)& 0x80) SDA = 1; //判断发送位
else SDA = 0;
_nop_();
SCL = 1; //时钟线为高,通知从机开始接收数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0;
}
_nop_();
_nop_();
SDA = 1; //释放数据线,准备接受应答位
_nop_();
_nop_();
SCL = 1;
_nop_();
_nop_();
_nop_();
if(SDA == 1) bAck =0;
else bAck = 1; //判断是否收到应答信号
SCL = 0;
_nop_();
_nop_();
}
//接收一个字节的数据
unsigned char RevByte()
{
unsigned char retc;
unsigned char BitCnt;
retc = 0;
SDA = 1;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_nop_();
SCL = 0; //置时钟线为低,准备接收
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1; //置时钟线为高使得数据有效
_nop_();
_nop_();
retc = retc << 1; //左移补零
if (SDA == 1)
retc = retc + 1; //当数据为1则收到的数据+1
_nop_();
_nop_();
}
SCL = 0;
_nop_();
_nop_();
return(retc); //返回收到的数据
}
unsigned char WIICByte(unsigned char WChipAdd,unsigned char InterAdd,unsigned char WIICData)
{
StartI2C(); //启动总线
SendByte(WChipAdd); //发送器件地址以及命令
if (bAck==1) //收到应答
{
SendByte(InterAdd); //发送内部子地址
if (bAck ==1)
{
SendByte(WIICData); //发送数据
if(bAck == 1)
{
StopI2C(); //停止总线
return(0xff);
}
else
{
return(0x03);
}
}
else
{
return(0x02);
}
}
return(0x01);
}
void main(void)
{
unsigned int OverCounter = 0;
unsigned char ptemp;
bit OverFlg = 0;
unsigned int temp,ppress = 0;
float press;
while(1)
{
getdata=Adc0832(0);
if(14<getdata<243) //当压力值介于15kpa到115kpa之间时,遵循线性变换
{
int vary=getdata; //y=(115-15)/(243-13)*X+15kpa 线性区间标度变换公式:
press=((10.0/23.0)*vary)+9.3; //测试时补偿值为9.3
temp=(int)(press*10); //放大10倍,便于后面的计算
if(temp != ppress)
{
ppress = temp;
OverFlg = 1;
}
dispbuf[3]=temp/1000; //取压力值百位
dispbuf[2]=(temp%1000)/100; //取压力值十位
dispbuf[1]=((temp%1000)%100)/10; //取压力值个位
dispbuf[0]=((temp%1000)%100)%10; //取压力值十分位
display();
if (temp > 100)
{
if(OverFlg == 1)
{
OverCounter++;
WIICByte(W24C04ADD,0x01,(OverCounter/0xff)); //低位
WIICByte(W24C04ADD,0x02,(OverCounter%0xff)); //高位
OverFlg = 0; //清除标志
}
}
}
}
}
五、实验现象
演示视频: