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

QQ登錄

只需一步,快速開始

搜索
查看: 6554|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

分享一個(gè)用數(shù)碼管顯示PCF8591 AD值的小程序加Proteus仿真

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
程序中,也有一些我自己寫的注解,仿真圖的畫法不是那么標(biāo)準(zhǔn),但是不影響仿真效果,親測。
本人水平有限,如有錯(cuò)誤的地方,希望大家指出,謝謝了

有圖有真相:程序 圖


仿真 圖


單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>

  3. typedef unsigned char uint8;
  4. typedef unsigned int uint16;
  5. typedef unsigned long uint32;

  6. sbit ADDRC = P1^0;
  7. sbit ADDRB = P1^1;
  8. sbit ADDRA = P1^2;//控制138譯碼器的三個(gè)引腳

  9. sbit I2C_SDA = P2^1;
  10. sbit I2C_SCL = P2^0;//I2C通信的兩個(gè)引腳

  11. bit flag_300ms = 0;//300ms時(shí)間標(biāo)志位
  12. uint8 T0RH = 0;//定時(shí)器高8位初值
  13. uint8 T0RL = 0;//定時(shí)器低8位初值
  14. uint8 AD_value = 0;//AD值
  15. uint8 code led_char[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  16.                                                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//LED段碼

  17. void config_timer0(uint8 ms);
  18. uint8 get_ADC_vaule(uint8 chn);

  19. void main()
  20. {
  21.         config_timer0(1);//初始化通用定時(shí)器0,定時(shí)1ms
  22.         while(1)
  23.         {
  24.                 if(flag_300ms == 1)        //判斷300ms時(shí)間是否到了
  25.                 {
  26.                         flag_300ms = 0;//清除標(biāo)志位
  27.                         AD_value = get_ADC_vaule(0);//讀取通道0的AD值
  28.                 }                        
  29.         }
  30. }

  31. void I2C_delay()//I2C延時(shí)函數(shù)
  32. {
  33.         _nop_();
  34.         _nop_();
  35.         _nop_();
  36.         _nop_();
  37. }

  38. void I2C_start()//I2C起始信號(hào)
  39. {
  40.         I2C_SDA = 1;
  41.         I2C_SCL = 1;
  42.         I2C_delay();
  43.         I2C_SDA = 0;
  44.         I2C_delay();
  45.         I2C_SCL = 0;
  46.         I2C_delay();
  47. }

  48. void I2C_stop()//I2C停止信號(hào)
  49. {
  50.         I2C_SDA = 0;
  51.         I2C_SCL = 0;
  52.         I2C_delay();
  53.         I2C_SCL = 1;
  54.         I2C_delay();
  55.         I2C_SDA = 1;
  56.         I2C_delay();
  57. }

  58. bit I2C_write(uint8 dat)//I2C寫一個(gè)字節(jié)
  59. {
  60.         bit ack = 0;
  61.         uint8 mask = 0;
  62.         for(mask=0x80;mask!=0;mask>>=1)
  63.         {
  64.                 if((mask&dat) == 0)
  65.                         I2C_SDA = 0;
  66.                 else
  67.                         I2C_SDA = 1;
  68.                 I2C_delay();
  69.                 I2C_SCL = 1;
  70.                 I2C_delay();
  71.                 I2C_SCL = 0;
  72.                 I2C_delay();
  73.         }
  74.         I2C_SDA = 1;
  75.         I2C_delay();
  76.         I2C_SCL = 1;
  77.         I2C_delay();
  78.         ack = I2C_SDA;
  79.         I2C_delay();
  80.         I2C_SCL = 0;
  81.         I2C_delay();
  82.         
  83.         return (~ack);        
  84. }

  85. uint8 I2C_read_ACK()//I2C讀一個(gè)字節(jié),并發(fā)送應(yīng)答位
  86. {
  87.         uint8 dat = 0;
  88.         uint8 mask = 0;
  89.         I2C_SDA = 1;
  90.         for(mask=0x80;mask!=0;mask>>=1)
  91.         {
  92.                 if(I2C_SDA == 0)
  93.                         dat = dat & (~mask);
  94.                 else
  95.                         dat = dat | mask;
  96.                 I2C_delay();
  97.                 I2C_SCL = 1;
  98.                 I2C_delay();
  99.                 I2C_SCL = 0;
  100.                 I2C_delay();
  101.         }
  102.         I2C_SDA = 0;
  103.         I2C_delay();
  104.         I2C_SCL = 1;
  105.         I2C_delay();
  106.         I2C_SCL = 0;
  107.         I2C_delay();

  108.         return dat;
  109. }

  110. uint8 I2C_read_NACK()//I2C讀一個(gè)字節(jié),并發(fā)送非應(yīng)答位
  111. {
  112.         uint8 dat = 0;
  113.         uint8 mask = 0;
  114.         I2C_SDA = 1;
  115.         for(mask=0x80;mask!=0;mask>>=1)
  116.         {
  117.                 if(I2C_SDA == 0)
  118.                         dat = dat & (~mask);
  119.                 else
  120.                         dat = dat | mask;
  121.                 I2C_delay();
  122.                 I2C_SCL = 1;
  123.                 I2C_delay();
  124.                 I2C_SCL = 0;
  125.                 I2C_delay();
  126.         }
  127.         I2C_SDA = 1;
  128.         I2C_delay();
  129.         I2C_SCL = 1;
  130.         I2C_delay();
  131.         I2C_SCL = 0;
  132.         I2C_delay();

  133.         return dat;
  134. }

  135. uint8 get_ADC_vaule(uint8 chn)//獲取AD值
  136. {
  137.         uint8 value = 0;
  138.         I2C_start();//I2C起始信號(hào)
  139.         if(!I2C_write(0X90))//寫入PCF8591地址及讀寫選擇位為寫
  140.         {
  141.                 I2C_stop();
  142.                 return 0;
  143.         }
  144. //        I2C_write(0X40 | chn);//寫入PCF8591通道0
  145.         I2C_write(0x00 | chn);//寫入PCF8591通道0
  146.         I2C_start();//I2C起始信號(hào)
  147.         I2C_write(0x48<<1 | 0x01);
  148.         I2C_read_ACK();//提供轉(zhuǎn)換所需的時(shí)鐘信號(hào)
  149.         value = I2C_read_NACK();//讀取上一次轉(zhuǎn)換的結(jié)果
  150.         I2C_stop();//I2C結(jié)束信號(hào)

  151.         return value;
  152. }

  153. void config_timer0(uint8 ms)//配置定時(shí)器0的通用函數(shù)
  154. {
  155.         uint32 temp =0 ;
  156.         temp = 11059200/12;
  157.         temp = (temp * ms)/1000;
  158.         temp = 65536 - (temp + 12);
  159.         T0RH = (uint8)(temp >> 8);
  160.         T0RL = (uint8)temp;

  161.         TMOD = TMOD & 0XF0;
  162.         TMOD = TMOD | 0X01;
  163.         TH0 = T0RH;
  164.         TL0 = T0RL;
  165.         EA = 1;
  166.         ET0 = 1;
  167.         TR0 = 1;
  168. }

  169. void led_scan()//LED掃描函數(shù),每個(gè)1ms掃描一次
  170. {
  171.         static uint8 index = 0;

  172.         P0 = 0X00;
  173.         switch(index)
  174.         {
  175.                 case 0:ADDRC=1;ADDRB=1;ADDRA=1;P0=led_char[AD_value%10];break;
  176.                 case 1:ADDRC=1;ADDRB=1;ADDRA=0;P0=led_char[AD_value/10%10];break;
  177.                 case 2:ADDRC=1;ADDRB=0;ADDRA=1;P0=led_char[AD_value/100];break;
  178.                 default:break;
  179.         }
  180.         index++;
  181.         if(index >= 3)
  182.         {
  183.                 index = 0;
  184.         }
  185. }

  186. void interrupt_timer0() interrupt 1//定時(shí)器0的中斷函數(shù)
  187. {
  188.         static uint16 cnt = 0;

  189.         TH0 = T0RH;
  190.         TL0 = T0RL;

  191.         led_scan();
  192.         cnt++;
  193.         if(cnt >= 300)
  194.         {
  195.                 cnt = 0;
  196.                 flag_300ms = 1;
  197.         }
  198. }
復(fù)制代碼

所有資料51hei提供下載:
數(shù)碼管顯示AD值.rar (91.21 KB, 下載次數(shù): 144)

評(píng)分

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

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:585455 發(fā)表于 2020-9-14 11:48 | 只看該作者
顯示全部是零,不知哪有問題,偵錯(cuò)中。
回復(fù)

使用道具 舉報(bào)

板凳
ID:169549 發(fā)表于 2021-8-16 16:37 | 只看該作者
jemery1030 發(fā)表于 2020-9-14 11:48
顯示全部是零,不知哪有問題,偵錯(cuò)中。

可以直接仿真嗎。我的protues可能缺少文件,仿真不了。8591
回復(fù)

使用道具 舉報(bào)

地板
ID:328014 發(fā)表于 2021-8-16 21:25 | 只看該作者
hmgqljz 發(fā)表于 2021-8-16 16:37
可以直接仿真嗎。我的protues可能缺少文件,仿真不了。8591

要用Proteus7.5版本打開才行 你看我的效果

51hei.png (28.08 KB, 下載次數(shù): 46)

51hei.png
回復(fù)

使用道具 舉報(bào)

5#
ID:984325 發(fā)表于 2021-12-3 14:05 | 只看該作者
在哪里改寫真是數(shù)值呀  X/256*5 我不知道在哪里加
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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