找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机智能路灯控制系统仿真及源程序

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

单片机智能路灯控制系统仿真工程文件及程序下载:
智能路灯控制系统程序 仿真.rar (185.5 KB, 下载次数: 232)


如果还有不完善的地方,希望大家一起改进

源程序:
  1. #include<reg52.h>    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
  3. #define AddWr 0x90   //写数据地址
  4. #define AddRd 0x91   //读数据地址
  5. #define  _Nop()  _nop_()  //定义空指令                        

  6. sbit IR=P3^2;  //红外接口标志
  7. sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
  8. sbit LATCH2=P2^3;//                 位锁存
  9. sbit SDA=P2^1;
  10. sbit SCL=P2^0;

  11. bit irpro_ok,irok;
  12. bit ack;                      //应答标志位
  13. extern bit ack;                 //外部点应答

  14. unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
  15. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
  16. unsigned char  irtime;//红外用全局变量
  17. unsigned char IRcord[4];
  18. unsigned char irdata[33];
  19. unsigned char TempData[8]; //存储显示值的全局变量
  20. unsigned char  RcvByte();
  21. unsigned char ReadADC(unsigned char Chl);
  22. unsigned char kkk;
  23. long num;

  24. void Ir_work(void);
  25. void Ircordpro(void);
  26. void delay(unsigned int t); //函数声明
  27. void Display();
  28. void asd(unsigned char t);
  29. void shaomiao(void);
  30. void Start_I2c();
  31. void Stop_I2c();
  32. void  SendByte(unsigned char c);
  33. void NoAck_I2c(void);
  34. void _nop_(void);
  35. void guang(void);
  36. void zhixing(void);
  37. void mjian(void);
  38. void mjia(void);
  39. void hjian(void);
  40. void hjia(void);
  41. void jieshu(void);
  42. void kaiguan(void);

  43. void kaiguan()
  44. {  kkk++;
  45.         while(kkk==2)
  46.         kkk=0;
  47. }

  48. void jieshu()
  49. {        P1=0xff;
  50.         DataPort=0;   //清空数据,防止有交替重影
  51.     LATCH1=1;     //段锁存
  52.     LATCH1=0;
  53.         kkk++;
  54.         if(kkk==2)
  55.         {kkk=0;}
  56. }

  57. void mjian()
  58. {        num=num-60;
  59.         if(num<=0)
  60.         {num=86400+num;}
  61.         zhixing();
  62. }

  63. void mjia()
  64. {        num=num+60;
  65.         if(num>=86400)
  66.         {num=num-86400;}
  67.         zhixing();
  68. }

  69. void hjian()
  70. {        num=num-3600;
  71.         if(num<=0)
  72.         {num=86400+num;}
  73.         zhixing();
  74. }
  75. void hjia()
  76. {        num=num+3600;
  77.         if(num>=86400)
  78.         {num=num-86400;}
  79.         zhixing();
  80. }
  81. void shaomiao(void)
  82. { if(irok)                        //如果接收好了进行红外处理
  83.           {   
  84.            Ircordpro();
  85.            irok=0;
  86.             if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
  87.           {
  88.            Ir_work();
  89.             }
  90.           }
  91. }

  92. void asd(unsigned char t)
  93. {
  94. num=t*3600 ;
  95. zhixing();
  96. }

  97. void zhixing()
  98. {
  99. unsigned char i;
  100.    while(num>0)
  101.    {for(i=0;i<80;i++)
  102.            {
  103.            TempData[0]=dofly_DuanMa[num/36000];
  104.            TempData[1]=dofly_DuanMa[(num/3600)%10];
  105.            TempData[2]=0x40;
  106.            TempData[3]=dofly_DuanMa[(num%3600)/600];
  107.            TempData[4]=dofly_DuanMa[(num%600)/60];
  108.            TempData[5]=0x40;
  109.            TempData[6]=dofly_DuanMa[(num%60)/10];
  110.            TempData[7]=dofly_DuanMa[(num%60)%10];
  111.            Display();
  112.            }
  113.            shaomiao();
  114.            if(kkk==0)
  115.            {guang();}
  116.            num--;
  117.            }
  118.                 jieshu();      
  119.       }

  120. void Delay(unsigned int t)
  121. {
  122. while(--t);
  123. }
  124. void Display()
  125. {
  126.       unsigned char i;          
  127.           for(i=0;i<8;i++)
  128.            {
  129.            DataPort=0;   //清空数据,防止有交替重影
  130.        LATCH1=1;     //段锁存
  131.        LATCH1=0;

  132.        DataPort=dofly_WeiMa[i]; //取位码
  133.        LATCH2=1;     //位锁存
  134.        LATCH2=0;

  135.        DataPort=TempData[i]; //取显示数据,段码
  136.        LATCH1=1;     //段锁存
  137.        LATCH1=0;
  138.       
  139.            Delay(80); // 扫描间隙延时,时间太长会闪烁,太短会造成重影

  140.        }
  141.            DataPort=0;   //清空数据,防止有交替重影
  142.        LATCH1=1;     //段锁存
  143.        LATCH1=0;

  144. }

  145. void tim0_isr (void) interrupt 1 using 1
  146. {
  147.   irtime++;  //用于计数2个下降沿之间的时间
  148. }

  149. void EX0_ISR (void) interrupt 0 //外部中断0服务函数
  150. {
  151.   static unsigned char  i;             //接收红外信号处理
  152.   static bit startflag;                //是否开始处理标志位

  153. if(startflag)                        
  154.    {
  155.     if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
  156.                         i=0;
  157.                     irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
  158.                     irtime=0;
  159.                     i++;
  160.                             if(i==33)
  161.                               {
  162.                                    irok=1;
  163.                                  i=0;
  164.                                   }
  165.           }
  166.            else
  167.                 {
  168.                 irtime=0;
  169.                 startflag=1;
  170.                 }

  171. }

  172. void TIM0init(void)//定时器0初始化
  173. {

  174.   TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  175.   TH0=0x00; //重载值
  176.   TL0=0x00; //初始化值
  177.   ET0=1;    //开中断
  178.   TR0=1;   
  179. }
  180. void EX0init(void)
  181. {
  182. IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  183. EX0 = 1;   //使能外部中断
  184. EA = 1;    //开总中断
  185. }
  186. void Ir_work(void)//红外键值散转程序
  187. {
  188.        switch(IRcord[2])//判断第三个数码值
  189.                  {
  190.                          case 0x0c:asd(1);break;//1
  191.                          case 0x18:asd(2);break;//2
  192.                          case 0x5e:asd(3);break;//3
  193.                          case 0x08:asd(4);break;//4
  194.                          case 0x1c:asd(5);break;//5
  195.                          case 0x5a:asd(6);break;//6
  196.                          case 0x42:asd(7);break;//7
  197.                          case 0x52:asd(8);break;//8
  198.                          case 0x4a:asd(9);break;//9
  199.                          case 0x07:mjian();break;//9
  200.                          case 0x15:mjia();break;//9
  201.                          case 0x44:hjian();break;//9
  202.                          case 0x40:hjia();break;//9
  203.                          case 0x43:num=0;break;//9
  204.                          case 0x09:kaiguan();break;//9
  205.                          case 0x16:P1=0xff;;break;//9
  206.              default:break;
  207.                          }

  208.                   irpro_ok=0;//处理完成标志

  209.   }
  210. void Ircordpro(void)//红外码值处理函数
  211. {
  212.   unsigned char i, j, k;
  213.   unsigned char cord,value;

  214.   k=1;
  215.   for(i=0;i<4;i++)      //处理4个字节
  216.      {
  217.       for(j=1;j<=8;j++) //处理1个字节8位
  218.          {
  219.           cord=irdata[k];
  220.           if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
  221.              value|=0x80;
  222.           if(j<8)
  223.                     {
  224.                          value>>=1;
  225.                         }
  226.            k++;
  227.          }
  228.      IRcord[i]=value;
  229.      value=0;     
  230.      }
  231.          irpro_ok=1;//处理完毕标志位置1
  232. }

  233. unsigned char ReadADC(unsigned char Chl)
  234. {
  235.    unsigned char Val;
  236.    Start_I2c();               //启动总线
  237.    SendByte(AddWr);             //发送器件地址
  238.      if(ack==0)return(0);
  239.    SendByte(0x40|Chl);            //发送器件子地址
  240.      if(ack==0)return(0);
  241.    Start_I2c();
  242.    SendByte(AddWr+1);
  243.       if(ack==0)return(0);
  244.    Val=RcvByte();
  245.    NoAck_I2c();                 //发送非应位
  246.    Stop_I2c();                  //结束总线
  247.   return(Val);
  248. }
  249. void Start_I2c()
  250. {
  251.   SDA=1;   //发送起始条件的数据信号
  252.   _Nop();
  253.   SCL=1;
  254.   _Nop();    //起始条件建立时间大于4.7us,延时
  255.   _Nop();
  256.   _Nop();
  257.   _Nop();
  258.   _Nop();   
  259.   SDA=0;     //发送起始信号
  260.   _Nop();    //起始条件锁定时间大于4μ
  261.   _Nop();
  262.   _Nop();
  263.   _Nop();
  264.   _Nop();      
  265.   SCL=0;    //钳住I2C总线,准备发送或接收数据
  266.   _Nop();
  267.   _Nop();
  268. }
  269. void Stop_I2c()
  270. {
  271.   SDA=0;    //发送结束条件的数据信号
  272.   _Nop();   //发送结束条件的时钟信号
  273.   SCL=1;    //结束条件建立时间大于4μ
  274.   _Nop();
  275.   _Nop();
  276.   _Nop();
  277.   _Nop();
  278.   _Nop();
  279.   SDA=1;    //发送I2C总线结束信号
  280.   _Nop();
  281.   _Nop();
  282.   _Nop();
  283.   _Nop();
  284. }




  285. void  SendByte(unsigned char c)
  286. {
  287. unsigned char BitCnt;

  288. for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位
  289.     {
  290.      if((c<<BitCnt)&0x80)SDA=1;   //判断发送位
  291.        else  SDA=0;               
  292.      _Nop();
  293.      SCL=1;               //置时钟线为高,通知被控器开始接收数据位
  294.       _Nop();
  295.       _Nop();             //保证时钟高电平周期大于4μ
  296.       _Nop();
  297.       _Nop();
  298.       _Nop();         
  299.      SCL=0;
  300.     }
  301.    
  302.     _Nop();
  303.     _Nop();
  304.     SDA=1;               //8位发送完后释放数据线,准备接收应答位
  305.     _Nop();
  306.     _Nop();   
  307.     SCL=1;
  308.     _Nop();
  309.     _Nop();
  310.     _Nop();
  311.     if(SDA==1)ack=0;     
  312.        else ack=1;        //判断是否接收到应答信号
  313.     SCL=0;
  314.     _Nop();
  315.     _Nop();
  316. }


  317. unsigned char  RcvByte()
  318. {
  319.   unsigned char retc;
  320.   unsigned char BitCnt;
  321.   
  322.   retc=0;
  323.   SDA=1;             //置数据线为输入方式
  324.   for(BitCnt=0;BitCnt<8;BitCnt++)
  325.       {
  326.         _Nop();           
  327.         SCL=0;       //置时钟线为低,准备接收数据位
  328.         _Nop();
  329.         _Nop();      //时钟低电平周期大于4.7us
  330.         _Nop();
  331.         _Nop();
  332.         _Nop();
  333.         SCL=1;       //置时钟线为高使数据线上数据有效
  334.         _Nop();
  335.         _Nop();
  336.         retc=retc<<1;
  337.         if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
  338.         _Nop();
  339.         _Nop();
  340.       }
  341.   SCL=0;   
  342.   _Nop();
  343.   _Nop();
  344.   return(retc);
  345. }



  346. void NoAck_I2c(void)
  347. {
  348.   
  349.   SDA=1;
  350.   _Nop();
  351.   _Nop();
  352.   _Nop();      
  353.   SCL=1;
  354.   _Nop();
  355.   _Nop();              //时钟低电平周期大于4μ
  356.   _Nop();
  357.   _Nop();
  358.   _Nop();  
  359.   SCL=0;                //清时钟线,钳住I2C总线以便继续接收
  360.   _Nop();
  361.   _Nop();   
  362. }

  363. void guang()
  364. {
  365. unsigned char num1=0;         //主循环
  366.   {
  367. num1=255-ReadADC(0);//值取差值,用于显示光强越小,数值越小
  368. if(num1 >=70)
  369. {P1=0xff;}
  370. else if(num1>=60)
  371. {P1=0xfe;}
  372. else if(num1>=50)
  373. {P1=0xfc;}
  374. else if(num1>=40)
  375. {P1=0xf8;}
  376. else if(num1>=30)
  377. {P1=0xf0;}
  378. else if(num1>=20)
  379. {P1=0xe0;}
  380. else if(num1>=10)
  381. {P1=0xc0;}
  382. else if(num1>=5)
  383. {P1=0x80;}
  384. else{P1=0x00;}         
  385.   }
  386. }
  387.        
  388.                        
  389. void main(void)
  390. {
  391. EX0init(); //初始化外部中断
  392. TIM0init();//初始化定时器

  393. while(1)//主循环
  394.    {
  395.     if(kkk==0)
  396.            {guang();}
  397.     if(irok)                        //如果接收好了进行红外处理
  398.           {   
  399.            Ircordpro();
  400.            irok=0;
  401.           }

  402.     if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
  403.           {
  404.            Ir_work();
  405.             }
  406.    }
  407. }
