找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1101|回复: 0
收起左侧

C51单片机的AD PCF5819采集程序 带Proteus仿真和代码

[复制链接]
ID:261183 发表于 2023-4-27 09:02 | 显示全部楼层 |阅读模式
分享一下做基于C51的AD数据采集用的PCF5819 有实验文档 还有仿真以及代码
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png
将AD转换后,转成电压量(保留2位小数),显示于数码管,并发送到PC机的串口调试助手上。
二、 仪器用具及材料
Keil、Proteus 8 Professional、串口助手、串口模拟器。
三、 实验内容及原理
1.  电路分析
本次使用的数码元器件有八位共阳数码管,串口,PCF8591以及单片机STC15W4K32S4。
(具体电路图见附件一)
2.  软件编程
(1)  数码管
因为实验涉及小数所以本次显示数码的码字有两种,一种是不带小数点的,一种是带小数点的。不带小数点的 “code unsigned char segcode[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};”
带小数点的“ code unsigned char segcode1[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x7F};”
数码管还涉及到三位数字的显示,虽然是一个整数和两个小数,但本质上可以用一个函数先将这个数直接变成三位数,然后将第一位的数字加上“.”显示的效果就是保留两位小数的数字。具体如下

int fenli(float e)  //分离函数 将AD转换以后的小数变成三位整数
{
    int x,y,z;
    x=e*1000;
    z=e*100;
    y=x%10;
    if(y>=5)
    {
        z=z+1;
    }
    return z;
}
数码管显示小数函数如下:
void shumaguan(int x)   //数码管显示函数显示被分离的数字
{
    int i,j,ge,shi,bai;
    bai=x/100%100%10;  
    shi=x/10%100%10;
    ge=x%1000%10;
    P0=segcode[10];  //清除所有位数
    P2=0xe0;
    P2=0;
    P0=0xFF;
    P2=0xc0;
    P2=0;
    P0=segcode1[bai];  // 显示百位
    P2=0xe0;
    P2=0;
    P0=0x01;
    P2=0xc0;
    P2=0;
    for(i=0;i<1;i++)
  for(j=0;j<1;j++);
    P0=segcode[shi];  //显示十位
    P2=0xe0;
    P2=0;
    P0=0x02;
    P2=0xc0;
    P2=0;
    P0=segcode[ge];  //显示个位
    P2=0xe0;
    P2=0;
    P0=0x04;
    P2=0xc0;
    P2=0;
}
(2)  I2C的软件编程
主要有以下几个步骤1.启动信号;2停止信号;3应答信号;4等待应答信号;5发送字节;6接收字节;
(3)  串口的编程
   本次串口的输出需要用到文本格式所以需要在头文件上加上stdio.h,另外还需要改写char putchar(char c)底层函数这样就可以用printf()函数通过串口来发送文本,代码如下。
char putchar(char c)
{  ES=0;  //关闭串口中断
   SBUF=c;
   while(!TI);   //等待发送完成
   TI=0;         //清除发送完成标志
   ES=1;  //开启串口中断
   return c;
}
(4)  PCF8591的串口通信代码以及采集AD的IO口选择。
本次实验主要用到的是AIN0口并不允许模拟电压输出模拟输入方式是4通道输入,另外不自动增加通道号因此控制字节为0x00;具体代码如下:
unsigned char PCF8591_Adc(void)
{
unsigned char temp;
    IIC_Start();
    IIC_SendByte(0x90);
    IIC_WaitAck();
    IIC_SendByte(0x00);
    IIC_WaitAck();

    IIC_Start();
   
IIC_SendByte(0x91);
    IIC_WaitAck();
    temp=IIC_RecByte();
    IIC_SendAck(1);
    IIC_Stop();
    return temp;
}
(5)  主函数的编程
流程图如右图。


代码如下
int main()
{
int a,b;
  float c=255,e;
  int x,n=1;

  while(1)
  {
  while(n)
      {
      PCF8591_Adc();
      a=PCF8591_Adc();
      e=a/c*5;
      x=fenli(e);
      UartInit();
      printf("%.2fV\n",e);
      shumaguan(x);

          n=0;
      }
      PCF8591_Adc();
      b=PCF8591_Adc();   
      if(b!=a)
      {
          n=1;
      }
  }
}      
总的代码见附件二。
四、 实验过程与数据记录
1.   将原理图中的滑动变阻器调成100%启动proteus模拟软件,串口输出5.00V如下图


数码管显示如下图

将滑动变阻器下调到99%串口输出如下图

数码管显示如下

将滑动变阻器改成50%串口显示如下

数码管显示如下图


9、总结
这次实验涉及的内容较多有数码管的显示串口以及I2C的通信等,算是个不大不小的项目,这次实验也是我巩固了之前所学C语言的知识,也对串口通信以及I2C的通信有了一个新的了解和认知,希望在今后的学习中能挑战更多更有趣的实验。
51hei.png
下载: 仿真和文档.7z (191.53 KB, 下载次数: 10)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表