模拟路灯控制系统
``#include “STC12C5A60S2.h”
#include “oled.h”
#include “stdio.h”
#include “intrins.h”
//DS1302地址定義
#define ds1302_sec_add 0x80 //秒數(shù)據(jù)地址
#define ds1302_min_add 0x82 //分?jǐn)?shù)據(jù)地址
#define ds1302_hr_add 0x84 //時數(shù)據(jù)地址
#define ds1302_date_add 0x86 //日數(shù)據(jù)地址
#define ds1302_month_add 0x88 //月數(shù)據(jù)地址
#define ds1302_day_add 0x8a //星期數(shù)據(jù)地址
#define ds1302_year_add 0x8c //年數(shù)據(jù)地址
#define ds1302_control_add 0x8e //控制數(shù)據(jù)地址
#define ds1302_charger_add 0x90
#define ds1302_clkburst_add 0xbe
//初始時間定義
uchar time_buf[8] = {0x20,0x21,0x04,0x18,0x16,0x25,0x00,0x07};//初始時間2021年1月24日15點21分0秒星期日
uchar readtime[15];//當(dāng)前時間
uchar sec_buf=0; //秒緩存
uchar sec_flag=0; //秒標(biāo)志位
//按鍵部分
int keyscan();
uchar table[6]={0};//存儲預(yù)設(shè)開燈時間
uchar table1[6]={0};//存儲預(yù)設(shè)關(guān)燈時間
void delay10ms(void);//延時
//鍵盤掃描變量
uchar temp;
uchar keynum;
uchar i,kflag,j,flag;
uchar open_time_set();//設(shè)置開燈時間
uchar close_time_set();//設(shè)置關(guān)燈時間
void time_display();//年月日時分秒星期顯示函數(shù)
//LED工作模式
void modle_1();//模式1,光敏電阻控制燈的開與關(guān)
void modle_2();//模式2,光電開關(guān)控制
uchar time_LEDopen();//開燈
uchar time_LEDclose();//關(guān)燈
uint ADC_Get(uchar Channel);
float ADC_Value(uchar Channel);
void delay(uint a);
void ADC_Init();
void Delay_xms(uint x);
void ds1302_init(void);
void ds1302_write_byte(uchar addr, uchar d);
uchar ds1302_read_byte(uchar addr);
void ds1302_write_time(void);
void ds1302_read_time(void);
//LED、蜂鳴器I/O定義
sbit led1=P1^1;
sbit led2=P1^3;
sbit beep=P3^7;
//DS1302引腳定義
sbit RST=P2^7;
sbit IO=P2^6;
sbit SCK=P2^5;
//光電開關(guān)引腳定義
sbit guang3=P2^2;
sbit guang2=P2^1;
sbit guang1=P2^0;
int main()
{
OLED_Init(); //初始化OLED
OLED_Clear(); //OLED清屏
ADC_Init();//ADC初始化
Delay_xms(50);//等待系統(tǒng)穩(wěn)定
ds1302_init(); //DS1302初始化
Delay_xms(10);
// ds1302_write_time(); //寫入初始值
while(1)
{
time_display();
/*
// open_time_set();
// keyscan();
// OLED_ShowNum(54,0,keyscan(),2,16);//顯示ASCII字符的碼值
// OLED_ShowNum(96,6,kflag,1,16);//顯示ASCII字符的碼值
/*
OLED_ShowNum(0,6,table[0],1,16);
OLED_ShowNum(8,6,table[1],1,16);
OLED_ShowNum(16,6,table[2],1,16);
OLED_ShowNum(24,6,table[3],1,16);
OLED_ShowNum(32,6,table[4],1,16);
OLED_ShowNum(40,6,table[5],1,16);
// OLED_ShowChar(48,0,‘R’,16);//顯示ASCII字符
// OLED_ShowChar(52,0,‘M’,16);//顯示ASCII字符
*/
}
}
void modle_1()//模式1,光敏電阻控制燈的開與關(guān)
{
if(ADC_Value(0)<2)
{
led1=0;
led2=0;
}
else
{
led1=1;
led2=1;
}
}
void modle_2()//模式2,光電開關(guān)控制燈的開與關(guān)
{
if(guang10&&guang21&&guang31)
{
flag=1;
}
else if(guang11&&guang21&&guang30)
{
flag=2;
}
//從右到左
if(flag1)
{
if(guang10&&guang21&&guang31)
{
led1=0;
led2=1;
}
if(guang11&&guang20&&guang31)
{
led1=1;
led2=0;
}
if(guang11&&guang21&&guang30)
{
led1=1;
led2=1;
}
}
//從左到右
else if(flag2)
{
if(guang11&&guang21&&guang30)
{
led2=0;
led1=1;
}
if(guang11&&guang20&&guang31)
{
led2=1;
led1=0;
}
if(guang11&&guang21&&guang30)
{
led1=1;
led2=1;
}
}
}
void time_display()//年月日時分秒星期顯示函數(shù)
{
ds1302_read_time(); //讀取時間
readtime[0]=(time_buf[0]>>4); //分離出年千位
readtime[1]=(time_buf[0]&0x0F); //分離出年百位
readtime[2]=(time_buf[1]>>4); //分離出年十位
readtime[3]=(time_buf[1]&0x0F); //分離出年個位
}
uint ADC_Get(uchar Channel)
{
ADC_CONTR=0x88|Channel;
nop();
nop();
nop();
nop();
while(!(ADC_CONTR&0x10)); //等待轉(zhuǎn)換完成
ADC_CONTR&=0xe7; //關(guān)閉AD轉(zhuǎn)換,ADC_FLAG右軟件清0
return(ADC_RES*4+ADC_RESL); //返回AD轉(zhuǎn)換的10位數(shù)據(jù)(16進制)
}
//將AD轉(zhuǎn)換之轉(zhuǎn)換成10進制數(shù)
float ADC_Value(uchar Channel)
{
float AD_Value;
uchar i;
for(i=0;i<10;i++) //采樣10次取平均值
AD_Value+=ADC_Get(Channel); //轉(zhuǎn)換100次求算數(shù)平均值(提高精度)
AD_Value/=10;
AD_Value=(AD_Value5)/1024;//ADRJ=0,取10位轉(zhuǎn)換結(jié)果ADC_RES+ADC_RESL=1024Vin/Vcc
return AD_Value;
}
//延時
void delay(uint a) //延時約1ms
{
uint i;
while (–a!=0)
for(i=600;i>0;i–); //1T單片機i=600,若是12T單片機i=125
}
//AD初始化
void ADC_Init()
{
P1ASF=0x15;//ADC I/O選擇 P10、P12、P1^4;
AUXR1=0x00;//ADRJ=0 ,ADRJ=0時高8位存于ADC_RES[7…0],低二位存于ADC_RESL[1…0];ADRJ=1時高2位存于ADC_RES[1…0],低8位存于ADC_RESL[7…0]
ADC_RES=0;//10位ADC采樣結(jié)果的高8位放在ADC_RES中,第二位存放在ADC_RES_L的低二位中
ADC_RESL=0;
ADC_CONTR=0x80;//開啟ADC電源
delay(2);//必要的延時
}
uchar open_time_set()//預(yù)設(shè)開燈時間函數(shù)
{
if(kflag1)
{
table[i++]=keynum;
kflag=0;
}
if(i6)
{
i=0;
}
}
uchar close_time_set()//預(yù)設(shè)開燈時間函數(shù)
{
if(kflag1)
{
table1[j++]=keynum;
kflag=0;
}
if(j6)
{
j=0;
}
}
//按鍵掃描函數(shù)
int keyscan()
{
//掃描第一行
P0=0xfe;
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay10ms();//延時去抖
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P0;
kflag=1;
switch(temp)
{
case 0xee:
keynum=1;
break;
case 0xde:
keynum=2;
break;
case 0xbe:
keynum=3;
break;
case 0x7e:
keynum=4;
break;
}
}
while(temp!=0xf0)//等待按鍵釋放
{
temp=P0;
temp=temp&0xf0;
}
}
//第三行
P0=0xfb;
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay10ms();
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P0;
kflag=1;
switch(temp)
{
case 0xeb:
keynum=9;
break;
case 0xdb:
keynum=10;
break;
case 0xbb:
keynum=11;
break;
case 0x7b:
keynum=12;
break;
}
}
while(temp!=0xf0)//等待按鍵釋放
{
temp=P0;
temp=temp&0xf0;
}
}
//第四行
P0=0xf7;
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay10ms();
temp=P0;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P0;
kflag=1;
switch(temp)
{
case 0xe7:
keynum=13;
break;
case 0xd7:
keynum=14;
break;
case 0xb7:
keynum=15;
break;
case 0x77:
keynum=0;
break;
}
}
while(temp!=0xf0)//等待按鍵釋放
{
temp=P0;
temp=temp&0xf0;
}
}
}
//開燈
uchar time_LEDopen()
{
if((table[0]==readtime[8])&&(table[1]==readtime[9])&&(table[2]==readtime[10])&&(table[3]==readtime[11])&&(table[4]==readtime[12])&&(table[5]==readtime[13])&&(table[6]==readtime[14]))
{
led1=0;
led2=0;
}
}
//關(guān)燈
uchar time_LEDclose()
{
if((table1[0]==readtime[8])&&(table1[1]==readtime[9])&&(table1[2]==readtime[10])&&(table1[3]==readtime[11])&&(table1[4]==readtime[12])&&(table1[5]==readtime[13])&&(table1[6]==readtime[14]))
{
led1=1;
led2=1;
}
}
void delay10ms(void)
{
unsigned char a,b,c;
for(c=1;c>0;c–)
for(b=38;b>0;b–)
for(a=130;a>0;a–);
}
//延時1毫秒
void Delay_xms(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<112;j++);
}
//DS1302初始化函數(shù)
void ds1302_init(void)
{
RST=0; //RST腳置低
SCK=0; //SCK腳置低
}
//向DS1302寫入一字節(jié)數(shù)據(jù)
void ds1302_write_byte(uchar addr, uchar d)
{
uchar i;
RST=1; //啟動DS1302總線
//寫入目標(biāo)地址:addr
addr = addr & 0xFE; //最低位置零,寄存器0位為0時寫,為1時讀
for (i = 0; i < 8; i ++) {
if (addr & 0x01)
{
IO=1;
}
else
{
IO=0;
}
SCK=1; //產(chǎn)生時鐘
SCK=0;
addr = addr >> 1;
}
//寫入數(shù)據(jù):d
for (i = 0; i < 8; i ++)
{
if (d & 0x01)
{
IO=1;
}
else
{
IO=0;
}
SCK=1; //產(chǎn)生時鐘
SCK=0;
d = d >> 1;
}
RST=0; //停止DS1302總線
}
//從DS1302讀出一字節(jié)數(shù)據(jù)
uchar ds1302_read_byte(uchar addr)
{
}
//向DS302寫入時鐘數(shù)據(jù)
void ds1302_write_time(void)
{
ds1302_write_byte(ds1302_control_add,0x00); //關(guān)閉寫保護
ds1302_write_byte(ds1302_sec_add,0x80); //暫停時鐘
//ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充電(原來就屏蔽)
ds1302_write_byte(ds1302_year_add,time_buf[1]); //年
ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
ds1302_write_byte(ds1302_date_add,time_buf[3]); //日
ds1302_write_byte(ds1302_hr_add,time_buf[4]); //時
ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
ds1302_write_byte(ds1302_control_add,0x80); //打開寫保護
}
//從DS302讀出時鐘數(shù)據(jù)
void ds1302_read_time(void)
{
time_buf[1]=ds1302_read_byte(ds1302_year_add); //年
time_buf[2]=ds1302_read_byte(ds1302_month_add); //月
time_buf[3]=ds1302_read_byte(ds1302_date_add); //日
time_buf[4]=ds1302_read_byte(ds1302_hr_add); //時
time_buf[5]=ds1302_read_byte(ds1302_min_add); //分
time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒。屏蔽秒第7位,避免超出59
time_buf[7]=ds1302_read_byte(ds1302_day_add); //周
}
總結(jié)
- 上一篇: 交易学习笔记
- 下一篇: 基于Spring boot的个人理财系统