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

📄 opm-main.#1

📁 用C8051F060开发的光功率计 由C51编写的程序
💻 #1
字号:

/*****************************************************************

应    用:光功率计(LCD版)				作    者:姚虹
文 件 名:OPM-LCD.c						编译系统:Keil C51
起止时间:2008.7.22						版    本:V1.00

基本功能:
1、通道采样,平滑滤波
2、数据转换
3、本地显示-送LCD显示
4、数据传送-送串口

*****************************************************************/

	#include "c8051F060.h"
	#include <intrins.h>
	#include <math.h>

	#define uchar unsigned char
	#define uint unsigned int
	#define ulong unsigned long

//---------------------------数据采集与处理
	uint idata ADC0G[20];			//采样数组
	uint idata ADC1G[20];

	ulong idata ADC0_S;				//和
	ulong idata ADC1_S;

	uint idata ADC0_M;				//均值-积分项
	uint idata ADC1_M;

	float idata ADC0_MP;
	float idata ADC1_MP;

	float idata ADC0_M1;
	float idata ADC0_M2;
	float idata ADC1_M1;
	float idata ADC1_M2;

	uchar idata N;

	float idata ADC0_F;
	float idata ADC1_F;

	float * ip;

	float idata FloatDec;

	uint idata F_Int;
	uint idata F_Dec;

	#define Vref 2.45

//--------------------------数据传送与处理
	uchar idata Command;
	bit CommSign = 0;

	uchar xdata HoldData[16];		//非易失数据保存包:1-、2-、

//--------------------------数据显示与处理
	sbit CS1 = P1 ^ 0;
	sbit CS2 = P1 ^ 1;
	sbit RES = P1 ^ 2;
	sbit RW  = P1 ^ 3;
	sbit DI  = P1 ^ 4;
	sbit EE  = P1 ^ 5; 

	uchar idata Bcd[6];				//二进制转BCD码组

	uchar xdata ShowPage1[256];	//开机页面
	uchar xdata ShowPage2[256];
	uchar xdata ShowPage3[256];
	uchar xdata ShowPage4[256];

	uchar xdata ShowPage5[256];	//仪表页面
	uchar xdata ShowPage6[256];
	uchar xdata ShowPage7[256];
	uchar xdata ShowPage8[256];

	uint TT = 5000;

	bit Ty;

//--------------------------键盘数据处理
	sbit KEY1 = P0 ^ 4;				//键盘中断检测线
	sbit KEY2 = P0 ^ 5;
	sbit KEY3 = P0 ^ 6;			
	sbit KEY4 = P0 ^ 7;

	bit DataCapture = 1;
	bit Instrument = 1;

/*======================================================*/

	void Init_Device(void);
	char code BS_Pape[];
	char code Meter_Pape[];

	char code Asc_Z[];


