找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3676|回復: 2
打印 上一主題 下一主題
收起左側

傳感器控制LED燈,程序看不太懂,求助

[復制鏈接]
跳轉到指定樓層
樓主
ID:194777 發(fā)表于 2017-4-29 14:48 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式


  1. #include "STC89.h"
  2. #include "intrins.h"
  3. #include "process.h"
  4. #define CycleTime_Ultrasonic 10

  5. #define TR_Ultrasonic TR0
  6. #define TH_Ultrasonic TH0
  7. #define TL_Ultrasonic TL0
  8. #define ET_Ultrasonic ET0
  9. #define TMOD_Ultrasonic TMOD

  10. sbit FrontTrig=P2^2;
  11. sbit FrontEcho=P3^2;//accord to the selected timer, timer 0-->P32  timer 1--->P33

  12. void InitDistance(void);
  13. float GetDistance(void);

  14. void StartCheckDistance(void);
  15. #define AddWr 0x90   //寫數(shù)據(jù)地址 PCF8591        bit321為地址A0 A1 A2
  16. #define AddRd 0x91   //讀數(shù)據(jù)地址 PCF8591

  17. sbit SDA_PCF8591=P2^6;
  18. sbit SCL_PCF8591=P2^7;

  19. unsigned char ReadADC(unsigned char Chl);

  20. unsigned char SysTime;
  21. unsigned char SoundAdc;
  22. unsigned int LedShowData;
  23. unsigned char NumToShow=6;
  24. unsigned int DistanceData;

  25. sbit Key0=P0^4;
  26. unsigned char OldKey0,DisMode=0;


  27. void InitTimer2(void)
  28. {
  29.     T2MOD = 0;
  30.         T2CON = 0;
  31.         RCAP2H = 0xFC;
  32.     RCAP2L = 0x17;
  33.         EA=1;                                             //總中斷打開
  34.         ET2=1;                                            //定時器T2允許中斷
  35.         TR2=1;                                            //定時器T2開始工作
  36. }

  37. void et2(void) interrupt 5 using 0
  38. {
  39.     TF2=0;
  40.         SysTime++;
  41. }

  42. bit ack;                      //應答標志位

  43. /*------------------------------------------------
  44.                     啟動總線
  45. ------------------------------------------------*/
  46. void Start_I2c()
  47. {
  48.   SDA_PCF8591=1;   //發(fā)送起始條件的數(shù)據(jù)信號
  49.   _nop_();
  50.   SCL_PCF8591=1;
  51.   _nop_();    //起始條件建立時間大于4.7us,延時
  52.   _nop_();
  53.   _nop_();
  54.   _nop_();
  55.   _nop_();   
  56.   SDA_PCF8591=0;     //發(fā)送起始信號
  57.   _nop_();    //起始條件鎖定時間大于4μ
  58.   _nop_();
  59.   _nop_();
  60.   _nop_();
  61.   _nop_();      
  62.   SCL_PCF8591=0;    //鉗住I2C總線,準備發(fā)送或接收數(shù)據(jù)
  63.   _nop_();
  64.   _nop_();
  65. }
  66. /*------------------------------------------------
  67.                     結束總線
  68. ------------------------------------------------*/
  69. void Stop_I2c()
  70. {
  71.   SDA_PCF8591=0;    //發(fā)送結束條件的數(shù)據(jù)信號
  72.   _nop_();   //發(fā)送結束條件的時鐘信號
  73.   SCL_PCF8591=1;    //結束條件建立時間大于4μ
  74.   _nop_();
  75.   _nop_();
  76.   _nop_();
  77.   _nop_();
  78.   _nop_();
  79.   SDA_PCF8591=1;    //發(fā)送I2C總線結束信號
  80.   _nop_();
  81.   _nop_();
  82.   _nop_();
  83.   _nop_();
  84. }




  85. /*----------------------------------------------------------------
  86.                  字節(jié)數(shù)據(jù)傳送函數(shù)               
  87. 函數(shù)原型: void  SendByte(unsigned char c);
  88. 功能:  將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應答,并對
  89.      此狀態(tài)位進行操作.(不應答或非應答都使ack=0 假)     
  90.      發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應答或損壞。
  91. ------------------------------------------------------------------*/
  92. void  SendByte(unsigned char c)
  93. {
  94. unsigned char BitCnt;

  95. for(BitCnt=0;BitCnt<8;BitCnt++)  //要傳送的數(shù)據(jù)長度為8位
  96.     {
  97.      if((c<<BitCnt)&0x80)SDA_PCF8591=1;   //判斷發(fā)送位
  98.        else  SDA_PCF8591=0;               
  99.      _nop_();
  100.      SCL_PCF8591=1;               //置時鐘線為高,通知被控器開始接收數(shù)據(jù)位
  101.       _nop_();
  102.       _nop_();             //保證時鐘高電平周期大于4μ
  103.       _nop_();
  104.       _nop_();
  105.       _nop_();         
  106.      SCL_PCF8591=0;
  107.     }
  108.    
  109.     _nop_();
  110.     _nop_();
  111.     SDA_PCF8591=1;               //8位發(fā)送完后釋放數(shù)據(jù)線,準備接收應答位
  112.     _nop_();
  113.     _nop_();   
  114.     SCL_PCF8591=1;
  115.     _nop_();
  116.     _nop_();
  117.     _nop_();
  118.     if(SDA_PCF8591==1)ack=0;     
  119.        else ack=1;        //判斷是否接收到應答信號
  120.     SCL_PCF8591=0;
  121.     _nop_();
  122.     _nop_();
  123. }


  124. /*----------------------------------------------------------------
  125.                  字節(jié)數(shù)據(jù)傳送函數(shù)               
  126. 函數(shù)原型: unsigned char  RcvByte();
  127. 功能:  用來接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應答信號),
  128.      發(fā)完后請用應答函數(shù)。  
  129. ------------------------------------------------------------------*/      
  130. unsigned char  RcvByte()
  131. {
  132.   unsigned char retc;
  133.   unsigned char BitCnt;
  134.   
  135.   retc=0;
  136.   SDA_PCF8591=1;             //置數(shù)據(jù)線為輸入方式
  137.   for(BitCnt=0;BitCnt<8;BitCnt++)
  138.       {
  139.         _nop_();           
  140.         SCL_PCF8591=0;       //置時鐘線為低,準備接收數(shù)據(jù)位
  141.         _nop_();
  142.         _nop_();      //時鐘低電平周期大于4.7us
  143.         _nop_();
  144.         _nop_();
  145.         _nop_();
  146.         SCL_PCF8591=1;       //置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
  147.         _nop_();
  148.         _nop_();
  149.         retc=retc<<1;
  150.         if(SDA_PCF8591==1)retc=retc+1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
  151.         _nop_();
  152.         _nop_();
  153.       }
  154.   SCL_PCF8591=0;   
  155.   _nop_();
  156.   _nop_();
  157.   return(retc);
  158. }


  159. /*----------------------------------------------------------------
  160.                      非應答子函數(shù)
  161. 原型:  void NoAck_I2c(void);

  162. ----------------------------------------------------------------*/
  163. void NoAck_I2c(void)
  164. {
  165.   
  166.   SDA_PCF8591=1;
  167.   _nop_();
  168.   _nop_();
  169.   _nop_();      
  170.   SCL_PCF8591=1;
  171.   _nop_();
  172.   _nop_();              //時鐘低電平周期大于4μ
  173.   _nop_();
  174.   _nop_();
  175.   _nop_();  
  176.   SCL_PCF8591=0;                //清時鐘線,鉗住I2C總線以便繼續(xù)接收
  177.   _nop_();
  178.   _nop_();   
  179. }

  180. /*------------------------------------------------
  181.              讀AD轉值程序
  182. 輸入?yún)?shù) Chl 表示需要轉換的通道,范圍從0-3
  183. 返回值范圍0-255
  184. ------------------------------------------------*/
  185. unsigned char ReadADC(unsigned char Chl)
  186. {
  187.    unsigned char Val;
  188.    Start_I2c();               //啟動總線
  189.    SendByte(AddWr);             //發(fā)送器件地址
  190.      if(ack==0)return(0);
  191.    SendByte(0x00|Chl);            //發(fā)送器件子地址
  192.      if(ack==0)return(0);
  193.    Start_I2c();
  194.    SendByte(AddRd);
  195.       if(ack==0)return(0);
  196.    Val=RcvByte();
  197.    NoAck_I2c();                 //發(fā)送非應位
  198.    Stop_I2c();                  //結束總線
  199.    Start_I2c();
  200.    SendByte(AddRd);
  201.       if(ack==0)return(0);
  202.    Val=RcvByte();
  203.    NoAck_I2c();                 //發(fā)送非應位
  204.    Stop_I2c();                  //結束總線
  205.   return(Val);
  206. }
  207. void InitDistance(void)                 //使用EX0口
  208. {
  209.     TMOD_Ultrasonic |= 0x09;//打開GATE0 內(nèi)部時鐘計數(shù)模式
  210.     ET_Ultrasonic=0;
  211.     FrontTrig = 0;
  212. }

  213. void Delay(void)
  214. {
  215.         unsigned i=10;
  216.         while(i--)
  217.         _nop_( );
  218. }

  219. void StartCheckDistance(void)
  220. {
  221.     FrontTrig = 1;
  222.         TH_Ultrasonic = 0;
  223.     TL_Ultrasonic = 0;
  224.     Delay();
  225.         TR_Ultrasonic=1;
  226.         FrontTrig = 0;
  227. }



  228. float GetDistance(void)//always return value ,unit:mm
  229. {               
  230.         static unsigned char DisTestStep,DisDelayTime;
  231.         unsigned int FrontTime;
  232.         static float DistanceData=0;

  233.         switch(DisTestStep)
  234.         {
  235.                 case 0:
  236.                 {
  237.                         StartCheckDistance();
  238.                         DisTestStep = 1;
  239.                         break;
  240.                 }
  241.                 case 1:
  242.                 {
  243.                         DisDelayTime++;
  244.                         if(DisDelayTime >= 30/CycleTime_Ultrasonic)
  245.                         {
  246.                                 DisDelayTime = 0;
  247.                                 DisTestStep = 2;
  248.                         }
  249.                         break;
  250.                 }
  251.                 case 2:
  252.                 {

  253.                         TR0 = 0;
  254.                         FrontTime = TH_Ultrasonic;
  255.                         FrontTime = FrontTime<<8;
  256.                         FrontTime = FrontTime+TL_Ultrasonic;
  257.                         DistanceData = FrontTime;
  258.                         DistanceData = DistanceData*0.17;
  259.                         DisTestStep = 3;

  260.                         break;
  261.                 }
  262.                 case 3:
  263.                 {
  264.                         DisDelayTime++;
  265.                         if(DisDelayTime >= 300/CycleTime_Ultrasonic)
  266.                         {
  267.                                 DisDelayTime = 0;
  268.                                 DisTestStep = 0;
  269.                         }
  270.                         break;
  271.                 }
  272.         }
  273.         return DistanceData;
  274. }




  275. main()
  276. {
  277.         InitTimer2();
  278.         //InitSci();
  279.         InitDistance();
  280.         for(;;)
  281.         {
  282.                 StartPro(0);
  283.                 SoundAdc = ReadADC(3);
  284.                 DistanceData = GetDistance();

  285.                 if((OldKey0==0)&&(Key0==1))
  286.                 {
  287.                         DisMode = ~DisMode;
  288.                 }
  289.                 OldKey0 = Key0;

  290.                 if(DisMode == 0)
  291.                 {
  292.                         P25 = 0;
  293.                         if(DistanceData < 200)
  294.                         {
  295.                                 NumToShow = 0;
  296.                         }
  297.                         else if(DistanceData > 800)
  298.                         {
  299.                                 NumToShow = 12;
  300.                         }
  301.                         else
  302.                         {
  303.                                 NumToShow = (DistanceData-200)/50;
  304.                         }
  305.                 }
  306.                 else
  307.                 {
  308.                         P25 = 1;
  309.                         if(SoundAdc < 62)
  310.                         {
  311.                                 NumToShow = 0;
  312.                         }
  313.                         else if(SoundAdc > 110)
  314.                         {
  315.                                 NumToShow = 12;
  316.                         }
  317.                         else
  318.                         {
  319.                                 NumToShow = (SoundAdc-62)>>2;
  320.                         }
  321.                 }
  322.                 LedShowData = (0x0FFF>>NumToShow);
  323.                 P36 = LedShowData>>11;
  324.                 P35 = LedShowData>>10;
  325.                 P34 = LedShowData>>9;
  326.                 P33 = LedShowData>>8;
  327.                 P10 = LedShowData>>7;
  328.                 P11 = LedShowData>>6;
  329.                 P12 = LedShowData>>5;
  330.                 P13 = LedShowData>>4;
  331.                 P14 = LedShowData>>3;
  332.                 P15 = LedShowData>>2;
  333.                 P16 = LedShowData>>1;
  334.                 P17 = LedShowData;
  335.                

  336.                 EndPro(10);
  337.         }
  338. }
復制代碼


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

使用道具 舉報

沙發(fā)
ID:474232 發(fā)表于 2019-2-1 18:27 | 只看該作者
一個簡單的ADC轉PWM控制就能把你糾結成這樣

評分

參與人數(shù) 2黑幣 +23 收起 理由
還有誰? + 8
yoxi + 15

查看全部評分

回復

使用道具 舉報

板凳
ID:469932 發(fā)表于 2019-2-3 00:34 | 只看該作者
圖片看的人眼花,為什么背景調那么刺眼

評分

參與人數(shù) 2黑幣 +47 收起 理由
struct00 + 12
jinsheng7533967 + 35

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

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

快速回復 返回頂部 返回列表