找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2430|回復(fù): 0
收起左側(cè)

單片機(jī)控制實(shí)現(xiàn)ADC TLC549一路模擬電壓采集程序Proteus仿真

[復(fù)制鏈接]
ID:1086975 發(fā)表于 2023-7-8 20:57 | 顯示全部樓層 |閱讀模式
使用proteus進(jìn)行仿真:運(yùn)用單片機(jī)(AT89C52、STM32、MSP430等)控制實(shí)現(xiàn)一路模擬電壓采集(ADC)
需實(shí)現(xiàn)以下功能:
1、電壓測(cè)量范圍0~5V
2、設(shè)置電壓上限4.5V,超過上限電壓紅色LED燈警示、蜂鳴器警示1S;
3、設(shè)置電壓下限0.5V,低于下限電壓黃色LED燈警示、蜂鳴器警示1S;
4、顯示實(shí)時(shí)測(cè)量電壓值、上下限電壓值,將采集到的電壓數(shù)據(jù)顯示在LCD1602液晶屏的第一行中間位置,上下限電壓值顯示在LCD1602液晶屏的第二行位置;
5、將學(xué)號(hào)后兩位顯示在液晶屏的右下角;
6、AD芯片選型:ADC0804,TLC549等。
在附件里還有一個(gè)可以自己計(jì)算可調(diào)的上下限電壓的python代碼。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif 1.png
單片機(jī)源程序如下:
  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報(bào)警引腳定義
  6. sbit LED_yellow = P1^7;    // 黃色LED報(bào)警引腳定義
  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時(shí)鐘引腳定義
  11. sbit TLC549_CS = P2^4;     // TLC549片選引腳定義
  12. sbit TLC549_DO = P2^5;     // TLC549數(shù)據(jù)引腳定義

  13. uchar volt_h =  0xBF, volt_l = 0x68;   // 設(shè)置電壓上下限 4.5V 0.5V
  14. unsigned char s1[] = "21";             // 顯示學(xué)號(hào)字符串
  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++);   // 延時(shí)函數(shù),以毫秒為單位
  21. }

  22. void delayus(uchar us)
  23. {
  24.     while (us--);                    // 延時(shí)函數(shù),以微秒為單位
  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;             // 下降沿執(zhí)行
  33.     delayms(1);
  34. }

  35. void w_dat(uchar dat)
  36. {
  37.     RS = 1;            // RS=1表示選擇數(shù)據(jù)寄存器
  38.     RW = 0;
  39.     E = 1;
  40.     P0 = dat;          // 數(shù)據(jù)從P0口送出
  41.     E = 0;             // 下降沿執(zhí)行
  42.     delayms(1);
  43. }

  44. void lcd_ini(void)
  45. {
  46.     delayms(10);
  47.     w_com(0x38);       // 功能設(shè)置:8位口2行
  48.     delayms(10);
  49.     w_com(0x0C);       // 顯示設(shè)置:開顯示,關(guān)光標(biāo),無閃爍
  50.     delayms(10);
  51.     w_com(0x06);       // 輸入模式:右移一格,地址加1
  52.     delayms(10);
  53.     w_com(0x01);       // 清顯示
  54.     delayms(10);
  55.     w_com(0x38);       // 功能設(shè)置: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; // 個(gè)位數(shù)和小數(shù)點(diǎn)后兩位數(shù)的變量
  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列顯示學(xué)號(hào)
  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;  // 基準(zhǔn)電壓5V轉(zhuǎn)換為電壓值
  95.         
  96.         digit1 = d %1000 / 100;     // 計(jì)算個(gè)位數(shù)
  97.         digit2 = d %100 / 10;       // 計(jì)算小數(shù)點(diǎn)后第一位
  98.         digit3 = d %10;             // 計(jì)算小數(shù)點(diǎn)后第二位


  99.         w_com(0x84);
  100.         w_dat(digit1 + 0x30);      // 顯示電壓值個(gè)位
  101.         w_dat('.');                 // 顯示小數(shù)點(diǎn)
  102.         w_dat(digit2 + 0x30); // 顯示電壓值小數(shù)點(diǎn)后第一位
  103.         w_dat(digit3 + 0x30);       // 顯示電壓值小數(shù)點(diǎn)后第二位
  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亮蜂鳴器報(bào)警
  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. }
復(fù)制代碼

python代碼:
  1. V_min = 0.0  # 最小電壓值
  2. V_max = 5.0  # 最大電壓值
  3. hex_min = 0x00  # 最小十六進(jìn)制值
  4. hex_max = 0xFF  # 最大十六進(jìn)制值

  5. # 輸入電壓范圍
  6. V_range_min = float(input("請(qǐng)輸入電壓范圍的最小值(范圍在{}之間):".format(V_min)))
  7. V_range_max = float(input("請(qǐng)輸入電壓范圍的最大值(范圍在{}之間):".format(V_max)))

  8. # 計(jì)算電壓范圍對(duì)應(yīng)的相對(duì)位置
  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. # 計(jì)算十六進(jìn)制范圍
  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. # 分解十六進(jìn)制范圍的最小值和最大值為高位和低位
  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. # 輸出結(jié)果
  20. print("最小電壓值的十六進(jìn)制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_min, volt_l_min))
  21. print("最大電壓值的十六進(jìn)制表示:volt_h = 0x{:02X}, volt_l = 0x{:02X}".format(volt_h_max, volt_l_max))


  22. #最后你只要把輸出的結(jié)果選擇volt_l的值就可以寫入就可以了
復(fù)制代碼


Keil代碼與Proteus仿真下載: 仿真程序.7z (60.3 KB, 下載次數(shù): 23)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表