找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机控制实现ADC TLC549一路模拟电压采集程序Proteus仿真

[复制链接]
跳转到指定楼层
楼主
使用proteus进行仿真:运用单片机(AT89C52、STM32、MSP430等)控制实现一路模拟电压采集(ADC)
需实现以下功能:
1、电压测量范围0~5V
2、设置电压上限4.5V,超过上限电压红色LED灯警示、蜂鸣器警示1S;
3、设置电压下限0.5V,低于下限电压黄色LED灯警示、蜂鸣器警示1S;
4、显示实时测量电压值、上下限电压值,将采集到的电压数据显示在LCD1602液晶屏的第一行中间位置,上下限电压值显示在LCD1602液晶屏的第二行位置;
5、将学号后两位显示在液晶屏的右下角;
6、AD芯片选型:ADC0804,TLC549等。
在附件里还有一个可以自己计算可调的上下限电压的python代码。

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

单片机源程序如下:
  1. #include <reg51.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sbit fengmingqi = P1^0;    // 蜂鸣器引脚定义
  5. sbit LED_red = P1^6;       // 红色LED报警引脚定义
  6. sbit LED_yellow = P1^7;    // 黄色LED报警引脚定义
  7. sbit RS = P2^0;            // LCD控制引脚定义
  8. sbit RW = P2^1;            // LCD控制引脚定义
  9. sbit E = P2^2;             // LCD控制引脚定义
  10. sbit TLC549_CLK = P2^3;    // TLC549时钟引脚定义
  11. sbit TLC549_CS = P2^4;     // TLC549片选引脚定义
  12. sbit TLC549_DO = P2^5;     // TLC549数据引脚定义

  13. uchar volt_h =  0xBF, volt_l = 0x68;   // 设置电压上下限 4.5V 0.5V
  14. unsigned char s1[] = "21";             // 显示学号字符串
  15. unsigned char s2[] = "2.05V 3.75V";      // 显示电压上下限字符串

  16. void delayms(uchar ms)
  17. {
  18.     uchar i;
  19.     while (ms--)
  20.         for (i = 0; i < 123; i++);   // 延时函数,以毫秒为单位
  21. }

  22. void delayus(uchar us)
  23. {
  24.     while (us--);                    // 延时函数,以微秒为单位
  25. }

  26. void w_com(uchar com)
  27. {
  28.     RS = 0;            // RS=0表示选择指令寄存器
  29.     RW = 0;            // RW=0表示写,RW=1表示读
  30.     E = 1;             // 使能端
  31.     P0 = com;          // 指令代码从P0口送出
  32.     E = 0;             // 下降沿执行
  33.     delayms(1);
  34. }

  35. void w_dat(uchar dat)
  36. {
  37.     RS = 1;            // RS=1表示选择数据寄存器
  38.     RW = 0;
  39.     E = 1;
  40.     P0 = dat;          // 数据从P0口送出
  41.     E = 0;             // 下降沿执行
  42.     delayms(1);
  43. }

  44. void lcd_ini(void)
  45. {
  46.     delayms(10);
  47.     w_com(0x38);       // 功能设置:8位口2行
  48.     delayms(10);
  49.     w_com(0x0C);       // 显示设置:开显示,关光标,无闪烁
  50.     delayms(10);
  51.     w_com(0x06);       // 输入模式:右移一格,地址加1
  52.     delayms(10);
  53.     w_com(0x01);       // 清显示
  54.     delayms(10);
  55.     w_com(0x38);       // 功能设置:8位口2行
  56.     delayms(10);
  57. }

  58. uchar TLC549_ADC(void)
  59. {
  60.     uchar i, temp;
  61.     TLC549_CLK = 0;
  62.     TLC549_CS = 0;
  63.     for (i = 0; i < 8; i++)
  64.     {
  65.         temp <<= 1;
  66.         temp |= TLC549_DO;
  67.         TLC549_CLK = 1;
  68.         TLC549_CLK = 0;
  69.     }
  70.     TLC549_CS = 1;
  71.     delayus(20);
  72.     return temp;
  73. }

  74. void main(void)
  75. {
  76.     uint temp, d, i = 0, j = 0;
  77.     uchar digit1, digit2, digit3; // 个位数和小数点后两位数的变量
  78.     lcd_ini();
  79.     w_com(0xC1);    // 第二行显示电压上下限
  80.     while (s2[j] != '\0')
  81.     {
  82.         w_dat(s2[j]);
  83.         j++;
  84.     }
  85.     w_com(0xCE);    // 第二行第14列显示学号
  86.     while (s1[i] != '\0')
  87.     {
  88.         w_dat(s1[i]);
  89.         i++;
  90.     }
  91.     while (1)
  92.     {
  93.         temp = TLC549_ADC();
  94.         d = temp * 1.96;  // 基准电压5V转换为电压值
  95.         
  96.         digit1 = d %1000 / 100;     // 计算个位数
  97.         digit2 = d %100 / 10;       // 计算小数点后第一位
  98.         digit3 = d %10;             // 计算小数点后第二位


  99.         w_com(0x84);
  100.         w_dat(digit1 + 0x30);      // 显示电压值个位
  101.         w_dat('.');                 // 显示小数点
  102.         w_dat(digit2 + 0x30); // 显示电压值小数点后第一位
  103.         w_dat(digit3 + 0x30);       // 显示电压值小数点后第二位
  104.         w_dat('V');
  105.         
  106.       
  107.            if(temp<=volt_l&&temp>=0x00)        //低于下限电压,黄色LED亮蜂鸣器响
  108.                         {
  109.                                  LED_red=1;   
  110.                                  LED_yellow =0;         //黄色灯示警
  111.                                  fengmingqi=0;                        //蜂鸣器示警
  112.                                  delayms(1000);
  113.                                  fengmingqi=1;
  114.                                  delayms(1000);         
  115.                         }
  116.                         else if(temp<volt_h&&temp>volt_l)     //正常电压
  117.                         {
  118.                                  LED_red =1;
  119.                                  LED_yellow =1;
  120.                                  fengmingqi=1;
  121.                                  delayms(1000);
  122.                         }
  123.                         else                //高于上限电压,红色LED亮蜂鸣器报警
  124.                         {
  125.                                  LED_red =0;         //红色灯示警
  126.                                  LED_yellow=1;
  127.                                  fengmingqi=0;                 //蜂鸣器示警
  128.                                  delayms(1000);
  129.                                  fengmingqi=1;
  130.                                  delayms(1000);      
  131.                         }
  132.         
  133.     }
  134. }
