⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kg.c

📁 89C2051 C语言例程,用于继电器和可控硅控制,并采样交流电频率
💻 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 + -