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

📄 ceshi.c.bak

📁 电能表误差测试仪的代码.为c语言编写.实现测量实时保存功能.
💻 BAK
📖 第 1 页 / 共 3 页
字号:
#include "PL3105.h"

#define uchar unsigned char
#define uint  unsigned int

/*常量定义*/
#define  CHECK_TIME  600   //3秒钟
#define  PULSE_DZ_CN 5    //待测表收到PULSE_DZ_CN个脉冲后,显示误差
#define  PULSE_JX_CN 3    //机械表收到PULSE_JX_CN个脉冲后,显示误差

//写24XX不同空间的地址指令
#define  WR_2402    0xA0         // 24空间0-2K 不受保护的低半部分
#define  WR_2404    0xA2         // 24空间2-4K 受保护的高半部分

#define  add_0        0x10             // 24空间0-2K
#define  add_1        0x20             // 24空间0-2K
#define  add_2        0x30             // 24空间0-2K
#define  add_3        0x40             // 24空间0-2K
#define  add_4        0x50             // 24空间0-2K
#define  add_5        0x60             // 24空间0-2K
#define  add_6        0x70             // 24空间0-2K
#define  add_7        0x80             // 24空间0-2K
#define  add_8        0x90             // 24空间0-2K
#define  add_9        0xa0             // 24空间0-2K
#define  add_n        0xb0             // 24空间0-2K

/****** I/O 口设置 ********/

sbit  pulse_bz_input  = P1^5;    //标准表脉冲采样
sbit  pulse_dc_input  = P1^6;    //待测表脉冲采样                
sbit  beep            = P1^4;    // 峰鸣器驱动                
sbit  relay           = P1^7;    // 继电器驱动
sbit  an_set_left     = P3^3;    // 常数设置时设置位左移
sbit  an_set_right    = P3^0;    // 常数设置时设置位右移  
sbit  an_set_up       = P3^4;    // 常数设置时设置位加1
sbit  an_set_down     = P3^5;    // 常数设置时设置位减1             
sbit  an_start        = P3^1;    // 开始检表
sbit  an_stop         = P3^2;    // 停止检表
sbit  lamp            = P1^0;    // 调试时用的指示灯
sbit S_Clk      = P1^2;                     // FM24C04的时钟口
sbit S_Dat      = P1^3;                     // FM24C04的数据口


uchar data   pulse_bz_pb;  //标准表脉冲判别
uchar data   pulse_dc_pb;  //待测表脉冲判别

uchar data   pulse_bz_flag;  //标准表脉冲标志
uchar data   pulse_dc_flag;  //待测表脉冲标志
uchar data   current_type; //表类型,机械表,电子表

uint  data   pulse_bz_cn;  //标准表脉冲计数器
uint  data   pulse_dc_cn;  //待测表脉冲计数器
uint  data   pulse_bz_time;  //标准表脉冲计时
uint  data   pulse_dc_time;  //待测表脉冲计时
uint  data   pulse_bz_t;  //标准表脉冲临时计时
uint  data   pulse_dc_t;  //待测表脉冲临时计时

uchar data   an_set_up_cn;   //加1键按下的时间计数器(5毫秒的倍数)
uchar data   an_set_down_cn;   //减1键按下的时间计数器(5毫秒的倍数)
uchar data   an_set_left_cn;   //左移键按下的时间计数器(5毫秒的倍数)
uchar data   an_set_right_cn;   //右移键按下的时间计数器(5毫秒的倍数)
uchar data   an_start_cn;   //开始检表键按下的时间计数器(5毫秒的倍数)
uchar data   an_stop_cn;   //停止检表键按下的时间计数器(5毫秒的倍数)


uchar data   an_set_up_flag;   //加1键按下的标志
uchar data   an_set_down_flag;   //减1键按下的标志
uchar data   an_set_left_flag;   //左移键按下的标志
uchar data   an_set_right_flag;   //右移键按下的标志
uchar data   an_start_flag;   //开始检表键按下的标志
uchar data   an_stop_flag;   //停止检表键按下的标志 

uchar data  check_step;    //
uint  data  check_time;     //
uchar data  error;          //检查脉冲时出错
uchar data  check_pulse;       //检查脉冲
uchar data  sign_flag;           //+-符号,数码显示用
uchar data  showing;        // 当前表常数正在显示.0隐藏

uchar data   current_flash_cn; //当前数码管闪烁的位置。
uchar data   flashing;         //当前数码管正在闪烁。
uchar data   flash_stop;       //消除在设置常数时闪烁位为隐藏状态。
uchar data  led_show_list[6];//数码管显示的数据 译码后的数据。
uchar data  constant_mtr[4]; //电表常数,BCD码中的个位十位百位千位。
uchar data  constant_cn;     //电表常数的排序位置。
uchar data  flashing_time;   //设置常数时数码管闪烁定时器
uchar bdata flashing_con;    //设置常数相关的位组合
sbit  flashing_pb=flashing_con^0; 
sbit  have_pulse= flashing_con^1;  //待测表有脉冲。数码管动态显示有脉冲 
sbit  FM24_Bit  = flashing_con^2;  //
uchar have_pulse_cn;             //待测表有脉冲循环计数,用于数码管动态显示有脉冲
uchar beep_time;             //响铃时间。