/*======================================================*/
/*------------------------------------延时*/
Delay(uchar Cyc)
{
	uchar i;
	for (i = 0;i < Cyc;i ++)
	{
		_nop_();
	}
}
/*------------------------------------二进制-BCD转换*/
Hex_Asc(uint value)	
{
	Bcd[1] = (value / 10000);
	Bcd[2] = ((value % 10000) / 1000);
	Bcd[3] = ((value % 1000) / 100);
	Bcd[4] = ((value % 100) / 10);
	Bcd[5] = (value % 10);
}
/*------------------------------------写flash*****/
WRflash()
{
	uchar i;
	uchar xdata * pwrite;				//程序存储器空间的指针(FLASH),指向待写地址

	SFRPAGE = LEGACY_PAGE;
	pwrite = 0x0000;					//初始化CODE读指针
	FLSCL = 0x21;						//置位FLWE
	PSCTL = 0x07;						//置位SFLE,PSEE,PSWE
	* pwrite = 0;						//启动擦除过程
	PSCTL = 0x05;						//清除PSEE
	pwrite = 0x0000;

	for (i = 0;i < 16;i ++)
		* pwrite ++ = HoldData[i];

	PSCTL = 0x00;						//复位SFLE,PSEE,PSWE
}
/*------------------------------------读flash*****/
RDflash()	
{
	uchar i;
	uchar code * pread;					//程序存储器空间的指针(FLASH),指向待读地址

	SFRPAGE = LEGACY_PAGE;
	PSCTL = 0x04;						//访问FLASH时将访问128B的临时存储器扇区
	pread = 0x0000;						//初始化CODE读指针

	for (i = 0;i < 16;i ++)
		HoldData[i] = * pread ++;

	PSCTL = 0x00;
}
/*------------------------------------通讯数据发送*/
Data_PC(uint A0,A1)
{
	uchar ADC0_L,ADC0_H,ADC1_L,ADC1_H;

	ADC0_L = A0;
	ADC0_H = A0 >> 8;

	ADC1_L = A1;
	ADC1_H = A1 >> 8;

    SFRPAGE   = UART0_PAGE;
	TI0 = 0;
	SBUF0 = ADC0_H;
	while (TI0 == 0);
	TI0 = 0;
	SBUF0 = ADC0_L;
	while (TI0 == 0);
	TI0 = 0;
	SBUF0 = ADC1_H;
	while (TI0 == 0);
	TI0 = 0;
	SBUF0 = ADC1_L;
	while (TI0 == 0);
}
/*------------------------------------写LCD命令*/
LCD_Command(uchar SW)
{
	DI = 0;
	EE = 1;
	P2 = SW;
	Delay(15);
	EE = 0;
}
/*------------------------------------刷新LCD-开始页*/
LCD_DataRefurbish1()
{
	uint i;uchar j;

	CS1 = 1;
	CS2 = 0;
	LCD_Command(0x40);

	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage1[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j + 4);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage2[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}

	CS1 = 0;
	CS2 = 1;
	LCD_Command(0x40);

	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage3[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j + 4);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage4[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
}
/*------------------------------------刷新LCD-仪表面页*/
LCD_DataRefurbish2()
{
	uint i;uchar j;

	CS1 = 1;
	CS2 = 0;
	LCD_Command(0x40);

	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage5[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j + 4);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage6[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}

	CS1 = 0;
	CS2 = 1;
	LCD_Command(0x40);

	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage7[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
	for (j = 0;j < 4;j ++)
	{
		LCD_Command(0xb8 + j + 4);
		DI = 1;
		for (i = 0;i < 64;i ++)
		{
			EE = 1;
			P2 = ShowPage8[i + (j * 64)];
			Delay(15);
			EE = 0;
		}
	}
}
/*------------------------------------LCD初始化*/
LCD_initialize()
{
	uint i;

	RES = 0;
	Delay(1);

	RES = 1;

	EE = 0;
	RW = 0;
	CS1 = 0;
	CS2 = 0;

	for (i = 0;i < 256;i ++)
	{
		ShowPage3[i] = BS_Pape[i];
		ip ++;
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage4[i] = BS_Pape[i + 256];
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage1[i] = BS_Pape[i + 512];
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage2[i] = BS_Pape[i + 768];
	}

	for (i = 0;i < 256;i ++)
	{
		ShowPage7[i] = Meter_Pape[i];
		ip ++;
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage8[i] = Meter_Pape[i + 256];
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage5[i] = Meter_Pape[i + 512];
	}
	for (i = 0;i < 256;i ++)
	{
		ShowPage6[i] = Meter_Pape[i + 768];
	}

	LCD_Command(0x3f);
	LCD_Command(0xc0);

	LCD_DataRefurbish1();


}
/*------------------------------------LCD单字符定位更换*/
LCD_number_Refurbish(uchar P,uchar x,uchar DD)
{
	uchar i;

	DD = DD + 0x10;

	switch (P)	
	{
		case 5 : {
			for (i = 0;i < 8;i ++)
			{
				ShowPage5[x + i] = Asc_Z[(DD * 8) + i];
			}
		}; break;
		case 6 : {
			for (i = 0;i < 8;i ++)
			{
				ShowPage6[x + i] = Asc_Z[(DD * 8) + i];
			}
		}; break;
		case 7 : {
			for (i = 0;i < 8;i ++)
			{
				ShowPage7[x + i] = Asc_Z[(DD * 8) + i];
			}
		}; break;
		case 8 : {
			for (i = 0;i < 8;i ++)
			{
				ShowPage8[x + i] = Asc_Z[(DD * 8) + i];
			}
		}; break;
		default: ; break;
	}

}



/*==========================================系统中断处理*/

/*====================================显示刷新延时*****/
Refurbish_LCD(void) interrupt 1 
{		
	TT --;
	if (TT == 0)
	{
		Instrument = 0;
		TT = 500;
	}
}

/*====================================URAT0*****/
URAT_PC(void) interrupt 4 
{		
    SFRPAGE   = UART0_PAGE;
	if (RI0 == 1)							//接收中断到
	{
		RI0 = 0;
		Command = SBUF0;
		DataCapture = 0;
	}
}

/*======================================================*/

void main ()
{
	Init_Device();

	P0 = 0xff;
	P1 = 0xff;
	P2 = 0xff;

	LCD_initialize();
	RDflash();

	REN0 = 1;
	ES0 = 1;
	EA = 1;

	TR0 = 1;
	ET0 = 1;

    SFRPAGE   = ADC0_PAGE;					//首次采样(通道1-2)作为历史值
	AD0INT = 0;
	AD0BUSY = 1;
	while (AD0INT == 0);
	ADC0_M = ADC0H;
	ADC0_M = (ADC0_M << 8) + ADC0L;

    SFRPAGE   = ADC1_PAGE;
	AD1INT = 0;
	AD1BUSY = 1;
	while (AD1INT == 0);
	ADC1_M = ADC1H;
	ADC1_M = (ADC1_M << 8) + ADC1L;

	for (N = 0;N < 20;N ++)					//获得第一个数组(通道1-2)
	{
	    SFRPAGE   = ADC0_PAGE;
		AD0INT = 0;
		AD0BUSY = 1;
		while (AD0INT == 0);
		ADC0G[N] = ADC0H;
		ADC0G[N] = (ADC0G[N] << 8) + ADC0L;

	    SFRPAGE   = ADC1_PAGE;
		AD1INT = 0;
		AD1BUSY = 1;
		while (AD1INT == 0);
		ADC1G[N] = ADC1H;
		ADC1G[N] = (ADC1G[N] << 8) + ADC1L;
	}

xxx:

/*========================主循环体======================*/


	for (N = 0;N < 20;N ++)					//去除首位(数组左移挤出首部)
	{
		ADC0G[N] = ADC0G[N + 1];
		ADC1G[N] = ADC1G[N + 1];
	}

    SFRPAGE   = ADC0_PAGE;					//增补末位(实时采样加入数组尾部)
	AD0INT = 0;
	AD0BUSY = 1;
	while (AD0INT == 0);
	ADC0G[19] = ADC0H;
	ADC0G[19] = (ADC0G[19] << 8) + ADC0L;

    SFRPAGE   = ADC1_PAGE;
	AD1INT = 0;
	AD1BUSY = 1;
	while (AD1INT == 0);
	ADC1G[19] = ADC1H;
	ADC1G[19] = (ADC1G[19] << 8) + ADC1L;

	ADC0_S = 0;
	ADC1_S = 0;

	for (N = 0;N < 20;N ++)					//新数组求和;均值组求最大最小值
	{
		ADC0_S = ADC0_S + ADC0G[N];
		ADC1_S = ADC1_S + ADC1G[N];
	}

	ADC0_S = ADC0_S + ADC0_M;				//加入历史项
	ADC1_S = ADC1_S + ADC1_M;

	ADC0_M = ADC0_S / 21;					//求滑动后的平均
	ADC1_M = ADC1_S / 21;

	if (Instrument == 0)
	{
		Instrument = 1;
		TR0 = 0;

	    SFRPAGE   = CONFIG_PAGE;

		ADC0_F = (ADC0_M * Vref) / 65536;			//转换为实际测量电压值
		ADC0_F = ((ADC0_F -1.4) * 50) + 0.0005 - 0.2;		//转换为dBm值

		ADC1_F = (ADC1_M * Vref) / 65536;
		ADC1_F = ((ADC1_F -1.4) * 50) + 0.0005 + 0.84;

		ADC0_M1 = ADC0_M2;
		ADC0_M2 = ADC0_F;
		ADC1_M1 = ADC1_M2;
		ADC1_M2 = ADC1_F;

		ADC0_MP = fabs(ADC0_M1 - ADC0_M2) + 0.0005;
		ADC1_MP = fabs(ADC1_M1 - ADC1_M2) + 0.0005;

		if (ADC0_F >= 0)
		{
			LCD_number_Refurbish(7,168,'+'-0x30);
		}
		else if (ADC0_F < 0)
		{
			LCD_number_Refurbish(7,168,'-'-0x30);
			ADC0_F = ADC0_F * -1;
		}

		FloatDec = modf(ADC0_F, ip);				//分离出浮点数小数部分
		F_Dec = FloatDec * 1000;					//取出小数部分,转换为整数
		F_Int = ADC0_F;								//取出整数部分

		Hex_Asc(F_Int);
		LCD_number_Refurbish(7,176,Bcd[4]);
		LCD_number_Refurbish(7,184,Bcd[5]);
		Hex_Asc(F_Dec);
		LCD_number_Refurbish(5,136,Bcd[3]);
		LCD_number_Refurbish(5,144,Bcd[4]);
		LCD_number_Refurbish(5,152,Bcd[5]);

		FloatDec = modf(ADC0_MP, ip);
		F_Dec = (FloatDec + 0.0005) * 1000;
		F_Int = ADC0_MP;	

		Hex_Asc(F_Int);
		LCD_number_Refurbish(7,240,Bcd[4]);
		LCD_number_Refurbish(7,248,Bcd[5]);
		Hex_Asc(F_Dec);
		LCD_number_Refurbish(5,200,Bcd[3]);
		LCD_number_Refurbish(5,208,Bcd[4]);
		LCD_number_Refurbish(5,216,Bcd[5]);

		if (ADC1_F >= 0 )
		{
			LCD_number_Refurbish(8,104,'+'-0x30);
		}
		else if (ADC1_F < 0)
		{
			LCD_number_Refurbish(8,104,'-'-0x30);
			ADC1_F = ADC1_F * -1;
		}

		FloatDec = modf(ADC1_F, ip);
		F_Dec = FloatDec * 1000;
		F_Int = ADC1_F;	

		Hex_Asc(F_Int);
		LCD_number_Refurbish(8,112,Bcd[4]);
		LCD_number_Refurbish(8,120,Bcd[5]);
		Hex_Asc(F_Dec);
		LCD_number_Refurbish(6,72,Bcd[3]);
		LCD_number_Refurbish(6,80,Bcd[4]);
		LCD_number_Refurbish(6,88,Bcd[5]);

		FloatDec = modf(ADC1_MP, ip);
		F_Dec = (FloatDec + 0.0005) * 1000;
		F_Int = ADC1_MP;	

		Hex_Asc(F_Int);
		LCD_number_Refurbish(8,176,Bcd[4]);
		LCD_number_Refurbish(8,184,Bcd[5]);
		Hex_Asc(F_Dec);
		LCD_number_Refurbish(6,136,Bcd[3]);
		LCD_number_Refurbish(6,144,Bcd[4]);
		LCD_number_Refurbish(6,152,Bcd[5]);

		LCD_DataRefurbish2();
		TR0 = 1;
	}
	else if (DataCapture == 0)
	{
		if (Command == 's')
		{
			Data_PC(ADC0_M,ADC1_M);
			Command = 0;
		}
		else if (Command == 'c')
		{
			Data_PC(ADC0_M,ADC1_M);
		}
		else if (Command == 'r')
		{
			;
		}
		else if (Command != 'w')
		{
			uchar i;

			for (i = 0;i < 16;i ++)
				HoldData[i] = 0;

			WRflash();
		}
		else if (Command == 'w')
		{
			;
		}
	}

/*======================================================*/

goto xxx;

}

⌨️ 快捷键说明

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