找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 656|回复: 1
打印 上一主题 下一主题
收起左侧

单片机ADC0832模数转换芯片显示采集电压Proteus仿真程序

[复制链接]
跳转到指定楼层
楼主
最近在学习ADC0832这款芯片,虽然说型号老了点,但是学懂了这个,其他AD芯片就不是这么难了。写了程序, 给大家学习参考!

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. //-----------------------------------------------------------------
  2. //  说明: 调整VR1时,ADC0832将模拟电压转换为数字电压显示在1602液晶
  3. //        屏第0行,液晶屏第1行同时以进程条方式显示当前电压大小.
  4. //
  5. //-----------------------------------------------------------------
  6. #include <reg51.h>
  7. #include <intrins.h>
  8. #include <string.h>
  9. #define uchar  unsigned char
  10. #define uint unsigned int
  11. //ADC0832引脚定义
  12. sbit CS   =  P1^0;                //片选线(电路中固定连接低电平)
  13. sbit CLK  =  P1^1;                //时钟线
  14. sbit DIO  =  P1^2;                //数据线
  15. //LCD1602端口定义
  16. sbit RS = P2^0;                        //寄存器选择
  17. sbit RW = P2^1;                        //读写控制
  18. sbit E  = P2^2;                        //使能控制
  19. #define LCD_PORT  P0        //液晶端口
  20. uchar Disp_Buff1[] = " VOLTAGE:  0.00V";        //数字电压显示缓冲
  21. uchar Disp_Buff2[16];                                                //进程条图形显示缓冲
  22. #define delay4us() { _nop_();_nop_();_nop_();_nop_();}
  23. //-----------------------------------------------------------------
  24. // 延时函数
  25. //-----------------------------------------------------------------
  26. void delay_ms(uint x)
  27. {
  28.         uchar t; while(x--) for(t = 0; t < 120; t++);
  29. }

  30. //-----------------------------------------------------------------
  31. // 读LCD忙状态
  32. //-----------------------------------------------------------------
  33. bit Read_LCD_Busy_Flag()
  34. {
  35.         uchar result;
  36.         LCD_PORT=0xff;                        //液晶屏端口电平拉高
  37.         RS=0;RW=1;                            //选择命令寄存器,准备读
  38.         E=1;delay4us(); result=P0; E=0;       //下降沿读命令寄存器
  39.         return (result&0x80)? 1 : 0;          //返回忙状态
  40. }

  41. //-----------------------------------------------------------------
  42. // 写LCD命令
  43. //-----------------------------------------------------------------
  44. void Write_LCD_Command(uchar cmd)        
  45. {
  46.         while(Read_LCD_Busy_Flag());           //液晶屏忙等待
  47.         RS=0;RW=0;                             //选择命令寄存器,准备写
  48.         E=0; _nop_();_nop_();LCD_PORT=cmd;     //数据送到液晶屏端口
  49.         delay4us();E=1;delay4us();E=0;         //写入后禁止液晶屏
  50. }

  51. //-----------------------------------------------------------------
  52. // 写LCD数据
  53. //-----------------------------------------------------------------
  54. void Write_LCD_Data(uchar dat)
  55. {
  56.         while(Read_LCD_Busy_Flag());           //液晶屏忙等待
  57.         RS=1;RW=0;                             //选择数据寄存器,准备写
  58.         E=0; LCD_PORT=dat; delay4us();         //数据送到液晶屏端口
  59.         E=1;delay4us(); E=0;                   //写入后禁止液晶屏
  60. }

  61. //-----------------------------------------------------------------
  62. // 在LCD指定行/列位置显示字符串
  63. //-----------------------------------------------------------------
  64. void LCD_Show_String(uchar r,uchar c, char *s)
  65. {
  66.         uchar i=0;
  67.         uchar code DDRAM[]={0x80,0xc0};              //液晶屏上下两行的DDRAM首地址   
  68.         Write_LCD_Command(DDRAM[r] | c);             //设置显示起始位置
  69.         while(s[i] && i<16) Write_LCD_Data(s[i++]);  //输出显示字符
  70. }

  71. //-----------------------------------------------------------------
  72. // LCD初始化
  73. //-----------------------------------------------------------------
  74. void LCD_Initialise()
  75. {
  76.         Write_LCD_Command(0x38); delay_ms(1);
  77.         Write_LCD_Command(0x0C); delay_ms(1);
  78.         Write_LCD_Command(0x06); delay_ms(1);
  79.         Write_LCD_Command(0x01); delay_ms(1);
  80. }

  81. //-----------------------------------------------------------------
  82. // 获取AD转换结果 ( 0通道 )
  83. //-----------------------------------------------------------------
  84. uchar Get_AD_Result()
  85. {
  86.         uchar i,dat1=0,dat2=0;
  87.         //使能ADC0832,时钟线初始置低电平
  88.         CS=0; CLK=0;
  89.         //第1个时钟脉冲上升沿之前,通过DIO选择模式
  90.         DIO=1;        _nop_();_nop_();
  91.         CLK=1;        _nop_();_nop_();
  92.         //第2个时钟脉冲上升沿之前,通过DIO选择模式
  93.         //设DI=1选择单端(SGL) 设DI=0 选择分差(DIF)
  94.         //下面设置的是单端模式
  95.         CLK=0; DIO=1;  _nop_();_nop_();
  96.         CLK=1;         _nop_();_nop_();
  97.         //第2个时钟脉冲上升沿之前,设DI=0/1,分别对应选择CH0/CH1
  98.         CLK=0; DIO=0;  _nop_();_nop_();
  99.         CLK=1;         _nop_();_nop_();
  100.         //第3个时钟脉冲下升沿之后置DI=1,释放数据线,准备接收(设置原理可参考第一章端口说明)
  101.         //P1端口读取数据时需要先写1,否则总线将出现逻辑冲突(黄色方块闪烁)
  102.         CLK=0; DIO=1;  _nop_();_nop_();
  103.         //根据时序图可知,在正式读取转换数据之前,此时的D0将固定输出0
  104.         //P3=(uchar)DIO;
  105.         //第4~11,共8个下降沿读数据(MSB-LSB)
  106.         for(i=0;i<8;i++)
  107.         {
  108.                 CLK=1;        _nop_();_nop_();
  109.                 CLK=0;        _nop_();_nop_();
  110.                 dat1<<=1;
  111.                 if(DIO)
  112.                         dat1=dat1+0x01;
  113.         }
  114.         //第11~18,共8个下降沿读数据(LSB——MSB)
  115.         for(i=0;i<8;i++)
  116.         {
  117.                 dat2>>=1;
  118.                 if(DIO)
  119.                         dat2=dat2+0x80;
  120.                 CLK=1;       _nop_();_nop_();
  121.                 CLK=0;       _nop_();_nop_();
  122.         }
  123.         CS=1; //禁止ADC0832
  124.         //如果MSB——LSB和LSB——MSB读取的结果相同则返回读取的结果,否则返回0
  125.         if(dat1==dat2)
  126.                 return dat1;
  127.         return 0x00;
  128. }

  129. //-----------------------------------------------------------------
  130. // 主程序
  131. //-----------------------------------------------------------------
  132. void main()
  133. {
  134.         uchar  AD; uint        d;                //注意d的类型为uint
  135.         LCD_Initialise();                        //初始化LCD
  136.         while(1)
  137.         {       
  138.                 AD=Get_AD_Result();    //获取A/D转换值
  139.                 //根据四舍五入法计算电压值(放大100倍以便分解)
  140.                 d=AD*500.0*2/511.0;
  141.                 //根据舍尾取整数计算电压值(放大100倍以便分解)
  142.                 //将d = AD*500.0/256;
  143.                 //将AD转换后得到数据分解为三个数位
  144.                 Disp_Buff1[11] = d / 100     +'0';
  145.                 Disp_Buff1[13] = d / 10 %10  +'0';
  146.                 Disp_Buff1[14] = d % 10      +'0';
  147.                 LCD_Show_String(0,0,Disp_Buff1);
  148.                 //将模数值折算为实心方块及空心方框字符个数,控制进程条图形显示
  149.         }
  150. }
复制代码

所有资料51hei附件下载:
仿真程序.7z (34.52 KB, 下载次数: 50)

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:994634 发表于 2023-12-14 08:24 | 只看该作者
注释很到位,便于学习和参考。已下载,谢谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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