uchar data  led_show_flag;   //可刷新数码管显示的标志   
uchar data  key_cn;          //按键按下的时间(5毫秒的倍数)
uchar data  key_time;        //按键屏蔽时间
uchar data  flash_flag;      //闪灯标志 
uchar data  flash_cn;        //闪灯计数器
uchar data  flash_time;      //闪烁节奏定时器
uchar data  flash_ok;        //允许闪

uchar data  watchdog_reset; //看门狗可清标志

uchar data   constant_all_flag;  //='A'可以显示常数。
uchar data    constant_showing;  //='S'当前正在显示常数
uchar xdata  read_buf[16];                   // 读取FM24时用的中间缓冲区
uchar xdata  write_buf[16];                  // 写入FM24时用的中间缓冲区
uchar xdata  constant_all[60];               // 10个常数
/**************************************************************************************
 *
 * FUNCTION:    initsys
 *
 * DESCRIPTION: 初始化设置函数,
 *              进行系统初始化设置
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void initsys(void)
{
  CKCON=0X3F;                       // 控制看门狗喂狗时间长度为832ms (0x8EH)
  ALU_MOD=0;                        // 8位/16位运算模式选择位 ; 设置成8位运算模式 (D0H^1)

  LED_LCD =1;                       // 打开数码管显示

//载波通讯配置
  PLM_SSC=0;                           // (D8H)使能载波通讯PLM_SSC(EXT_CFG.0)=1
  EIE=0X00;                            // (A9H 使能INT2中断(EX2=1)
  IT2=1;                               // (C8H) 为边沿触发方式(IT2=1)。
  PLM_RS=0;                            // PLM_RS(EXT_CTRL.0)=1  为0时,载波处于接收状态

  // T0设置为定时方式
  TMOD=0x21;                        // 设 T/C1 为模式2,8 位自装载计数器 ;T/C0 为模式1, 定时方式,16 位计数器
  TH0=0xF8;                         // 定时器0中断配置
  TL0=0x30;                         // 定时 5ms 一个定时中断
  TR0 =1;                           // 启动 T0 定时器
  ET0 =1;                           // 允许定时器 T0 中断

  
  EA=1;                             // 开总中断


}


/**************************************************************************************
 *
 * FUNCTION:    initsys_ref
 *
 * DESCRIPTION: 初始化重置函数,
 *              进行系统初始化重置
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void initsys_ref(void)
{
   if(ALU_MOD!=0)
   {ALU_MOD=0;
   }
   //载波通讯重置

   if(PLM_SSC!=0)
   {PLM_SSC=0;
   }
   if (EIE!=0x00)
   {EIE=0x00;
   }                          // (A9H 使能INT2中断(EX2=0)

   // T0设置重置为定时方式
   if (TMOD!=0x21)                        // 设 T/C1 为模式2,8 位自装载计数器 ;T/C0 为模式1, 定时方式,16 位计数器
   {TMOD = 0x21;
   }
   if (TR0!=1)                            // 启动 T0 定时器
   {TR0 = 1;
   }
   if (ET0!=1)
   {ET0=1;
   }
   if (EA!=1)                             // 开中断
   {EA=1;
   }

   if(LED_LCD!=1)
   {LED_LCD=1;                         // 打开数码管显示
   }
   

}


/**************************************************************************************
 *
 * FUNCTION:    timeint0
 *
 * DESCRIPTION: 定时器0中断程序,5ms 发生一次中断,
 *              对延时变量进行减1处理
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void  timeint0(void) interrupt 1
{
	 if(check_pulse=='C')
	 {
      //<<<<<<<<<读取脉冲
     if(pulse_bz_flag=='M')
     {  pulse_bz_t++;}	 
     pulse_bz_pb<<= 1;                //标准表脉冲
     if(pulse_bz_input==1)
     {  pulse_bz_pb++;}
     if(pulse_bz_pb==0x03)
     {
        pulse_bz_cn++;
        pulse_bz_time+=pulse_bz_t;
        pulse_bz_t=0x00;
        pulse_bz_flag='M';
        check_time=CHECK_TIME;
     }

     	  if(pulse_dc_flag=='M')
        {  pulse_dc_t++;}
        pulse_dc_pb<<= 1;                 //待测待测表脉冲
        if(pulse_dc_input==1)
        {  pulse_dc_pb++;}
        if(pulse_dc_pb==0x03)
        {  have_pulse=1;
           pulse_dc_cn++;
           pulse_dc_time+=pulse_dc_t;
           pulse_dc_t=0x00;           
           pulse_dc_flag='M';
           if(current_type=='D')
           {
               if(pulse_dc_cn >= PULSE_DZ_CN )
               {  check_pulse='F'; }         //脉冲检测完毕,通知计算显示误差
           }
           else  if(current_type=='J')
           {
               if(pulse_dc_cn >= PULSE_JX_CN )
               {  check_pulse='F'; }         //脉冲检测完毕,通知计算显示误差     	
           }	
        }
   }                           //>>>>>
   
    //<<<<<<<<按键
   key_cn++;                     
   if(key_cn>3)
   {  key_cn=0;
      an_set_left_cn=0;
      an_set_right_cn=0;
      an_set_up_cn=0;
      an_set_down_cn=0;
      an_start_cn=0;
      an_stop_cn=0;
   }
   if(key_time!=0)
   {
      key_time--;
   }

   if(key_time==0)
   {
       if(an_set_left==1)            
       {an_set_left_cn++;}
       if(an_set_right==1)            
       {an_set_right_cn++;}   
       if(an_set_up==1)            
       {an_set_up_cn++;}
       if(an_set_down==1)            
       {an_set_down_cn++;}
       if(an_start==1)            
       {an_start_cn++;}
       if(an_stop==1)            
       {an_stop_cn++;}                      
   }
  
  
 //>>>>>>>按键
 

   if(flashing_time!=0)                   
   {
      flashing_time--;                       //设置常数时闪烁定时器。
   }
  
   if(beep_time!=0)                   
   {
      beep_time--;                       //设置常数时闪烁定时器。
   } 
   if(check_time!=0x00)
   {check_time--;
   }
   if(watchdog_reset==0x9a)
   {
      WDT_RST=0xa1;                         // 清看门狗
      watchdog_reset=0;
   }

   TH0=0xF8;                                // 置定时器计数   5ms 中断一次( 9.6/2 )
   TL0=0x30;

}
/**************************************************************************************
 *
 * FUNCTION:    LED_DIS_TEST
 *
 * DESCRIPTION:  数码管显示测试程序
 *               将数码管全部点亮,可以检查数码管是否有问题
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void led_dis_test()
{
  uchar i;
  for(i=0x10; i<0x1c; i++)
  {
     EXT_ADR=i;
     EXT_DAT=0xFF;
  }

}
/**************************************************************************************
 *
 * FUNCTION:    LCD_DIS_CLEAR
 *
 * DESCRIPTION:  数码管显示清屏程序
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void led_dis_clr()
{
  uchar i;
  for(i=0x10; i<0x1c; i++)
  {
    EXT_ADR=i;
    EXT_DAT=0x00;
  }
}
/*
void led_dis_hello()
{
   EXT_ADR=0x10;
   EXT_DAT=0x3f;

   EXT_ADR=0x11;
   EXT_DAT=0x38;

   EXT_ADR=0x12;
   EXT_DAT=0x38;

   EXT_ADR=0x13;
   EXT_DAT=0x79;
   
   EXT_ADR=0x14;
   EXT_DAT=0x76;

   EXT_ADR=0x15;
   EXT_DAT=0x00;
}*/