复制代码




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

使用道具 举报

沙发
ID:276554 发表于 2018-1-16 14:19 | 只看该作者
厉害了
回复

使用道具 举报

板凳
ID:276655 发表于 2018-1-16 17:03 | 只看该作者
学习了,厉害
回复

使用道具 举报

地板
ID:277230 发表于 2018-1-18 08:56 来自手机 | 只看该作者
这个灯是通过时间来控制开关的吗?还是通过光感
回复

使用道具 举报

5#
ID:247623 发表于 2018-5-2 12:50 | 只看该作者
楼主,有没有相关原理说明
回复

使用道具 举报

6#
ID:445343 发表于 2018-12-13 09:38 | 只看该作者
有报告吗?
回复

使用道具 举报

7#
ID:467951 发表于 2019-1-14 15:11 | 只看该作者
厉害了老哥
回复

使用道具 举报

8#
ID:467951 发表于 2019-1-14 15:14 | 只看该作者
有原理或者实现的功能介绍吗?
回复

使用道具 举报

9#
ID:473853 发表于 2019-1-29 12:25 | 只看该作者
有具体的功能介绍吗?我新手,还不知道怎么控制等多个单片机一起工作
回复

使用道具 举报

10#
ID:519430 发表于 2019-4-23 11:47 | 只看该作者
楼主厉害
回复

使用道具 举报

11#
ID:519430 发表于 2019-4-23 11:47 | 只看该作者
牛逼牛逼
回复

使用道具 举报

12#
ID:521382 发表于 2019-4-25 15:42 | 只看该作者
想问问都实现了什么功能?
回复

使用道具 举报

13#
ID:650526 发表于 2019-11-28 18:51 | 只看该作者
作者写的特别好
回复

使用道具 举报

14#
ID:650526 发表于 2019-11-29 07:25 | 只看该作者
为社么图下载不了?
回复

使用道具 举报

15#
ID:652278 发表于 2019-11-29 12:03 | 只看该作者
不错的资源
回复

使用道具 举报

16#
ID:838995 发表于 2020-11-5 10:59 | 只看该作者
请问那个示波器怎么调波形
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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