?? lcd.c
字號:
/*
-2/10/2006: Petre M.
-this file contains library routines that manage the LCD of the reference design
*/
#include "ioADE7169F16.h"
#include "extern_declarations.h"
#include "EEPROM_locations.h"
//this function initializes the LCD driver
void Setup_LCD(void)
{
//bit3 of PERIPH=1: LCD enabled in Battery Mode (PSM1)
PERIPH_bit.REF_BATT_EN = 1;
/*1=LCD enabled
0=LCD data registers are not reset to 0
0=blink mode disabled
0=LCD is disabled or enabled in PSM2 by LCDEN bit
0=LCD clock is 2048KHz
1=Bias Mode is 1/3
11=Multiplex level is 4x
*/
LCDCON = 0x87;
/*00=Blink rate is controlled by software
00=Blink rate is 1Hz
0010=LCD Frame Rate is 2=0010
*/
LCDCLK = 0x02;
#ifdef GOWORLD_LCD
#ifdef LCD_5V
/*0=reserved
0=external resistor ladder disabled. Charge Pump enabled
101100=Bias Level set to 5V
*/
LCDCONX = 0x2c;
#else
/*0=reserved
0=external resistor ladder disabled. Charge Pump enabled
010010=Bias Level set to 3.3V
*/
LCDCONX = 0x12;
#endif
#endif
#ifdef OCULAR_LCD
/*0=reserved
0=external resistor ladder disabled. Charge Pump enabled
101100=Bias Level set to 5V
*/
LCDCONX = 0x2c;
#endif
/*0000=reserved
1=FP19 used for LCD
1=FP18 used for LCD
1=FP17 used for LCD
0=FP16 used as GPIO
*/
LCDSEGE2 = 0x0e;
/*0=FP25 used as GPIO=P1.2=CASE_OPEN_HI
0=FP24 used as GPIO=P1.3=SCROLL UP
1=FP23 used for LCD
1=FP22 used for LCD
1=FP21 used for LCD
1=FP20 used for LCD
00=No timeout delay before powerdown
*/
LCDSEGE = 0x3c;
LCDCONY_bit.INV_LVL = 0; //frames are not inverted
return;
}
//this function copies the LCD_buffer[15] into LCD Data Memory.
//In this manner, the latest update of LCD_buffer is visualized on the display
void Display_to_LCD(void)
{
LCDCONY_bit.REFRESH = 1; //LCD data memory is updated, so bit0=1
#ifdef GOWORLD_LCD
char i, a;
char __idata *iram_ptr;
iram_ptr = &LCD_buffer[0];
a = 0x8e;
for (i=0; i<15; i++) {
LCDDAT = *iram_ptr;
LCDPTR = a;
iram_ptr++;
a--;
}
#endif
#ifdef OCULAR_LCD
LCDDAT = LCD_buffer[0];
LCDPTR = 0x8e;
LCDDAT = LCD_buffer[1];
LCDPTR = 0x8e-0x01;
LCDDAT = LCD_buffer[2];
LCDPTR = 0x8e-0x02;
LCDDAT = LCD_buffer[11];
LCDPTR = 0x8e-0x03;
LCDDAT = LCD_buffer[4];
LCDPTR = 0x8e-0x04;
LCDDAT = LCD_buffer[10];
LCDPTR = 0x8e-0x05;
LCDDAT = LCD_buffer[6];
LCDPTR = 0x8e-0x06;
LCDDAT = LCD_buffer[7];
LCDPTR = 0x8e-0x07;
LCDDAT = LCD_buffer[8]>>4;
LCDPTR = 0x8e-0x08;
LCDDAT = (LCD_buffer[8]<<4) | (LCD_buffer[9]>>4);
LCDPTR = 0x8e-0x09;
LCDDAT = (LCD_buffer[9]<<4) | (LCD_buffer[12]>>4);
LCDPTR = 0x8e-0x0a;
LCDDAT = (LCD_buffer[12]<<4) | (LCD_buffer[13]>>4);
LCDPTR = 0x8e-0x0b;
LCDDAT = (LCD_buffer[13]<<4) | (LCD_buffer[14]>>4);
LCDPTR = 0x8e-0x0c;
LCDDAT = (LCD_buffer[14]<<4);
LCDPTR = 0x8e-0x0d;
LCDDAT = LCD_buffer[3];
LCDPTR = 0x8e-0x0e;
#endif
LCDCONY_bit.REFRESH = 0; //updating LCD data memory has ended, so bit0=0
//clear the status flag
Clear_flag(NBit1, &Command_Status[0]);
return;
}
//this function clears the icons of the LCD_buffer except for Battery, Phone and T icons
//Bit2 and Bit0 in LCD_buffer[4] and Bit7 in LCD_buffer[13] for GOWORLD,
//Bit7 in LCD_buffer[8] and Bit1 in LCD_buffer[4] for OCULAR
//Clear also Digits 7,6,...,1
void Clear_LCD_Icons_Points(void) {
#ifdef GOWORLD_LCD
LCD_buffer[3] = LCD_buffer[3] & NBit7;
LCD_buffer[4] = LCD_buffer[4] & NBit1;
LCD_buffer[5] = LCD_buffer[5] & NBit7;
LCD_buffer[6] = LCD_buffer[6] & NBit6 & NBit5 & NBit4;
LCD_buffer[7] = LCD_buffer[7] & NBit6 & NBit5 & NBit4 & NBit3 & NBit2 & NBit1 & NBit0;
LCD_buffer[8] = 0x00;//=LCD_buffer[8] & NBit7;
LCD_buffer[9] = 0x00;//=LCD_buffer[9] & NBit7;
LCD_buffer[10]= 0x00;//= LCD_buffer[10]& NBit7;
LCD_buffer[11]= 0x00;//= LCD_buffer[11]& NBit7;
LCD_buffer[12]= 0x00;//= LCD_buffer[12]& NBit7;
LCD_buffer[13]= LCD_buffer[13] & Bit7;
LCD_buffer[14]= 0x00;//= LCD_buffer[14]& NBit7;
#endif
#ifdef OCULAR_LCD
LCD_buffer[4] = LCD_buffer[4] & NBit7 & NBit6 & NBit5 & NBit4 & NBit2 & NBit0;
LCD_buffer[6] = LCD_buffer[6] & NBit7 & NBit6 & NBit5 & NBit4;
LCD_buffer[8] = LCD_buffer[8] & Bit7;
LCD_buffer[9] = 0x00;//= LCD_buffer[9] & NBit7;
LCD_buffer[10]= 0x00;//= LCD_buffer[10]& NBit7;
LCD_buffer[11]= 0x00;//= LCD_buffer[11]& NBit7;
LCD_buffer[12]= 0x00;//= LCD_buffer[12]& NBit7;
LCD_buffer[13]= 0x00;//= LCD_buffer[13]& NBit7;
LCD_buffer[14]= 0x00;//= LCD_buffer[14]& NBit7;
#endif
return;
}
//this function takes digits computed in the buffer Temporary1[8] and
//sets accordingly bits of LCD_buffer
//The user must tell how many less significant digits would like to display
//All numbers are displayed with that number of LS digits if the number's
//most significant digits allow
void Manage_Numbers(char Nr_Fract_Digits) {
char i,a, b, c;
char nr_MS_digits;
char __idata *iram_ptr;
char __code const *iram_ptr2;
char __idata *iram_ptr3;
char Flag;
signed char Nr_LS_digits;
//first, the number of most significant digits is computed
nr_MS_digits = 0;
//Flag is set when a 0 digit is found. We don't want to
//visualize 0s that are at the left of non 0 integers
Flag = 0;
iram_ptr = &Temporary1[Nr_Fract_Digits];
for (i=0;i<7-Nr_Fract_Digits;i++) {
a = *iram_ptr;
iram_ptr++;
//if a!=0: If Flag=1 (i.e. this non 0 integer was preceeded by a 0, then
//count that 0 as part of MS digits and then clear Flag. Then increase
//anyway nr_MS_digits because a is not 0
if (a!=0) {
if (Flag==1) {
nr_MS_digits++;
Flag = 0;
}
nr_MS_digits++;
}
//if a=0 and Flag=0, then set Flag=1 to signal a 0 has been encountered.
//Do not increase nr_MS_digits because we do not know if a non 0 integer
//will not be found next iteration
else if (Flag==0) {
Flag = 1;
}
}
//now we arrived at the most significant digit of the number.
//If a!=0, then we increment nr_MS_digits.
//If a=0xa, then we have a minus sign to visualize and we write 0x0a immediately
//after the most significant digit
a = *iram_ptr;
if (a!=0) {
if (a==0xa) {
Temporary1[Nr_Fract_Digits+nr_MS_digits] = 0x0a;
}
nr_MS_digits++;
}
//if the number does not have integer digits, then increase nr_MS_digits by 1
//in order to visualize the number as 0.xxx
if (nr_MS_digits==0) {
nr_MS_digits++;
}
//At this point, we know how many MS digits has to be visualized. We need
//to compute how many LS digits can be visualized because the display
//has only LCD_digits_number digits
Nr_LS_digits = LCD_digits_number - nr_MS_digits;
//If Nr_LS_digits1<0, then we visualize error (i.e. all digits are "minus" signs")
if (Nr_LS_digits<0) {
for(i=0;i<8;i++) {
Temporary1[i] = 0x0f;
}
Nr_LS_digits = Nr_Fract_Digits;
}
//If Nr_LS_digits1>Nr_LS_digits, then use Nr_LS_digits.
//Otherwise, use Nr_LS_digits1 as was computed above
if (Nr_LS_digits>Nr_Fract_Digits) {
Nr_LS_digits = Nr_Fract_Digits;
}
//Now, we set bytes in LCD_buffer accordingly
//Start screening Temporary1 buffer from an address determined by Nr_Fract_Digits-Nr_LS_digits
iram_ptr = &Temporary1[Nr_Fract_Digits-Nr_LS_digits];
iram_ptr2 = &Digit_Table[0];
iram_ptr3 = &LCD_buffer[8];
for(i=0;i<(Nr_LS_digits+nr_MS_digits);i++) {
b = *iram_ptr;
c = *(iram_ptr2+b);
*iram_ptr3 = c;
iram_ptr++;
iram_ptr3++;
}
//now we need to place the dot after MS digits
//P3 is located at LCD_buffer[12]
//P4 is located at LCD_buffer[11]
//P5 is located at LCD_buffer[10]
//P6 is located at LCD_buffer[9]
//if digit_cntr=0, then we don't need to put a dot
if (Nr_LS_digits!=0) {
iram_ptr3 = &LCD_buffer[9]+Nr_LS_digits-1;
(*iram_ptr3) = (*iram_ptr3) | 0x80;
}
return;
}
void Display_Time_Date(char __idata *iram_ptr1){
char a, b, i;
char __idata *iram_ptr2;
char __code const *iram_ptr3;
iram_ptr2 = &LCD_buffer[8];
iram_ptr3 = &Digit_Table[0];
for (i=0;i<3;i++) {
//a=seconds, minutes, hours
a = *iram_ptr1;
iram_ptr1++;
//b=the units of the seconds
b=a%10;
*iram_ptr2 = *(iram_ptr3+b);
iram_ptr2++;
//b=the decimals of the seconds
b=a/10;
*iram_ptr2 = *(iram_ptr3+b);
iram_ptr2++;
}
return;
}
//this function computes the digits and sets the icons that
//are used to visualize all the measurements
void Manage_Display(void) {
//display the active energy
//this is the declaration of a pointer to a function.
void (* LCD_func_ptr)(void);
//set the flag showing an LCD command is in progress
Command_Status[0] = Command_Status[0] | Bit1;
//clear the icons and points that are managed for these visualizations:
//This means all except for Battery and Phone icons
Clear_LCD_Icons_Points();
//load into the function pointer a function from Table_LCD
//The same function is executed every 8 passages through Manage_Display function
LCD_func_ptr = (void (*) (void))Table_LCD[LCD_Command[0]>>3];
//visualize one quantity
(*LCD_func_ptr)();
//visualize LOGO
LCD_buffer[14] = LCD_buffer[14] | Bit7;
return;
}
//this function visualizes the Active Energy
void Active_Energy_Display(void) {
//if we are in PSM1 mode, then we need to read the energy from EEPROM
if (!(PERIPH_bit.VSWSOURCE)) {
//read Active Energy from EEPROM
Active_Energy_read();
}
Temporary[3] = Active_Energy.B4;
Temporary[2] = Active_Energy.B3;
Temporary[1] = Active_Energy.B2;
Temporary[0] = Active_Energy.B1;
asm("MOV R1, #Temporary+3");
asm("MOV R0, #Temporary1+7");
Comp_Nibbles2();
Manage_Numbers(Fract_Digits_2);
//set the right icons in LCD_buffer
//visualize K, X1, X2, X3, h and Logo
#ifdef GOWORLD_LCD
LCD_buffer[7] = LCD_buffer[7] | Bit6 | Bit3 | Bit2 | Bit1 | Bit0;
#endif
#ifdef OCULAR_LCD
LCD_buffer[6] = LCD_buffer[6] | Bit7 | Bit6 | Bit5 | Bit4;
LCD_buffer[4] = LCD_buffer[4] | Bit6;
#endif
return;
}
//this function reads Irms ratio from EEPROM
void Irms_threshold_read(void) {
Tx_CTRL_byte(Nr_Bytes_2, I_1A_threshold_val,(unsigned char __idata *)&I_1A_threshold);
return;
}
//this function reads Vrms ratio from EEPROM
void Vrms_threshold_read(void) {
Tx_CTRL_byte(Nr_Bytes_2, V_1V_threshold_val,(unsigned char __idata *)&V_1V_threshold);
return;
}
//This function may display any 24 bits number that is given in
//bits in Temporary[8] with LSB written into Temporary[0]
//unit_ratio=10^x*2^16/Threshold
// -where: x=number of digits after the fractional dot that we want to display
// Threshold is the number of bits that correspond to 1 unit.
// -For Irms, this is the number of bits that correspond to 1Amp
void Display_Number(char Nr_Fract_Digits, unsigned int unit_ratio) {
unsigned int __idata *iram_ptr;
iram_ptr = (unsigned int __idata *)&Temporary[3];
*iram_ptr = unit_ratio;
//multiply Temporary[2-0] by Temporary[4-3] and put the result in Temporary[4-0]
mult24x16();
//take the most significant 24 bits of the result from
//Temporary1[2]and move them in Temporary[0]
Temporary[0] = Temporary1[2];
Temporary[1] = Temporary1[3];
Temporary[2] = Temporary1[4];
Temporary[3] = 0x0;
Bin2bcd();
Manage_Numbers(Nr_Fract_Digits);
return;
}
//this function visualizes Irms with 3 fractional digits
void IRMS_Display(void) {
//if we are in PSM1 mode, then we need to read the ratio from EEPROM
if (!(PERIPH_bit.VSWSOURCE)) {
Irms_threshold_read();
}
Temporary[3] = 0x0;
Temporary[2] = IRMSH;
Temporary[1] = IRMSM;
Temporary[0] = IRMSL;
Display_Number(Fract_Digits_3, I_1A_threshold);
//set the right icons in LCD_buffer
//visualize Irms Icons, Amps and Logo
#ifdef GOWORLD_LCD
LCD_buffer[6] = LCD_buffer[6] | Bit6 | Bit5;
LCD_buffer[7] = LCD_buffer[7] | Bit4 | Bit0;
#endif
#ifdef OCULAR_LCD
LCD_buffer[6] = LCD_buffer[6] | Bit5 | Bit4;
#endif
return;
}
//this function visualizes Vrms with 2 fractional digits
void VRMS_Display(void) {
//if we are in PSM1 mode, then we need to read the ratio from EEPROM
if (!(PERIPH_bit.VSWSOURCE)) {
Vrms_threshold_read();
}
Temporary[3] = 0x0;
Temporary[2] = VRMSH;
Temporary[1] = VRMSM;
Temporary[0] = VRMSL;
Display_Number(Fract_Digits_2, V_1V_threshold);
//set the right icons in LCD_buffer
//visualize Vrms Icons, Volts and Logo
#ifdef GOWORLD_LCD
LCD_buffer[6] = LCD_buffer[6] | Bit6 | Bit4;
LCD_buffer[7] = LCD_buffer[7] | Bit2;
#endif
#ifdef OCULAR_LCD
LCD_buffer[6] = LCD_buffer[6] | Bit6;
#endif
return;
}
//this function computes the digits of the current time and stores them into LCD_buffer
void Manage_Time(void) {
//turn OFF Digit1
LCD_buffer[14]= LCD_buffer[14]& 0x80;
Store_time(&Temporary[0]);
Display_Time_Date(&Temporary[1]);
//blink P1, P3, P2, P5 every 0.5sec
//Because the LCD Points are erased every time Manage_Display() is called,
//here we need only to turn them ON
#ifdef GOWORLD_LCD
if (HTHSEC < 64) {
LCD_buffer[4] = LCD_buffer[4] | Bit1;
LCD_buffer[12]= LCD_buffer[12]| Bit7;
LCD_buffer[8] = LCD_buffer[8] | Bit7;
LCD_buffer[10]= LCD_buffer[10]| Bit7;
}
#endif
#ifdef OCULAR_LCD
if (HTHSEC < 64) {
LCD_buffer[13]= LCD_buffer[13]| Bit7;
LCD_buffer[12]= LCD_buffer[12]| Bit7;
LCD_buffer[4] = LCD_buffer[4] | Bit0;
LCD_buffer[10]= LCD_buffer[10]| Bit7;
}
#endif
return;
}
//this function visualizes the Date
void Date_Display(void) {
//display Current Date
//if we are in PSM1 mode, then we need to read the Date from EEPROM
if (!(PERIPH_bit.VSWSOURCE)) {
//The calendar is read from EEPROM
Calendar_read();
}
//turn OFF Digit1 because we do not display it at all
LCD_buffer[14]= LCD_buffer[14]& 0x80;
Display_Time_Date(&Date.Year);
//turn on P3, P5
LCD_buffer[12]= LCD_buffer[12]| 0x80;
LCD_buffer[10]= LCD_buffer[10]| 0x80;
return;
}
//this function increments LCD_Command[0] in order to change
//what is visualized on the display
void Decide_LCD_command(void) {
LCD_Command[0] = LCD_Command[0] +1;
if (LCD_Command[0]>0x27)
LCD_Command[0]=0;
return;
}
//this function sets the LCD to blink with LCDCON bits BLKFREQ
void Blink_LCD(char BLKFREQ) {
LCDCON_bit.BLINKEN=1;//blink mode enabled
//BLKMOD1(Bit7)=1, BLKMOD0(Bit6)=1
LCDCLK = LCDCLK | ((0x0c+BLKFREQ)<<4);
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -