微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 灯光控制器

灯光控制器

时间:10-02 整理:3721RD 点击:
程序:

#include<reg52.h>

#include<intrins.h>  //提供系统中的一些函数,像_nop()_ 空操作函数

#include<math.h>

//shuma.h是数码管扫描驱动,定义着数码管的扫描函数

//数码管的段码0~A

unsigned char code shuma[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F ,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76 };

unsigned char code shuma1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef };//电压整数部分显示码

unsigned char code shuma2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };//电压小数部分显示码

unsigned char vol,ta,ge;

unsigned char second=0,//数码管第一位和第二位组成累计的时间,数据存在second中 ,0~99s

                      on_off=0,//,第三位是开关次数,数据存在data_3中,0~9次

                      bright=0,//第四位为亮度等级,数据存在data_4中,0~9级

                      my_bright=0x05;

                      //my_bright为程序中定义的亮度等级,当亮度小于程序中的亮度等级时就会驱动继电器

           

sbit delay_on=P3^5;//此引脚用于驱动继电器

sbit ctrl_1=P1^5;//锁存器1的使能端

sbit ctrl_2=P1^6;//锁存器2的使能端

sbit wei1=P0^0;//数码管位选1

sbit wei2=P0^1;//数码管位选2

sbit wei3=P0^2;//数码管位选3

sbit wei4=P0^3;//数码管位选4

sbit wei5=P0^4;//数码管位选5

sbit wei6=P0^5;//数码管位选6

void delay()//延时函数

{

      unsigned char i,j;

      for(i=0;i<30;i++)

           for(j=0;j<20;j++);

}

//数码管显示子程序,即数码管显示驱动

void screen(char wei,char led_data)

{

      switch(wei)

      {

           case 1:

                 P0=0x00;

                 ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=0;wei2=1;wei3=1;wei4=1;wei5=1;wei6=1;

                 ctrl_1=0;ctrl_2=0;break;

           case 2:P0=0x00;

                 ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=1;wei2=0;wei3=1;wei4=1;wei5=1;wei6=1;

                 ctrl_1=0;ctrl_2=0;break;

           case 3:P0=0x00;

                 ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=1;wei2=1;wei3=0;wei4=1;wei5=1;wei6=1;

                 ctrl_1=0;ctrl_2=0;break;

           case 4:P0=0x00;

                 ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=1;wei2=1;wei3=1;wei4=0;wei5=1;wei6=1;

                 ctrl_1=0;ctrl_2=0;break;

           case 5:P0=0x00;

               ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=1;wei2=1;wei3=1;wei4=1;wei5=0;wei6=1;

                 ctrl_1=0;ctrl_2=0;break;

        case 6:P0=0x00;

               ctrl_1=1;ctrl_2=0;

                 P0=led_data;

                 ctrl_1=0;ctrl_2=0;

                 P0=0xff;

                 ctrl_1=0;ctrl_2=1;

                 wei1=1;wei2=1;wei3=1;wei4=1;wei5=1;wei6=0;

                 ctrl_1=0;ctrl_2=0;break;

           default:;

      }

}

//数码管整体扫描函数

void disp()

{

      screen(1,shuma[second/10]); //显示时间的十位

      delay();

      screen(2,shuma[second%10]); //显示时间的各位

      delay();

      screen(3,shuma[on_off]);  //显示开关次数

      delay();

      screen(4,shuma[bright]); //显示灯光的量的等级

      delay();

      screen(5,shuma1[vol]);

      delay();

      screen(6,shuma2[ge]);

      delay();

}

//rom.h是52单片机中自带的伪EEPROM,扇区删除和擦写,在此没有存储数据可以完全忽略,

//此头文件的意义在于掉电保存数据,在此没有用上

#include"rom.h"

//int.h中定义着中断初始化函数和中断服务函数,具体见int.h

sbit ADC0809_clk=P1^3;

unsigned char num1=0,num2=0,num4=0;

//定时器0初始化函数

void time0_init()

{

      TMOD=0x21;                    //设置TO,T1定时器

      TH0=(65536-45872)/256;  //装初值晶振定时50ms数为45872

      TL0=(65536-45872)%256;

      TH1=200;  //装初值晶振定时50ms数为45872

      TL1=200;   

      EA=1;               //开总中断

      ET0=1;              //开启定时器T0中断

      ET1=1;              //开启定时器T1中断

      TR0=1;                  //启动定时器0

      TR1=1;                  //启动定时器1

      ADC0809_clk=0;

}

void T0_time()interrupt 1     //定时器T0,中断序号为1

{

      num1++;

      if(num1==2)               //如果到了2次,说明0.1秒的时间到

      {

           num1=0;               //然后把num2清零重新再计2次

           num2++;

           if(num2==10)

           {

                 num2=0;

                 if(second>=99)

                      second=0;

                 else

                      second++;  //秒信号产生

           }

      }

      TH0=(65536-45872)/256;     //重装定时器初值

      TL0=(65536-45872)%256;

      TR0=1;

}

void T1_time()interrupt 3     //定时器T0,中断序号为1

{      

      ADC0809_clk=~ADC0809_clk;  //产生0809的时钟

      

      /*if(num4<=9)  num4++;

       else

      {

           while(1)

           {

                 P0=shuma[num4];

                 P2=0x07;

           }

      } */

}

//0809.h中定义着0809 的初始化函数,和读取0809中的数据函数

unsigned char data0809=0;

sbit start=P1^0;//启动0809引脚

sbit EOC=P1^1;//转换结束标志位

sbit OE=P1^2;//0809使能端

//clk时钟在int.h中定义

void s0809_init()//0809初始化

{

      start=0;

      _nop_();

      _nop_();

      _nop_();

      OE=0;

}

void s0809()

{

      start=1;

      _nop_();

      _nop_();

      _nop_();

      start=0;

      _nop_();

      _nop_();

      _nop_();

      while(!EOC) //等待0809 中的数据,当转换完成后,EOC就会变高,就会跳出循环

      {

           disp();//等待0809数据的时候,要继续数码管扫描

       };

           OE=1;

           _nop_();

           _nop_();

           _nop_();

           data0809=P2;//从0809中读取数据

           bright=data0809/26%10;//将光度等级划分成10个等级

           vol=data0809*5/256;//电压的整数部分

           ta=data0809*5%256;

           ge=ta%10;//电压的小数部分

           OE=0;

      

}

void main()

{

      bit flag=0;

      time0_init();//定时器初始化

      s0809_init();//0809初始化

      while(1)

      {

           s0809();//检测0809的标志位,查看是否转换完毕,若转换完则读取转化数据,否则等待

           if(data0809/26%10<my_bright)//my_bright是自己定义的等级值,若光线等级大于这个值时就关灯,

                                                  //小于时就开灯

           {

                 unsigned char i;

                 i=second;

                 while(1)

                 {

                      disp();

                      if(second-i>=1)//开关灯延时,1可以换成2或者其他数据,当灯光亮度和自定义的亮度不同时

                                             //就会延时1或者其他数据之后再改变

                            break;//跳出循环

                 }

                 if(flag==0)  

                 {

                      if(on_off<9) //开关次数,当开关次数小于9次时,开关次数就加一,当大于或者等于9时就不变,始终在第三位数码管上显示9

                            on_off++;

                      second=0;//秒计数值清零

                 }

                 flag=1;delay_on=1;//启动继电器

           }

           else

           {

                 flag=0;delay_on=0;//关闭继电器

           }

      };

}


嘿嘿牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛

图很赞                                                              

上一篇:k60程序求解
下一篇:求解k60小程序问题

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top