📄 108.c
字号:
/*软件名称:智能涡轮流量计 *
* *
*作者:李维平&陈超 *
*时间:星期二 2005年4月26日 *
* 晶振:640KHZ *
* 微处理器:PIC16F877或者PIC16F877A *
* 采用澳大利亚HI-TECH公司的PICC编译器 * * 功能简介: *
*可显示瞬时流量和累计流量 *
*累计量定时存储于EEPROM *
*瞬时量和累计量都可实现精度自动调整(小数点动态移动显示) *
*仪表系数K可以在线置入EEPROM当中,设置同时计量工作仍继续 *
*当第一点K值为0时,可以作为频率计使用 *
*仪表系数的点数可通过修改宏定义中的set 值来改变,范围3~6点 *
*按键操作采用中断方式 *
*仪表系数K默认小数部分为零 *
* *
* */
#include <pic.h>
#include <pic1687x.h>
//#include <pic168xa.h>
#include <math.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define ushort unsigned short
#define ulong unsigned long
#define sleep() asm("sleep")
#define nop() asm("nop")
#define clrwdt() asm("clrwdt")
#define CS RB1
#define WR RB2
#define DATA RB3
#define KEY_SR RB4 //RB4
#define KEY_ADD RB6
#define KEY_F RB5 //RB6
#define set1 3 //set1为仪表系数点数3~6点
#define set2 1 //set2为0,无满度流量,set2为1,有满度流量
void delay(uchar x,uchar y);
void delay1(void);
void delay2(void);
void Lcd_Write_Com(uchar com);
void Lcd_Write_Data_Contin_u(uchar addr,uchar j);
void Lcd_Write_Data_Contin_n(uchar addr,uchar j);
void Lcd_Write_Data_Q_or_P(uchar j);
void Lcd_Black();
void Lcd_Init(void);
void Timer_Init(void);
void Eeprom_Initia(void);
void interrupt ISR(void);
void Read_Fre_K(void);
void Caculate_pre();
void Caculate();
void Caculate_Q3();
void Dis_Buf(void);
void Lcd_Dispay(void);
void Cumulation_to_EEPROM();
void Read_Sum_flux();
void Parameter_Set();
void ccp2_out(void);
void Sum_Q_Clear();
bank3 uchar i,eeadr,addr,da,time_f_sr=0,time_sr=0,no_f=0,ti;
bit flag_tmr0=0,flag_tmr1=0,key_f=0,key_sr=0,key_add=0,key_f_add=0,key_f_sr=0,key_sr_add=0,flag_set=0,flag_out=0,flag_turn,flag_mid;
uchar *p1,x[3],y[3],save_time,save_adr,pass_time,ct=0,disp_buf[15],disp;
bank2 uchar n1,m1,n2,m2,n3,m3,n4,m4,gdl,jc,jm;
bank3 uint x1,x2,F1,F2,F3,F4,F5,F6,Q2d,ff;
bank2 float K1,K2,K3,K4,K5,K6,b0,b1,b2,b3,b4;
bank1 ulong Q3nd,Q3ud,Q3INT,Qfull;
bank1 float Q2,Q3DEC,*p2,fr,K,qqq,Q1,frqian,Qliu,Q3;
bank1 uint mm @ 0xA0;
bank3 uint gao @ 0x1A0;
bank3 uchar cp @ 0x1A2;
const char table_up_for_lcd [25][2]={// the digit from "0" to "9" for upper number 1~6
{0xe0,0xb0},{0x60,0x00},{0xC0,0x70},{0xe0,0x50},//0~9不带点
{0x60,0xc0},{0xa0,0xd0},{0xa0,0xf0},{0xe0,0x00},
{0xe0,0xf0},{0xe0,0xd0},
{0xf0,0xb0},{0x70,0x00},{0xd0,0x70},{0xf0,0x50}, //0~9带点
{0x70,0xc0},{0xb0,0xd0},{0xb0,0xf0},{0xf0,0x00},
{0xf0,0xf0},{0xf0,0xd0},
{0x00,0x00},{0x10,0x00}}; //BLACK,末尾显Q1可不要 03.10调换后两位位置
const char table_nether_for_lcd[21][2]={ //used nether number 7~14 // segment for character 0~9
{0xd0,0x70},{0x00,0x60},{0xe0,0x30},{0xa0,0x70}, //0~3不带点
{0x30,0x60},{0xb0,0x50},{0xF0,0x50},{0x00,0x70}, //4~7
{0xf0,0x70},{0xb0,0x70},
{0xd0,0xf0},{0x00,0xe0},{0xe0,0xb0},{0xa0,0xf0}, //0~3带点
{0x30,0xe0},{0xb0,0xd0},{0xF0,0xd0},{0x00,0xf0}, //4~7
{0xf0,0xf0},{0xb0,0xf0},
{0x00,0x00} }; //8,9,.,black
const char Ladr[16]={ //液晶字符地址
0x15,0x13,0x11,0x0f,
0x1e,0x1c,0x00,0x02,0x04,0x06,0x08,0x0a,0x19,0x17};
//#pragma interrupt_level 1
void delay(uchar x,uchar y) //delay time :14+(3*(Y-1)+7)*(X-1)
{
uchar z;
do{
z=y;
do{;}while(--z);
}while(--x);
}
void delay1() //delay function
{
nop();
}
void delay2() //delay function
{
uchar x;
x=250;
while(--x){;};
}
void Lcd_Write_Com(uchar com) //write command to lcd
{
uchar j;
CS=1; // pre-initialize
delay1();
nop();
CS=0; // pre-initialize
delay1();
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1 command mode 100
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
for(j=0;j<8;j++) //write 8+1 bit command
{
if(com&0x80)
DATA=1;
else
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1();
com<<=1;
}
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //the last bit of the command 0
}
//#pragma interrupt_level 1
void Lcd_Write_Data_Contin_u(uchar addr,uchar j) //液晶显示器上排显示
{
uchar k,m,da;
CS=1; // pre-initialize
delay1();
CS=0; // pre-initialize
delay1();
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1 data mode 101
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1
addr<<=2; //surpose that ADDR=8bit
for (k=0;k<6;k++)
{
if (addr&0x80)
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
addr<<=1;
}
for(k=0;k<2;k++) //send number
{
da= table_up_for_lcd [j][k]; //j is determined by other things
for(m=0;m<4;m++)
{
if(da&0x80) //send DATA first ,WR clock second for safety
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
da<<=1;
}
}
}
//#pragma interrupt_level 1
void Lcd_Write_Data_Contin_n(uchar addr,uchar j) //液晶显示器下排显示
{
uchar k,m,da;
CS=1; // pre-initialize
delay1();
CS=0; // pre-initialize
delay1();
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1 data mode 101
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1
// addr=0x19; //the digit 5's address
// Lcd_Write_Data_Addr();
addr<<=2; //surpose that ADDR=8bit
for (k=0;k<6;k++)
{
if (addr&0x80)
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
addr<<=1;
}
for(k=0;k<2;k++) //send number
{
da= table_nether_for_lcd [j][k]; //j is determined by other things
for(m=0;m<4;m++)
{
if(da&0x80) //send DATA first ,WR clock second for safety
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
da<<=1;
}
}
}
//#pragma interrupt_level 1
void Lcd_Write_Data_Q_or_P(uchar j) //K1为0时显示P,其余情况显示Q
{
uchar k,m,da,addr;
CS=1; // pre-initialize
delay1();
CS=0; // pre-initialize
delay1();
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1 data mode 101
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1
addr=0x1b;
addr<<=2; //surpose that ADDR=8bit
for (k=0;k<6;k++)
{
if (addr&0x80)
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
addr<<=1;
}
da=j; //0x01--Q1; 0x0e--P; 0x0f--Q1P
for(m=0;m<4;m++)
{
if(da&0x08) //send DATA first ,WR clock second for safety
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
da<<=1;
}
}
//#pragma interrupt_level 1
void Lcd_Black() //全黑屏
{
uchar k,m,da,i,addr;
//write data mode :101
CS=1; // pre-initialize
delay1();
CS=0; // pre-initialize
delay1();
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1 data mode 101
DATA=0;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=0
DATA=1;
delay1();
WR=0;
delay1();
WR=1;
delay1(); //d=1
addr=0x00; //the digit 5's address
// Lcd_Write_Data_Addr();
//addr<<=2; //surpose that cpu sets ADDR=8bit
for (k=0;k<6;k++)
{
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
}
for(m=0;m<32;m++) //32 addr:00000--------11111
{
//da=0x08; //TEST DA=0X00,0X01,0X02,0X04,0X08
//da<<=4;
da=0x00; //TEST DA=0X00,0X10,0X20,0X40,0X80
for(i=0;i<4;i++)
{
if(da&0x80)
DATA=1;
else
DATA=0;
WR=0;
delay1();
WR=1;
delay1();
da<<=1;
}
}
}
void Lcd_Init(void) //initialize the lcd
{
delay2();
Lcd_Write_Com(0b00101001); //own to LCM141 only
Lcd_Write_Com(0b00010100); // external oscillator mode
Lcd_Write_Com(0b00000001); //open oscillater
Lcd_Write_Com(0b00000011);
}
void Timer_Init(void)
{
Lcd_Black();
clrwdt();
INTCON=0xe8; //ei();//GIE=1;PEIE=1;T0IF=0;T0IE=1; T0CS=0;//选内部时钟
OPTION=0x87; //分频比为 1:256 ,屏蔽RB口弱上拉~RBPU=1//PSA=0;
//TMR0=0x62;
TMR1IE=0;
//TMR1IF=0;
T1CON=0x03; //P13WLT//分频比1:1T1CKPS1=0;T1CKPS0=0;~T1SYNC=0同步;
TMR1H=0x00; //赋初值;TMR1CS=1计数;TMR1ON=1;//开启计数器
TMR1L=0x00;
TMR0=0x97;
clrwdt();
}
#pragma interrupt_level 1
void interrupt ISR(void)
{
if(KEY_F) //莫用 if(RBIE&&RBIF)语句,否则任意键按下都会中断(起作用)
{key_f=1;
}
else
{key_f=0;
RBIF=0;
}
if(KEY_SR)
{key_sr=1;
}
else
{key_sr=0;
RBIF=0;
}
if(KEY_ADD)
{key_add=1;
}
else
{key_add=0;
RBIF=0;
}
if(KEY_F&&KEY_SR) //进入置数状态标志
{
key_f_sr=1;
}
else
{key_f_sr=0;
RBIF=0;
}
if(KEY_SR&&KEY_ADD)
{
key_sr_add=1;
}
else
{key_sr_add=0;
RBIF=0;
}
if(KEY_F&&KEY_ADD) //莫用 if(RBIE&&RBIF)语句,清累计量标志
{key_f_add=1;
} //也可读一下PORTB口
else
{key_f_add=0;
RBIF=0;
}
if(T0IF&&T0IE) //定时时间1s=(4/640k)*(256-tm0)[158]*(分频比256)*循环次数c[4]
{
T0IF=0;
ct++;
TMR0=0x97; //可设初值为4,然后c--;
if(ct%2==0)
{flag_tmr1=1;
flag_turn=!flag_turn;
flag_tmr1=0;}
if(ct==6) //原为4
{
flag_tmr0=1;
ct=0; }
}
}
void Read_Fre_K() //读出仪表系数
{
uchar i;
uint a,b,c,e;
float d,g;
uchar da_ee[12];
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(255-i);clrwdt();}
a=da_ee[0]*1000;clrwdt();
b=da_ee[1]*100;clrwdt();
c=da_ee[2]*10;clrwdt();
F1=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(251-i);clrwdt();}
da_ee[4]=eeprom_read(251);
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
c=da_ee[8]*10;clrwdt();
K1=da_ee[9]+c+b+a+d;clrwdt();
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(243-i);clrwdt();}
a=da_ee[0]*1000;
b=da_ee[1]*100;
c=da_ee[2]*10;
F2=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(239-i);clrwdt();}
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
c=da_ee[8]*10;clrwdt();
K2=da_ee[9]+c+b+a+d;clrwdt();
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(231-i);clrwdt();}
a=da_ee[0]*1000;
b=da_ee[1]*100;
c=da_ee[2]*10;
F3=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(227-i);clrwdt();}
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
c=da_ee[8]*10;clrwdt();
K3=da_ee[9]+c+b+a+d;clrwdt();
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(219-i);clrwdt();}
a=da_ee[0]*1000;clrwdt();
b=da_ee[1]*100;clrwdt();
c=da_ee[2]*10;clrwdt();
F4=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(215-i);clrwdt();}
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
c=da_ee[8]*10;clrwdt();
K4=da_ee[9]+c+b+a+d;clrwdt();
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(207-i);clrwdt();}
a=da_ee[0]*1000;clrwdt();
b=da_ee[1]*100;clrwdt();
c=da_ee[2]*10;clrwdt();
F5=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(203-i);clrwdt();}
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
c=da_ee[8]*10;clrwdt();
K5=da_ee[9]+c+b+a+d;clrwdt();
for(i=0;i<4;i++)
{da_ee[i]=eeprom_read(195-i);clrwdt();}
a=da_ee[0]*1000;clrwdt();
b=da_ee[1]*100;clrwdt();
c=da_ee[2]*10;clrwdt();
F6=a+b+c+da_ee[3];clrwdt();
for(i=0;i<8;i++)
{da_ee[4+i]=eeprom_read(191-i);clrwdt();}
d=da_ee[4]*1000;clrwdt();
e=da_ee[5]*100;clrwdt();
d=(d+e)*100;
a=da_ee[6]*1000;clrwdt();
b=da_ee[7]*100;clrwdt();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -