📄 kg.c
字号:
/**************************版本说明说明***************************/
/******************V2.0硬件版本需要控制风门正反转*****************/
/******************V2.1硬件版本去掉了控制风门正反转操作***********/
#include "REG51.h"
#include "intrins.h"
#include "math.h"
#include "stdio.h"
#include "absacc.h"
#include "string.h"
#include "stdlib.h"
#define uchar unsigned char
#define uint unsigned int
#define ulint unsigned long int
sbit SCR_CNL = P1^7; //可控硅控制信号,用来控制风机或空调,风机是高导通,空调是低导通
sbit RS485_CNL = P1^6; //RS485方向控制信号,低为接收,高为发送
sbit RUN_LED_CNL = P1^5; //工作灯控制
sbit CS = P1^4; //273的锁存信号,先给信号附值,再给锁存信号,锁存信号是一个1US的低脉冲
sbit DOG =P3^4; //看门狗喂狗信号
sbit type0 =P3^5; //设备类型位0
sbit type1 =P3^7; //设备类型位1
uchar runledtime=200,one_scond_count=0; //
uint rst_time=6000;
uchar rxd_data_buf[10],txd_data_buf[10],rxd_da_buf;
uchar rxd_data_num_count=0,ensig=0,fysig=0;
bit send_flag=0,into_mark1=0;
// type0 tpye1 类型
// 0 0 空调控制
// 1 0 进风机控制
// 0 1 出风机控制
void Delay(int x)//延时子程序
{
int i,j;
for(i=0;i<x;i++)
{
DOG=~DOG;
for(j=0;j<1000;j++);
}
}
void sc_sig() //273锁存信号控制信号
{
CS=1;
Delay(1);
CS=0;
Delay(1);
CS=1;
}
void fengji_power_cntl(bit power_flag) //风机
{
if( power_flag)SCR_CNL=1; //启动风机
else SCR_CNL=0; //关掉风机
sc_sig(); //273锁存信号
}
void kongtiao_power_cntl(bit power_flag) //空调控制子程序
{
if( power_flag)SCR_CNL=0; //启动空调
else SCR_CNL=1; //关掉空调
sc_sig(); //273锁存信号
}
void rs485_direction_cntrl(bit direction_flag) //rs485发送方向控制 1为发送,0为接收
{
RS485_CNL=direction_flag;
sc_sig(); //273锁存信号
}
void interrupt_init (void)//中断初始化
{
PCON = 0x80;
SCON = 0x50; /* mode 1: 8-bit UART, enable receiver */
TMOD = 0x21; /* timer 1 mode 2: 8-Bit reload */
TH1 = 0xfc; /* reload value 9600 baud */
TL1 = 0xfc;
TR1 = 1; /* timer 1 enable */
ES = 1; /* enable serial port interrupt */
TH0=0xf4; TL0=0x18; /* initial Timer0 interrupt 5ms */
ET0=1; TR0=1; /* timer 0 run and interrupt opened*/
EA=1; /* enable all interrupt */
}
void init_system( )//系统状态初始化
{
rs485_direction_cntrl(0); //485初始化为接收
if((!type0)&&(!type1))kongtiao_power_cntl(0);//如果复合开关属于空调控制类型,初始化时关空调
else fengji_power_cntl(0); //如果复合开关属于风机控制类型,初始化时关风机
interrupt_init ( );//串口和定时器、外部中断的初始化
}
void txd_send( ) //串口采用查询方式发送,每次发5个字节,第0字节固定为7E,尾字节固定为0D;
{ //第1字节为设备类型,第2字节是设备地址码,第3字节根据接收指令不同而内容不同
uchar i,t;
rs485_direction_cntrl(1);//设RS485为发送
txd_data_buf[0]=0x7e; //
txd_data_buf[4]=0x0d;
for(i=0;i<5;i++) //发送5个字节数据
{
SBUF=txd_data_buf[i];
while(TI==0); //标志位TI=1时跳出循环,TI置0
TI=0;
}
Delay(20);//延时16MS
rs485_direction_cntrl(0);//设RS485为接收
}
void process() //指令执行程序
{
uchar i,j,n,addr_number,type_number;
if(!type0&&!type1)type_number=0; //本设备为控制空调
if(type0&&!type1)type_number=1; //本设备为控制进风机
if(!type0&&type1)type_number=2; //本设备为控制出风机
addr_number=P1; //读取地址码
addr_number&=0x0f;
n=rxd_data_buf[1];
i=rxd_data_buf[2];
txd_data_buf[1]= type_number;//给串口发送数据附值
txd_data_buf[2]= addr_number;
if(send_flag) //如果串口接收到指令
{
if(n==type_number&&i==addr_number) //如果主机要对本设备操作
{
j=rxd_data_buf[3];//判断主机的指令内容
switch(j)
{
case 1: fengji_power_cntl(1); Delay(50); //开风机
ensig=0; //开关机确认信号置0
one_scond_count=200; //附时间值
IT0=1;EX0=1; //启动外部中断0,负跳变沿触发中断
while(one_scond_count); //1秒时间到
EX0=0; //关中断
txd_data_buf[3]=ensig;//读取确认信号,准备发出去
break;
case 2: fengji_power_cntl(0);Delay(50); //关风机
ensig=0; //开关机确认信号置0
one_scond_count=200;
IT0=1;EX0=1;
while(one_scond_count);
EX0=0;
txd_data_buf[3]=ensig;
break;
case 3: kongtiao_power_cntl(1); Delay(50); //开空调
ensig=0;one_scond_count=200;
IT0=1;EX0=1;
while(one_scond_count);
EX0=0;
txd_data_buf[3]=ensig;
break;
case 4: kongtiao_power_cntl(0); Delay(50);//关空调
ensig=0;one_scond_count=200;
IT0=1;EX0=1;
while(one_scond_count);
EX0=0;
txd_data_buf[3]=ensig;
break;
case 5: fysig=0; //风压传感器数据置0
one_scond_count=200;
IT1=1;EX1=1;
//读取风压传感器数据
while(one_scond_count);
EX1=0;
txd_data_buf[3]=fysig;
break;
case 6:
txd_data_buf[3]=6; //设备接受主机的查询,查询本设备是否存在
break;
}
rst_time=6000; //串口接收到数据后,本设备认为主机和串口都没故障,
//所以重新给状态复位定时时间变量附值
txd_send( ); //串口给主机返回信息
}
send_flag=0; //清串口接收标志
}
if( rxd_data_buf[1]==0x55&&rxd_data_buf[2]==0xaa&&rxd_data_buf[3]==0x55)
{
rst_time=6000; //串口接收到广播信息,重新给状态复位定时时间变量附值
}
if(!rst_time) //30秒到,没收到广播信息
{
if((!type0&&type1)||(type0&&!type1))fengji_power_cntl(0);//如果是控制进风机或出风机设备,
//执行关风机操作
if(!type0&&!type1)kongtiao_power_cntl(1); //如果是控制空调设备,执行开空调操作
rst_time=6000; //重新给状态复位定时时间变量附值
}
}
void EXTERN_INT0() interrupt 0
{
if(ensig<255)ensig++; //确认信号自加
}
void timer0() interrupt 1 //5MS定时中断
{
TH0=0xf4,TL0=0x18; //重新赋值,5毫秒中断1次
if(runledtime)runledtime--; //1秒喂狗一次
else {
runledtime=200;
RUN_LED_CNL=~RUN_LED_CNL;
sc_sig(); //273锁存信号
DOG=~DOG;
}
if(one_scond_count)one_scond_count--; //1秒时间定时,用于捕捉上下电确认信号和风压开关信号
if(rst_time)rst_time--; //30秒定时,用于广播信息接收时间间隔的限制
}
void EXTERN_INT1() interrupt 2
{
if(fysig<255)fysig++; //风压开关数据自加
}
void serial (void) interrupt 4 //串口中断接收
{
ES=0;//关串口中断
RI=0; //接收标志清零
TR1=0; //停TIME1计数
rxd_da_buf=SBUF;//读取串口数据
if(rxd_da_buf==0x7e) //接收头字节
{
rxd_data_num_count=0;
into_mark1=1;
}
if(into_mark1)
{
rxd_data_buf[rxd_data_num_count] = rxd_da_buf;
if(rxd_da_buf==0x0d) //是尾字节
{
rxd_data_num_count=0;
into_mark1=0;
send_flag=1;
Delay(10);
}
else rxd_data_num_count++;
}
TR1=1; //恢复TIME1 计数
ES=1; //恢复串口中断
}
void main()
{
uchar i,n,m=0;
for(i=0;i<10;i++){rxd_data_buf[i]=0xaa;txd_data_buf[i]=0x55;}
init_system( );
interrupt_init ( );
while(1)
{
process();
DOG=~DOG;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -