找回密码
 立即注册

QQ登录

只需一步,快速开始

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

传感器控制LED灯,程序看不太懂,求助

[复制链接]
跳转到指定楼层
楼主


  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   //写数据地址 PCF8591        bit321为地址A0 A1 A2
  16. #define AddRd 0x91   //读数据地址 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;   //发送起始条件的数据信号
  49.   _nop_();
  50.   SCL_PCF8591=1;
  51.   _nop_();    //起始条件建立时间大于4.7us,延时
  52.   _nop_();
  53.   _nop_();
  54.   _nop_();
  55.   _nop_();   
  56.   SDA_PCF8591=0;     //发送起始信号
  57.   _nop_();    //起始条件锁定时间大于4μ
  58.   _nop_();
  59.   _nop_();
  60.   _nop_();
  61.   _nop_();      
  62.   SCL_PCF8591=0;    //钳住I2C总线,准备发送或接收数据
  63.   _nop_();
  64.   _nop_();
  65. }
  66. /*------------------------------------------------
  67.                     结束总线
  68. ------------------------------------------------*/
  69. void Stop_I2c()
  70. {
  71.   SDA_PCF8591=0;    //发送结束条件的数据信号
  72.   _nop_();   //发送结束条件的时钟信号
  73.   SCL_PCF8591=1;    //结束条件建立时间大于4μ
  74.   _nop_();
  75.   _nop_();
  76.   _nop_();
  77.   _nop_();
  78.   _nop_();
  79.   SDA_PCF8591=1;    //发送I2C总线结束信号
  80.   _nop_();
  81.   _nop_();
  82.   _nop_();
  83.   _nop_();
  84. }




  85. /*----------------------------------------------------------------
  86.                  字节数据传送函数               
  87. 函数原型: void  SendByte(unsigned char c);
  88. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  89.      此状态位进行操作.(不应答或非应答都使ack=0 假)     
  90.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  91. ------------------------------------------------------------------*/
  92. void  SendByte(unsigned char c)
  93. {
  94. unsigned char BitCnt;

  95. for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位
  96.     {
  97.      if((c<<BitCnt)&0x80)SDA_PCF8591=1;   //判断发送位
  98.        else  SDA_PCF8591=0;               
  99.      _nop_();
  100.      SCL_PCF8591=1;               //置时钟线为高,通知被控器开始接收数据位
  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位发送完后释放数据线,准备接收应答位
  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.                  字节数据传送函数               
  126. 函数原型: unsigned char  RcvByte();
  127. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  128.      发完后请用应答函数。  
  129. ------------------------------------------------------------------*/      
  130. unsigned char  RcvByte()
  131. {
  132.   unsigned char retc;
  133.   unsigned char BitCnt;
  134.   
  135.   retc=0;
  136.   SDA_PCF8591=1;             //置数据线为输入方式
  137.   for(BitCnt=0;BitCnt<8;BitCnt++)
  138.       {
  139.         _nop_();           
  140.         SCL_PCF8591=0;       //置时钟线为低,准备接收数据位
  141.         _nop_();
  142.         _nop_();      //时钟低电平周期大于4.7us
  143.         _nop_();
  144.         _nop_();
  145.         _nop_();
  146.         SCL_PCF8591=1;       //置时钟线为高使数据线上数据有效
  147.         _nop_();
  148.         _nop_();
  149.         retc=retc<<1;
  150.         if(SDA_PCF8591==1)retc=retc+1; //读数据位,接收的数据位放入retc中
  151.         _nop_();
  152.         _nop_();
  153.       }
  154.   SCL_PCF8591=0;   
  155.   _nop_();
  156.   _nop_();
  157.   return(retc);
  158. }


  159. /*----------------------------------------------------------------
  160.                      非应答子函数
  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总线以便继续接收
  177.   _nop_();
  178.   _nop_();   
  179. }

  180. /*------------------------------------------------
  181.              读AD转值程序
  182. 输入参数 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);             //发送器件地址
  190.      if(ack==0)return(0);
  191.    SendByte(0x00|Chl);            //发送器件子地址
  192.      if(ack==0)return(0);
  193.    Start_I2c();
  194.    SendByte(AddRd);
  195.       if(ack==0)return(0);
  196.    Val=RcvByte();
  197.    NoAck_I2c();                 //发送非应位
  198.    Stop_I2c();                  //结束总线
  199.    Start_I2c();
  200.    SendByte(AddRd);
  201.       if(ack==0)return(0);
  202.    Val=RcvByte();
  203.    NoAck_I2c();                 //发送非应位
  204.    Stop_I2c();                  //结束总线
  205.   return(Val);
  206. }
  207. void InitDistance(void)                 //使用EX0口
  208. {
  209.     TMOD_Ultrasonic |= 0x09;//打开GATE0 内部时钟计数模式
  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空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:474232 发表于 2019-2-1 18:27 | 只看该作者
一个简单的ADC转PWM控制就能把你纠结成这样

评分

参与人数 2黑币 +23 收起 理由
还有谁? + 8
yoxi + 15

查看全部评分

回复

使用道具 举报

板凳
ID:469932 发表于 2019-2-3 00:34 | 只看该作者
图片看的人眼花,为什么背景调那么刺眼

评分

参与人数 2黑币 +47 收起 理由
struct00 + 12
jinsheng7533967 + 35

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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