?? opm-main.#3
字號:
/*****************************************************************
應 用:光功率計(LCD版) 作 者:姚虹
文 件 名:OPM-LCD.c 編譯系統(tǒng):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的臨時存儲器扇區(qū)
pread = 0x0000; //初始化CODE讀指針
for (i = 0;i < 16;i ++)
HoldData[i] = * pread ++;
PSCTL = 0x00;
}
/*------------------------------------通訊數據發(fā)送*/
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(4);
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;
}
}
/*==========================================系統(tǒng)中斷處理*/
/*====================================顯示刷新延時*****/
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:
/*========================主循環(huán)體======================*/
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;
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 + -