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

📄 3-0.c

📁 PIC单片机编写显示表头,用于测量脉冲输出式速度信号
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*软件名称:智能涡轮流量计					*
 	*								*
	*作者:李维平&陈超						*
	*时间:星期二 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 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,da_ee[12];
bank2 uchar n1,m1,n2,m2,n3,m3,n4,m4,gdl,jc,jm,cp,t2ct,numct;
bank3 uint x1,x2,F1,F2,F3,F4,F5,F6,Q2d,ff,gao,mm,Q3ud,pulout,mpul,npul;
bank2 float K1,K2,K3,K4,K5,K6,b0,b1,b2,b3,b4;
bank1 ulong Q3nd,Q3INT,Qfull,Qpint;
bank1 float Q2,Q3DEC,*p2,K,qqq,Q1,frqian,Qliu,Q3,fr,Qpdec;
//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; 
TMR2IE=1; 
TMR2IF=0; 
T2CON=0x02;
//TMR2ON=0;
TMR2=0x00;
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)
{uint i;

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; }
	}
if(TMR2IF&&TMR2IE) 		//定时时间1s=(4/640k)*(256-tm0)[158]*(分频比256)*循环次数c[4]
	{ 
	TMR2IF=0;
	TMR2=0x00; 
	PR2=0xc8;
	RB0=1;
	for(i=1;i<=100;i++)
	{nop();}
	RB0=0;
	t2ct++;
	
	if(t2ct==numct)       //原为4
		{ 
		TMR2ON=0;
		t2ct=0; }
	}
}

void Read_Fre_K()			//读出仪表系数
	{
	uchar i;
	uint a,b,c,e;
	float d,g,h;
//	uchar da_ee[12];
	
	nop();
	nop();
	nop();
	for(i=0;i<4;i++)
	{da_ee[i]=eeprom_read(255-i);clrwdt();nop();}
	
	a=da_ee[0]*1000;
	b=da_ee[1]*100;
	c=da_ee[2]*10;
	F1=a+b+c+da_ee[3];clrwdt();

	for(i=0;i<8;i++)
	{da_ee[4+i]=eeprom_read(251-i);clrwdt();nop();}			

	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();nop();}
	
	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();nop();}	
	
	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();


⌨️ 快捷键说明

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