Hi,
I'm trying to get the display (AMPIRE 164A, 4lines, 16symbols) to work through a
PIC18F45K20, programmed through
MCC18, but without success till now. I connected the
data line of the display to
PORTD on the PIC, the
command line to
PORTC. The power supply (to logic and backlight) is an old phone charger at 4.82V and the contrast PIN (pin#3) is set to ground.
I initialize the ports and set it to 8bit/4lines, CursorOn, BlinkOn, ClearDisplay etc. commands, but nothing seems to work. I tried using a delay of 20ms and 4ms (which are quite big btw.), and I tried to use the BusyFlag. Neither worked...
Previously I programmed a NEW Heaven Disp. with the
SPLC780D controller, through a
Rabbit5600W. I copied the library which I wrote for that and changed a couple of things, so It will work with the
PIC18F45K20.
My
main is of the following form:
/** C O N F I G U R A T I O N B I T S ******************************/
#pragma config FOSC = INTIO67
/** I N C L U D E S **************************************************/
#include "p18f45k20.h"
#include "KS0066U.h"
int i;
void main()
{
KS0066U_Init(&DL1N1F0, &D1C1B1);
KS0066U_PrintString("UoD RenewableEnergy",&L3,&I1S0);
}
For Simplicity, I post the initializations which I perform step by step:
#pragma config FOSC = INTIO67
/** I N C L U D E S **************************************************/
#include "p18f45k20.h"
#include "delays.h"
#include "KS0066U.h"
int i;
void main()
{
TRISD = 0x00;
TRISC = 0x00;
LATD = 0x00;
LATC = 0x00;
//This loop is just for testing purposes
for(i = 0;i<100;i++){
LATD = 0x3C; //Function Set (8bit,4lines)
LATCbits.LATC5 = 1;//Enable
LATCbits.LATC5 = 0;//Disable
Delay1KTCYx(5); //Delay of 5*1000 clock cycles = 20ms @ 1MHz
LATD = 0x0f;
LATCbits.LATC5 = 1;
LATCbits.LATC5 = 0;
Delay1KTCYx(50);
LATD = 0x01;
LATCbits.LATC5 = 1;
LATCbits.LATC5 = 0;
Delay1KTCYx(50);
LATD = 0x01;
LATCbits.LATC5 = 1;
LATCbits.LATC5 = 0;
Delay1KTCYx(50);
};
//KS0066U_Init(&DL1N1F0, &D1C1B1);
//KS0066U_PrintString("UoD RenewableEnergy",&L3,&I1S0);
}
_______________________________________________________________
The Library I use is as follows:
/*** BeginHeader */
#ifndef __KS0066U_LIB
#define __KS0066U_LIB
/*** EndHeader */
/* START LIBRARY DESCRIPTION ************************************************
KS0066U.LIB
*****************************************************************************
Library Developed by Lyuboslav Petrov, UoD[Renewable Energy]
under supervision of
1. Dr. Ladson Hayes
2. Dr. Stephen Reynolds
Date: 26.05.2010
Last updade: 09.06 .2010
*****************************************************************************
DESCRIPTION:
This library was created for use with the KS0066U microcontroller and the
Ampire Display AC-164A. The connections, for which the library is written are as follows:
KS0066U |Rs R/W E DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
PIC |C4 C6 C5 D7 D6 D5 D4 D3 D2 D1 D0
Usage:
#include <KS0066U.h>
main()
{
KS0066U_Init(&DL1N1F0, &D1C1B1);
KS0066U_PrintString("UoD RenewableEnergy",&L3,&I1S0);
}
SUPPORT LIBRARIES: none
//END DESCRIPTION *************************************************************/
/*** BeginHeader KS0066U_Init */
char *iter, *addr, *ems, *donoff, *cdshift, L1, L2, L3, L4, I1S1,I1S0, I0S1, I0S0, *fset;
char DL1N1F0, DL1N1F1, DL1N0F0, DL1N0F1, DL0N0F0, DL0N1F0, DL0N1F1, DL0N0F1;
char D1C1B1, D1C1B0, D1C0B1, D1C0B0, D0C0B1, D0C0B0, D0C1B1, D0C1B0;
char SC1RL1, SC1RL0, SC0RL1, SC0RL0;
void KS0066U_PortSetup();
void KS0066U_Enable();
void KS0066U_Disable();
void KS0066U_Write();
void KS0066U_Read();
void KS0066U_Clear();
void KS0066U_Return();
void KS0066U_EntryModeSet();
void KS0066U_FunctionSet();
void KS0066U_DispOnOffCtrl();
void KS0066U_CursDispShift();
void KS0066U_SetAddr();
void KS0066U_ReadBusyFlag();
void KS0066U_Default();
void KS0066U_PrintString();
void KS0066U_Init();
/*** EndHeader */
void KS0066U_PortSetup()
{
TRISD = 0x00;
TRISCbits.TRISC6 = 0;
TRISCbits.TRISC5 = 0;
TRISCbits.TRISC4 = 0;
LATD = 0x00;
LATC = 0x00;
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_PortSetup <KS0066U.LIB>
EXECUTION TIME = N/A
This function Sets the Ports for the PIC18F45K20. The ports chosen by de-
fault are DataPort[PD] and CommandPort[PC]. After initialization the ports are
set to '0'.
//END DESCRIPTION *************************************************************/
void KS0066U_Enable() // Enable
{
LATCbits.LATC5 = 1;
}
void KS0066U_Disable() // Disable
{
LATCbits.LATC5 = 0;
}
void KS0066U_Write() // Write
{
LATCbits.LATC6 = 0;
}
void KS0066U_Read() // Read
{
LATCbits.LATC6 = 1;
}
void KS0066U_ReadBusyFlag()
{
double P;
KS0066U_Read();
TRISD = 0x80;
while(LATDbits.LATD7);
KS0066U_Disable();
TRISD = 0x00;
}
/* START FUNCTION DESCRIPTION ***********************************************
SPC780D_ReadBusyFlag <KS0066U.LIB>
EXECUTION TIME = N/A
Read busy flag and address
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 1 BF a a a a a a a
When BF = 1, it indicates the system is busy now and it will not
accept any instruction until not busy (BF = 0). At the same time,
the content of Address Counter (aaaaaaa)2 is read.
//END DESCRIPTION *************************************************************/
void KS0066U_Clear() // Clear
{
LATCbits.LATC4 = 0;
LATCbits.LATC6 = 0;
LATD = 0x01;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_Clear <KS0066U.LIB>
EXECUTION TIME = 1.52ms
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 0 0 0 0 1
It clears the entire display and sets Display Data RAM Address 0
in Address Counter. PD is set to '0' after execution.
//END DESCRIPTION *************************************************************/
void KS0066U_Return() // Return home
{
LATD = 0x02;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_Return <KS0066U.LIB>
EXECUTION TIME = 1.52ms
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 0 0 0 1 X
X: Do not care (0 or 1)
It sets Display Data RAM Address 0 in Address Counter and the
display returns to its original position. The cursor or blink goes to
the most-left side of the display (to the 1st line if 2 lines are
displayed). The contents of the Display Data RAM do not
change.
//END DESCRIPTION *************************************************************/
void KS0066U_EntryModeSet(char *ems) // EntryModeSet
{
I1S1 = 0x07;
I1S0 = 0x06;
I0S1 = 0x05;
I0S0 = 0x04;
LATD = *ems;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_EntryModeSet <KS0066U.LIB>
EXECUTION TIME = 38us
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 0 0 1 I/D S
During writing and reading data, it defines cursor moving direction
and shifts the display.
I / D = 1: Increment, I / D = 0: Decrement.
S = 1: The display shifts, S = 0: The display does not shift.
//END DESCRIPTION *************************************************************/
void KS0066U_FunctionSet(char *fset) // FunctionSet
{
DL1N1F0 = 0x38;
DL1N1F1 = 0x3c;
DL1N0F0 = 0x30;
DL1N0F1 = 0x34;
DL0N0F0 = 0x20;
DL0N1F0 = 0x28;
DL0N1F1 = 0x2C;
DL0N0F1 = 0x24;
LATD = *fset;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_FunctionSet <KS0066U.LIB>
EXECUTION TIME = 38us
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 1 DL N F X X
X: Do not care (0 or 1)
DL: It sets interface data length.
DL = 1: Data transferred with 8-bit length (DB7 - 0).
DL = 0: Data transferred with 4-bit length (DB7 - 4).
It requires two times to accomplish data transferring.
N: It sets the number of the display line.
N = 0: One-line display.
N = 1: Two-line display.
F: It sets the character font.
F = 0: 5 x 8 dots character font.
F = 1: 5 x 10 dots character font.
N F No. of Display Lines Character Font Duty Factor
0 0 1 5 x 8 dots 1 / 8
0 1 1 5 x 10 dots 1 / 11
1 X 2 5 x 8 dots 1 / 16
It cannot display two lines with 5 x 10 dots character font.
DL1N1F0 = 0x38;
DL1N1F1 = 0x3c;
DL1N0F0 = 0x30;
DL1N0F1 = 0x34;
DL0N0F0 = 0x20;
DL0N1F0 = 0x28;
DL0N1F1 = 0x2C;
DL0N0F1 = 0x24;
//END DESCRIPTION *************************************************************/
void KS0066U_DispOnOffCtrl(char *donoff) // DispOnOffCtrl
{
D1C1B1 = 0x0f;
D1C1B0 = 0x0e;
D1C0B1 = 0x0d;
D1C0B0 = 0x0c;
D0C0B1 = 0x09;
D0C0B0 = 0x08;
D0C1B1 = 0x0b;
D0C1B0 = 0x0a;
LATD = *donoff;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_DispOnOffCtrl <KS0066U.LIB>
EXECUTION TIME = 38us
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 0 1 D C B
D = 1: Display on, D = 0: Display off
C = 1: Cursor on, C = 0: Cursor off
B = 1: Blinks on, B= 0: Blinks off
//END DESCRIPTION *************************************************************/
void KS0066U_CursDispShift(char *cdshift)
{
SC1RL1 = 0x1c;
SC1RL0 = 0x18;
SC0RL1 = 0x14;
SC0RL0 = 0x10;
LATD = *cdshift;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_CursDispShift <KS0066U.LIB>
EXECUTION TIME = 38us
Without changing DD RAM data, it moves cursor and shifts
display.
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 1 S/C R/L X X
S/C R/L Description Address Counter ENG HEX
0 0 Shift cursor to the left AC = AC - 1 SC1RL1 0x1c
0 1 Shift cursor to the right AC = AC + 1 SC1RL0 0x18
1 0 Shift display to the left.- AC = AC SC0RL1 0x14
Cursor follows the display- SC0RL0 0x10
shift
1 1 Shift display to the right.- AC = ACf
Cursor follows the display -
shift
//END DESCRIPTION *************************************************************/
void KS0066U_SetAddr(char *addr) // SetDispDataRamAddr
{
L1 = 0x00;
L2 = 0xC0;
L3 = 0x94;
L4 = 0xD4;
LATD = *addr;
KS0066U_Enable();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_SetAddr <KS0066U.LIB>
EXECUTION TIME = 38us
It sets Display Data RAM Address (aaaaaaa)2 to the Address
Counter..
Rs R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 a a a a a a a
Display data RAM can be read or written after this setting.
In one-line display (N = 0),
(aaaaaaa)2: (00)16 - (4F)16.
In two-line display (N = 1),
(aaaaaaa)2: (00)16 - (27)16 for the first line,
(aaaaaaa)2: (40)16 - (67)16 for the second line.
//END DESCRIPTION *************************************************************/
void KS0066U_PrintString(char *iterator,char *addr,char *ems)
{
KS0066U_SetAddr(addr);
KS0066U_EntryModeSet(ems);
while (*iterator){
LATD = *iterator;
KS0066U_Write();
KS0066U_Disable();
KS0066U_ReadBusyFlag();
iterator++;
}
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_PrintString <KS0066U.LIB>
EXECUTION TIME = SUM of execution times of seperate commands
Print String to Display
KS0066U_PrintString(&String,&LineNumber);
(e.g.)
This command is the shortcut for writing directly to the display. It accepts
a string, the RAM address and prints it to the specified address.
This example code shows it's functionality
#include <KS0066U.LIB>
main()
{
KS0066U_Init(&DL1N1F0, &D1C1B1,&I1S0);
KS0066U_PrintString("UoD RenewableEnergy",&L3);
}
//END DESCRIPTION *************************************************************/
void KS0066U_Init(char *fset, char *donoff)
{
KS0066U_PortSetup();
KS0066U_FunctionSet(fset);
KS0066U_DispOnOffCtrl(donoff);
KS0066U_Clear();
KS0066U_Clear();//For some reason it is necessary to repeat the clear command
}
/* START FUNCTION DESCRIPTION ***********************************************
KS0066U_Init <KS0066U.LIB>
KS0066U_Init( char *fset , char *donoff);
For More information regarding this function, see:
1. KS0066U_PortSetup()
2. KS0066U_FunctionSet(char *fset)
2. KS0066U_DispOnOffCtrl(char *donoff);
KS0066U_Init() will initialize the NewHeaven Display model 0420DZ FL YBW 3V3.
The initialization process includes the following:
1. Set Ports - Setting the ports of the Rabbit RCM5600W. In this library
the ports used are Parallel Port A[0:7] and Parallel Port D[0:2].
In case the user wants to use another port, he/she must change the
write port addresses corespondingly. In example, if PPortA is to be
changed to PPE, then all WrPortI()commands need to be reconfigured:
(e.g. WrPortI(PADR, &PADRShadow, 0x06) - Current Setup)
( WrPortI(PEDR, &PEDRShadow, 0x06) - Desired Setup)
!Note! DataDirection Registers need to be changed in the primary
setup as well as the mentioned Data Registers. For more info on how to
change DDR's, check out the IOconfig executable available with
Dynamic C 10.60 or your Rabbit CPU manual.
2. FunctionSet (see help)
3. DispOnOffCtrl (see help)
Future Depelopment Goals:
1. User to define the precision (8bit to 12 bit)
2. User to define the output time period
3. User to define SPI or 3Wire interface
- SubLibraries for specific interface
To use this function, simply call the library as follows:
#include <KS0066U.h>
main()
{
KS0066U_Init(&DL1N1F0, &D1C1B1);
KS0066U_PrintString("UoD RenewableEnergy",&L3,&I1S0);
}
For Further Function Details See:
KS0066U_PortSetup();
KS0066U_Enable();
KS0066U_Disable();
KS0066U_Write();
KS0066U_Clear();
KS0066U_Return();
KS0066U_EntryModeSet();
KS0066U_FunctionSet()
KS0066U_DispOnOffCtrl();
KS0066U_AddrIncr();
KS0066U_SetLine1();
KS0066U_SetLine2();
KS0066U_SetLine3();
KS0066U_SetLine4();
KS0066U_Init();
//END DESCRIPTION*************************************************************/
/*** BeginHeader */
#endif
/*** EndHeader */
My problem solution guesses are:
1. Incorrect power supply(too high or too low)
2. Bad Connections (soldering??)
3. PIC port initializations
Thank you for your help! I am really desperate here on this perhaps trivial problem. I am attaching the library which I try to implement below.