复制代码

python代码:
  1. V_min = 0.0  # 最小电压值
  2. V_max = 5.0  # 最大电压值
  3. hex_min = 0x00  # 最小十六进制值
  4. hex_max = 0xFF  # 最大十六进制值

  5. # 输入电压范围
  6. V_range_min = float(input("请输入电压范围的最小值(范围在{}之间):".format(V_min)))
  7. V_range_max = float(input("请输入电压范围的最大值(范围在{}之间):".format(V_max)))

  8. # 计算电压范围对应的相对位置
  9. relative_position_min = (V_range_min - V_min) / (V_max - V_min)
  10. relative_position_max = (V_range_max - V_min) / (V_max - V_min)

  11. # 计算十六进制范围
  12. hex_range_min = int(relative_position_min * (hex_max - hex_min) + hex_min)
  13. hex_range_max = int(relative_position_max * (hex_max - hex_min) + hex_min)

  14. # 分解十六进制范围的最小值和最大值为高位和低位
  15. volt_h_min = (hex_range_min >> 8) & 0xFF  # 最小值的高位
  16. volt_l_min = hex_range_min & 0xFF  # 最小值的低位
  17. volt_h_max = (hex_range_max >> 8) & 0xFF  # 最大值的高位
  18. volt_l_max = hex_range_max & 0xFF  # 最大值的低位

  19. # 输出结果
  20. print("最小电压值的十六进制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_min, volt_l_min))
  21. print("最大电压值的十六进制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_max, volt_l_max))


  22. #最后你只要把输出的结果选择volt_l的值就可以写入就可以了
复制代码


Keil代码与Proteus仿真下载: 仿真程序.7z (60.3 KB, 下载次数: 23)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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