/**************************************************************************************
 *
 * FUNCTION:    Send_I2C_Start
 *
 * DESCRIPTION:  启动I2C总线(发送起始条件)
 *               在SCL为高电平时,SDA上一个由高到低的跳变就可以启动总线
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void Send_I2C_Start()
{
   S_Dat=1;
   S_Dat=1;
   S_Dat=1;

   S_Clk=1;                       // 起始条件建立时间大于4.7us
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;

   S_Dat=0;                      // 起始条件锁定时大于4us
   S_Dat=0;
   S_Dat=0;
   S_Dat=0;

   S_Clk=0;                      // 钳住总线,准备发送数据
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
}


/**************************************************************************************
 *
 * FUNCTION:    Send_I2C_Stop
 *
 * DESCRIPTION:  关闭I2C总线(发送停止条件)
 *               在SCL为高电平时,SDA上一个由低到高的跳变就会终止总线
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void Send_I2C_Stop()
{
   S_Dat=0;
   S_Dat=0;
   S_Dat=0;

   S_Clk=1;                       // 发送结束条件的时钟信号,结束总线时间大于4us
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;

   S_Dat=1;                       // 结束总线,保证终止信号和起始信号的空闲时间大于4.7us
   S_Dat=1;
   S_Dat=1;
   S_Dat=1;

   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
}



/**************************************************************************************
 *
 * FUNCTION:    Send_I2C_Ack
 *
 * DESCRIPTION:  发送应答信号
 *               在SCL的一个由低到高再由高到低的周期里,保持SDA为低电平,即为应答信号。
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void Send_I2C_Ack()
{
   S_Dat=0;                       // 将S_Dat置低
   S_Dat=0;
   S_Dat=0;
   S_Dat=0;

   S_Clk=1;                       // 保持数据时间,即S_Clk为高,时间大于4.7us
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;
   S_Clk=1;

   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
   S_Clk=0;
}


/**************************************************************************************
 *
 * FUNCTION:    Check_I2C_Ack
 *
 * DESCRIPTION:  检测I2C总线的应答信号
 *
 *
 * PARAMETERS:  none
 *
 * RETURNED:    返回I2C总线的应答状态=00正确应答=01 错误
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -