一直想做个多路实时控制器,实现自动控制。网上找了几个实例不满意,还是自己攒一个与网友分享。
/*********************************************************************************/
//项目名称: 智能实时八路继电器控制系统
//单片机 :STC89C52RC
//
//
/**********************************头文件*****************************************/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
/**********************************宏定义*****************************************/
#define INT8U unsigned char
#define INT16U unsigned int
/*****************************DS1302端口引脚定义**********************************/
sbit SCLK = P3^5; //控制数据时钟
sbit IO = P3^6; //数据口
sbit RST = P3^7; //使能端、复位端
/*****************************写时分秒地址定义************************************/
//INT8U DATA[]={}; //初始化使用
#define write_nian 0x8A
#define write_yue 0x88
#define write_ri 0x86
#define write_shi 0x84
#define write_fen 0x82
#define write_miao 0x80
/*****************************读时分秒地址定义************************************/
#define read_shi 0x85
#define read_fen 0x83
#define read_miao 0x81
//bit miao_flag=0;
bit flag;
INT8U miao_num;
//INT8U Dmiao;
INT8U shi,fen,miao; //读出数据存储变量
/*****************************继电器端口引脚定义**********************************/
sbit COM1 = P0^0; //第一路继电器控制
sbit COM2 = P0^1; //第二路继电器控制
sbit COM3 = P0^2; //第三路继电器控制
sbit COM4 = P0^3; //第四路继电器控制
sbit COM5 = P0^4; //第五路继电器控制
sbit COM6 = P0^5; //第六路继电器控制
sbit COM7 = P0^6; //第七路继电器控制
sbit COM8 = P0^7; //第八路继电器控制
INT8U ON_OFF_number = 0, COM_number = 0, MODE_number = 0;
INT8U SMG_display = 0;
INT8U SET_COM1, SET_COM2, SET_COM3, SET_COM4, SET_COM5, SET_COM6, SET_COM7, SET_COM8;
/*************************** 8路继电器开关时间数列********************************/
INT8U JDQ_ON_OFF[10][4]=
{
0, 0, 0, 0, 0,
9, 15, 9, 15,
9, 17, 9, 50,
9, 16, 9, 26,
9, 18, 9, 45,
9, 19, 9, 39,
9, 21, 9, 40,
9, 26, 9, 48,
9, 20, 9, 30,
0, 0, 0
};
/******************************按键端口引脚定义***********************************/
sbit KEY1 = P1^0; //设置继电器通道1-8
sbit KEY2 = P1^1; //设置定时功能
sbit KEY3 = P1^2; //小时加
sbit KEY4 = P1^3; //分钟加
sbit KEY5 = P1^4; //时钟设置
sbit KEY6 = P1^5; //时钟加
INT8U KEY_number=0;
INT8U SHI_shi, SHI_ge, FEN_shi, FEN_ge;
INT8U on_shi, on_fen, off_shi, off_fen;
INT8U JDQ_shi, JDQ_fen, JDQ_miao;
/*****************************功能LED端口引脚定义*********************************/
sbit GREEN_LED = P1^6; //黄灯亮设置继电器打开时间
sbit YELLOW_LED = P1^7; //绿灯亮设置继电器关闭时间
/*****************************蜂鸣器端口引脚定义**********************************/
sbit BUZZER = P3^4;
/***************************数码管引脚/真值表定义*********************************/
#define DUAN P2 //段选
sbit SEC = P2^0; //
sbit WE_1 = P3^0; //千位选
sbit WE_2 = P3^1; //百位选
sbit WE_3 = P3^2; //十位选
sbit WE_4 = P3^3; //个位选
INT8U code SMG_array[]=
{
0x03, 0x9F, 0x25, 0x0D, 0x99, 0x49, 0x41, 0x1F, 0x01, 0x09 //自定义共阳码
};
/*****************************毫秒级延时函数**************************************/
void delay_ms(INT16U ms)
{
INT16U i, j;
for(i=0; i<ms; i++)
for(j=0; j<110; j++);
}
/*******************************蜂鸣器函数****************************************/
void Buzzer(INT16U Number,INT8U Time) //可以选择鸣响次数和音频
{
INT8U h,j;
INT16U i ;
for (h = 0; h < Number; h ++)
{
for (i = 0; i < Time; i ++)
{
BUZZER = ~BUZZER; //BUZZER取反
for (j = 0 ; j < 100 ; j ++); //需要产生方波,调节音频
}
delay_ms(100); //间隔时间
}
BUZZER = 1; //注意PNP=0;NPN=1关闭蜂鸣器,否则三极管电流会很大。
}
/***************************定时中断0初始化函数***********************************/
void TIMER0_init(void) //定时50ms一个中断
{
TMOD = 0x01;
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
IE = 0x82;
TR0 = 1;
}
/******************************DS1302读函数***************************************/
INT8U READ_1302(INT8U add)
{
INT8U i,date;
RST=0; //禁止读写数据
for(i=0;i<8;i++)
{
RST=1;
SCLK=0;
IO=add&0x01;
add>>=1;
SCLK=1;
}
for(i=0;i<8;i++)
{
if(IO)
date=date|0x80;
else
date=date|0x00;
SCLK=1;
date>>=1;
SCLK=0;
}
RST=0;
date=date/16*10+date%16;//进制转换 16转10进制
IO=0; //数据读完后,IO口必须为0,不然小时一直显示85
return date;
}
/******************************DS1302写函数***************************************/
void write_1302(INT8U add, INT8U dat)
{
INT8U i;
RST=0; //禁止读写数据
SCLK=0;
for(i=0;i<8;i++) //写地址
{
RST=1; //允许读写数据
SCLK=0;
IO=add&0x01;
add>>=1;
SCLK=1;
}
for(i=0;i<8;i++) //写数据
{
RST=1; //允许读写数据
SCLK=0;
IO=dat&0x01;
dat>>=1;
SCLK=1;
}
RST=0;
}
/****************************DS1302初始化函数*************************************/
/*void DS1302_init(void) //设置时间用一次即可
{
flag=READ_1302(0x81);
if(flag&0x80)
write_1302(0x8e,0x00); //保护取消,可以进行读写操作
write_1302(write_miao,0x56);
write_1302(write_fen,0x49);
write_1302(write_shi,0x14);
write_1302(0x90,0xa5);
write_1302(0x8e,0x80); //保护启动,不能进行读写操作
}
/*****************************数码管显示函数**************************************/
void DISPLAY_time(INT8U shi, INT8U fen)
{
WE_1 = SMG_display;
DUAN = SMG_array[SHI_shi=shi/10];
delay_ms(5);
WE_1 = 1;
WE_2 = SMG_display;
DUAN = SMG_array[SHI_ge=shi%10];
delay_ms(5);
WE_2 = 1;
WE_3 = SMG_display;
DUAN = SMG_array[FEN_shi=fen/10];
delay_ms(5);
WE_3 = 1;
WE_4 = SMG_display;
DUAN = SMG_array[FEN_ge=fen%10];
delay_ms(5);
WE_4 = 1;
}
/***************************继电器控制显示函数************************************/
void DISPLAY_set(INT8U set_shi, INT8U set_fen)
{
WE_1 = 0;
DUAN = SMG_array[set_shi/10];
delay_ms(10);
WE_1 = 1;
WE_2 = 0;
DUAN = SMG_array[set_shi%10];
delay_ms(10);
WE_2 = 1;
WE_3 = 0;
DUAN = SMG_array[set_fen/10];
delay_ms(10);
WE_3 = 1;
WE_4 = 0;
DUAN = SMG_array[set_fen%10];
delay_ms(10);
WE_4 = 1;
}
/******************************读取时间函数***************************************/
void READ_time(void)
{
fen = READ_1302(read_fen);
shi = READ_1302(read_shi);
// if(shi<shi)
// Buzzer(2, 100); //整点报时
DISPLAY_time(shi, fen);
}
/******************************按键扫描函数***************************************/
void KEYSCAN(void)
{
if(KEY5 == 0) //时钟设置按键按下
{
delay_ms(10);
if(KEY5==0)
{
while(!KEY5)
Buzzer(1,100);
DISPLAY_time(shi,fen); //加上这句,按键按下就不会闪
KEY_number ++;
if(KEY_number == 1) //分闪烁
{
write_1302(0x8E,0x00); //
write_1302(write_fen,0x80);
}
if(KEY_number == 3) //时钟启动
{
KEY_number = 0;
write_1302(write_fen , 0x00);
write_1302(0x8E, 0x80); //保护取消
}
}
}
if(KEY_number == 1) //分钟调节
{
if(KEY6 == 0) //加
{
delay_ms(10);
if(KEY6 == 0)
Buzzer(1,100);
{
while(!KEY6)
DISPLAY_time(shi,fen); //加上这句,按键按下就不会闪
fen++;
if(fen==60)
fen=0;
write_1302(write_fen,fen/10*16+fen%10); //写入1302
}
}
}
if(KEY_number == 2)
{
if(KEY6 == 0)
{
delay_ms(10);
if(KEY6 == 0)
Buzzer(1,100);
{
while(!KEY6)
DISPLAY_time(shi,fen); //加上这句,按键按下就不会闪
shi++;
if(shi==24)
shi=0;
write_1302(write_shi,shi/10*16+shi%10);
READ_time();
}
}
}
}
void JDQ_ON_OFF_IF(void)
{
JDQ_miao = READ_1302(read_miao);
JDQ_fen = READ_1302(read_fen);
JDQ_shi = READ_1302(read_shi);
if(JDQ_ON_OFF[SET_COM1][1]!=JDQ_ON_OFF[SET_COM1][3] || JDQ_ON_OFF[SET_COM1][2]!=JDQ_ON_OFF[SET_COM1][4])
{
if(JDQ_ON_OFF[SET_COM1][1]==JDQ_shi && JDQ_ON_OFF[SET_COM1][2]==JDQ_fen && 0==JDQ_miao)
{
COM1 = 0; //打开第一路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM1][3]==JDQ_shi && JDQ_ON_OFF[SET_COM1][4]==JDQ_fen && 0==JDQ_miao)
{
COM1 = 1; //关闭第一路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM2][1]!=JDQ_ON_OFF[SET_COM2][3] || JDQ_ON_OFF[SET_COM2][2]!=JDQ_ON_OFF[SET_COM2][4])
{
if(JDQ_ON_OFF[SET_COM2][1]==JDQ_shi && JDQ_ON_OFF[SET_COM2][2]==JDQ_fen && 0==JDQ_miao)
{
COM2 = 0; //打开第二路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM2][3]==JDQ_shi && JDQ_ON_OFF[SET_COM2][4]==JDQ_fen && 0==JDQ_miao)
{
COM2 = 1; //关闭第二路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM3][1]!=JDQ_ON_OFF[SET_COM3][3] || JDQ_ON_OFF[SET_COM3][2]!=JDQ_ON_OFF[SET_COM3][4])
{
if(JDQ_ON_OFF[SET_COM3][1]==JDQ_shi && JDQ_ON_OFF[SET_COM3][2]==JDQ_fen && 0==JDQ_miao)
{
COM3 = 0; //打开第三路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM3][3]==JDQ_shi && JDQ_ON_OFF[SET_COM3][4]==JDQ_fen && 0==JDQ_miao)
{
COM3 = 1; //关闭第三路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM4][1]!=JDQ_ON_OFF[SET_COM4][3] || JDQ_ON_OFF[SET_COM4][2]!=JDQ_ON_OFF[SET_COM4][4])
{
if(JDQ_ON_OFF[SET_COM4][1]==JDQ_shi && JDQ_ON_OFF[SET_COM4][2]==JDQ_fen && 0==JDQ_miao)
{
COM4 = 0; //打开第四路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM4][3]==JDQ_shi && JDQ_ON_OFF[SET_COM4][4]==JDQ_fen && 0==JDQ_miao)
{
COM4 = 1; //关闭第四路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM5][1]!=JDQ_ON_OFF[SET_COM5][3] || JDQ_ON_OFF[SET_COM5][2]!=JDQ_ON_OFF[SET_COM5][4])
{
if(JDQ_ON_OFF[SET_COM5][1]==JDQ_shi && JDQ_ON_OFF[SET_COM5][2]==JDQ_fen && 0==JDQ_miao)
{
COM5 = 0; //打开第五路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM5][3]==JDQ_shi && JDQ_ON_OFF[SET_COM5][4]==JDQ_fen && 0==JDQ_miao)
{
COM5 = 1; //关闭第五路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM6][1]!=JDQ_ON_OFF[SET_COM6][3] || JDQ_ON_OFF[SET_COM6][2]!=JDQ_ON_OFF[SET_COM6][4])
{
if(JDQ_ON_OFF[SET_COM6][1]==JDQ_shi && JDQ_ON_OFF[SET_COM6][2]==JDQ_fen && 0==JDQ_miao)
{
COM6 = 0; //打开第六路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM6][3]==JDQ_shi && JDQ_ON_OFF[SET_COM6][4]==JDQ_fen && 0==JDQ_miao)
{
COM6 = 1; //关闭第六路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM7][1]!=JDQ_ON_OFF[SET_COM7][3] || JDQ_ON_OFF[SET_COM7][2]!=JDQ_ON_OFF[SET_COM7][4])
{
if(JDQ_ON_OFF[SET_COM7][1]==JDQ_shi && JDQ_ON_OFF[SET_COM7][2]==JDQ_fen && 0==JDQ_miao)
{
COM7 = 0; //打开第七路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM7][3]==JDQ_shi && JDQ_ON_OFF[SET_COM7][4]==JDQ_fen && 0==JDQ_miao)
{
COM7 = 1; //关闭第七路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
if(JDQ_ON_OFF[SET_COM8][1]!=JDQ_ON_OFF[SET_COM8][3] || JDQ_ON_OFF[SET_COM8][2]!=JDQ_ON_OFF[SET_COM8][4])
{
if(JDQ_ON_OFF[SET_COM8][1]==JDQ_shi && JDQ_ON_OFF[SET_COM8][2]==JDQ_fen && 0==JDQ_miao)
{
COM8 = 0; //打开第八路继电器
delay_ms(1000);
Buzzer(1,40);
}
if(JDQ_ON_OFF[SET_COM8][3]==JDQ_shi && JDQ_ON_OFF[SET_COM8][4]==JDQ_fen && 0==JDQ_miao)
{
COM8 = 1; //关闭第八路继电器
delay_ms(1000);
Buzzer(1,40);
}
}
}
void SET_JDQ(void)
{
if(KEY2==0)
{
delay_ms(10);
if(KEY2==0)
{
while(!KEY2)
delay_ms(10);
MODE_number ++;
if(MODE_number==1)
{
GREEN_LED = 0;
YELLOW_LED = 1;
Buzzer(1,80);
on_shi = READ_1302(read_shi);
on_fen = READ_1302(read_fen)+5;
if(on_fen>59)
on_fen = 0;
}
if(MODE_number==2)
{
GREEN_LED = 1;
YELLOW_LED = 0;
Buzzer(1,80);
off_shi = READ_1302(read_shi);
off_fen = READ_1302(read_fen)+15;
if(off_fen>59)
off_fen = 0;
}
if(MODE_number>2)
{
GREEN_LED = 1;
YELLOW_LED = 1;
Buzzer(1,80);
MODE_number=0;
// SET_COM[COM_number] = COM_number;
}
}
}
if(MODE_number==1)
{
if(KEY3==0)
{
delay_ms(10);
if(KEY3==0)
{
while(!KEY3)
delay_ms(10);
JDQ_ON_OFF[COM_number][1] ++;
Buzzer(1,80);
if(JDQ_ON_OFF[COM_number][1]>23)
JDQ_ON_OFF[COM_number][1] = 0;
}
}
if(KEY4==0)
{
delay_ms(10);
if(KEY4==0)
{
while(!KEY4)
delay_ms(10);
JDQ_ON_OFF[COM_number][2] ++;
Buzzer(1,80);
if(JDQ_ON_OFF[COM_number][2]>59)
JDQ_ON_OFF[COM_number][2] = 0;
}
}
DISPLAY_set(JDQ_ON_OFF[COM_number][1], JDQ_ON_OFF[COM_number][2]);
}
if(MODE_number==2)
{
if(KEY3==0)
{
delay_ms(10);
if(KEY3==0)
{
while(!KEY3)
delay_ms(10);
JDQ_ON_OFF[COM_number][3] ++;
Buzzer(1,80);
if(JDQ_ON_OFF[COM_number][3]>23)
JDQ_ON_OFF[COM_number][3] = 0;
}
}
if(KEY4==0)
{
delay_ms(10);
if(KEY4==0)
{
while(!KEY4)
delay_ms(10);
JDQ_ON_OFF[COM_number][4] ++;
Buzzer(1,80);
if(JDQ_ON_OFF[COM_number][4]>59)
JDQ_ON_OFF[COM_number][4] = 0;
}
}
DISPLAY_set(JDQ_ON_OFF[COM_number][3], JDQ_ON_OFF[COM_number][4]);
}
JDQ_ON_OFF_IF();
}
/**************************设置继电器开关时间函数*********************************/
void KEYJDQ(void)
{
if(KEY1==0)
{
delay_ms(10);
if(KEY1==0)
{
while(!KEY1)
SMG_display = 1; //关闭时间显示
delay_ms(5);
COM_number++;
if(COM_number==1) //选择设置继电器通道1
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==2) //选择设置继电器通道2
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==3) //选择设置继电器通道3
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==4) //选择设置继电器通道4
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==5) //选择设置继电器通道5
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==6) //选择设置继电器通道6
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==7) //选择设置继电器通道7
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number==8) //选择设置继电器通道8
{
Buzzer(1,80);
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(500);
}
if(COM_number>8) //进入工作状态
{
Buzzer(1,80);
COM_number = 0;
WE_1 = 0;
DUAN = SMG_array[COM_number];
delay_ms(100);
SMG_display = 0; //重新打开时间显示
}
}
}
if(COM_number==1) //选择设置继电器通道1
{
SET_JDQ();
SET_COM1 = COM_number;
}
if(COM_number==2) //选择设置继电器通道2
{
SET_JDQ();
SET_COM2 = COM_number;
}
if(COM_number==3) //选择设置继电器通道3
{
SET_JDQ();
SET_COM3 = COM_number;
}
if(COM_number==4) //选择设置继电器通道4
{
SET_JDQ();
SET_COM4 = COM_number;
}
if(COM_number==5) //选择设置继电器通道5
{
SET_JDQ();
SET_COM5 = COM_number;
}
if(COM_number==6) //选择设置继电器通道6
{
SET_JDQ();
SET_COM6 = COM_number;
}
if(COM_number==7) //选择设置继电器通道7
{
SET_JDQ();
SET_COM7 = COM_number;
}
if(COM_number==8) //选择设置继电器通道8
{
SET_JDQ();
SET_COM8 = COM_number;
}
}
/*********************************主函数******************************************/
void main(void)
{
TIMER0_init();
// DS1302_init();
Buzzer(1,60);
P1 =0xFF;
P2 =0xFF;
while(1)
{
READ_time();
KEYSCAN();
KEYJDQ();
JDQ_ON_OFF_IF();
}
}
void TIMER0_timer() interrupt 1
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
miao_num++;
if(miao_num>=10)
{
SEC = 0;
}
if(miao_num==20)
{
SEC = 1;
miao_num=0;
}
}
|