当前位置: 首页 > news >正文

【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;    //清除标志
          }
      }

       }        
  }

五、实验现象

演示视频:

http://www.dtcms.com/a/365220.html

相关文章:

  • wpf触发器
  • Dify 从入门到精通(第 73/100 篇):Dify 的高级 RAG 优化(高级篇)
  • 调制端Phase Shift Discriminator(PSD)算法原理
  • 数据结构从青铜到王者第二十话---Map和Set(3)
  • windows安装PostgreSQL 和TimescaleDB
  • 数据结构:顺序栈与链栈的原理、实现及应用
  • 集成 Node.js 模块:文件系统与网络操作
  • 深入理解 Java 集合框架:底层原理与实战应用
  • 数据结构——二叉树+堆
  • .gitignore 文件为什么无效。
  • 开学季,老师如何用阅兵仪式激励学生?
  • PNP具身解读——RSS2025论文加州伯克利RLDG: 通过强化学习实现机器人通才策略提炼。
  • 在DDPM(扩散模型)中,反向过程为什么不能和前向一样一步解决,另外实际公式推导时反向过程每一步都能得到一个预测值,为什么还要一步一步的推导?
  • GEM5学习(4): 运行全系统模式的ARM系统
  • Docker 运行 PolarDB-for-PostgreSQL 的命令,并已包含数据持久化配置
  • 梅赛德斯-AMG PETRONAS F1车队携手SAP Cloud ERP:以数字化驱动精确与高效
  • HTML全屏功能实现汇总
  • 缠论笔线段画线,文华财经期货指标公式,好用的缠论指标源码
  • 从全栈开发到微服务架构:一位Java工程师的实战经验分享
  • 突破闭集限制:3D-MOOD 实现开集单目 3D 检测新 SOTA
  • Cesium 实战 - 自定义纹理材质 - 箭头流动线(图片纹理)
  • Corona 13 渲染器安装与使用教程(适用于3ds Max 2016–2026)
  • 【LeetCode热题100道笔记】搜索旋转排序数组
  • 认知诊断模型发展与NeuralCD框架笔记
  • Springboot3+SpringSecurity6Oauth2+vue3前后端分离认证授权
  • 七、面向对象技术
  • Moonchain:「新加坡大华银行」加持下连接现实金融与链上经济的价值通道
  • 从公共形象到专属定制,井云交互数字人满足金融/政务多元需求
  • 23种设计模式-适配器(Adapter)模式
  • 如何通过level2千档盘口分析挂单意图