I connected pull up resistors at the 5v pins but surprisingly my LCD was not drawing more than 3.3V(which is the voltage at which the PIC is operating.)I don't know why this happened.
I decided to use the lcd at 3.3V then. The code is as shown below. (Many sections have been commented out.)
The LCD has been connected on PORTA(from A0-A3)
The connections for RS, EN and RW are on PORTB.
RS is connected to B5, EN to B6 and RW to B7.
I think the delays are for a sufficient duration. Kindly check if my initialization sequence is correct.
Also, I have made the circuit on a breadboard. So I could post that picture if required.
Code C - [expand] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
| #include <p32xxxx.h>
#include <plib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// DEVCFG3:
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration, allow mult reconfig
#pragma config PMDL1WAY = OFF // Peripheral Module Disable Config, allow mult reconfig
// DEVCFG2:
#pragma config FPLLODIV = DIV_2 // PLL Output Divider
#pragma config FPLLMUL = MUL_20 // PLL Multiplier
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider
// 8MHz / 2 * 20 / 2 = 40MHz
// DEVCFG1:
#pragma config FWDTEN = OFF // Watchdog Timer
#pragma config WDTPS = PS1 // Watchdog Timer Postscale
#pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
#pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
#pragma config OSCIOFNC = OFF // CLKO Enable
#pragma config POSCMOD = OFF // Primary Oscillator
#pragma config IESO = OFF // Internal/External Switch-over
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off)
#pragma config FNOSC = FRCPLL // Oscillator Selection
// DEVCFG0:
#pragma config CP = OFF // Code Protect
#pragma config BWP = ON // Boot Flash Write Protect
#pragma config PWP = OFF // Program Flash Write Protect
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
#pragma config JTAGEN = OFF // JTAG Enable
#pragma config DEBUG = OFF // Background Debugger Enable
#define SYS_FREQ 40000000uL
#define RS LATBbits.LATB5
#define EN LATBbits.LATB6
#define RW LATBbits.LATB7
#define CHECKBIT(x,b) x&(1<<b) //Checks bit status
#define SETBIT(x,b) x|=(1<<b) //Sets the particular bit
#define CLEARBIT(x,b) x&=~(1<<b) //Sets the particular bit
#define TOGGLEBIT(x,b) x^=(1<<b) //Toggles the particular bit
#define Line1 0x80
#define Line2 0xC0
int t1=0;
unsigned int i=0,j=0;
void delay(void);
void initbinary(void);
void delay1(unsigned int num)
{
for(i=0;i<num;i++)
{for(j=0;j<10000000;j++)
{Nop();}}
}
void toggle(void)
{
EN=1;
delay();
EN=0;
delay();
}
void go2line1(int position) // Function to go to a particular position
{
RS=0;
RW=0;
EN=0;
PORTA=(Line1 | position)>>4;
toggle();
PORTA=(Line1 | position);
toggle();
}
void lcd_putchar(unsigned char str) // Function to display a string on the lcd
{ RW=0;
EN=0;
PORTA=(str&0xF0);
RS=1;//To enable data mode
toggle();
delay();
PORTA=(str&0x0F);
toggle();
delay();
delay();
}
void check_busy(void)
{//checks if lcd is busy. If D7 is high the LCD is in the busy state
TRISA=0xFFFF;//setting port a as input port
RW=1;//Enabling Read Mode
RS=0;//Enabling register select for command mode
}
void init(void);
int main()
{
ANSELA=0b00000;//Enabling PORTA as digital
ANSELB=0x0000;//Enabling PORTB as digital
SYSTEMConfigPerformance(SYS_FREQ);
INTEnableSystemMultiVectoredInt();
mPORTASetPinsDigitalOut(BIT_0 | BIT_1 | BIT_2 | BIT_3 );
mPORTBSetPinsDigitalOut( BIT_5 | BIT_6 | BIT_7 | BIT_9);
OpenCoreTimer(40000000);
while(1)
{
EN=0;
RW=0;//enabling write mode
RS=0;//enabling command mode for register select
// PORTA=(0x28 & 0xF0);
// PORTA=0b11111;
j=0;
toggle();
initbinary();
// PORTA=0x0E;
// init();
// toggle();
//init();
// RW=0;EN=0;
// RS=0;
// //Initalizing CGRAM address
// PORTA=(0x80 & 0xF0)>> 4;
// toggle();
// delay();
// PORTA=(0x80 & 0x0F);
// toggle();
// delay();
// go2line1(3);
// lcd_putchar('a');
// RS=1;//To enable the data mode
////Sending character A
// PORTA=(0x45 & 0xF0);
// toggle();
// delay();
//PORTA=(0x45 & 0x0F);
//toggle();
//delay();
}
while(1)
{
Nop();
}
return;
}
//Coretimer works at frequency of 20MHz, So current delay function is set to 0.5ms
void delay(void)
{
WriteCoreTimer(0);
j=ReadCoreTimer();
while(j<10000000) j=ReadCoreTimer();
}
void init(void)
{
// TRISA=0x0000;//setting porta as an output port
// TRISB=0x0000;//setting portb as an output port
EN=0;
RW=0;//enabling read mode
RS=0;//enabling command mode for register select
PORTA=(0x28 & 0xF0);
toggle();
//delay();
PORTA=(0x28 & 0x0F);
toggle();
// delay();
PORTA=0x0E;//writing value for cursor blink on data lines
toggle();
//Enabling the LCD - Will work only when there is a H-L transition
}
void initbinary(void)
{
EN=0;
RW=0;
RS=0;
//Initializing four bit mode of operation
//Passing command 0x28 for 4 bit mode of operation
PORTA=0b00010;
toggle();
PORTA=0b01000;
toggle();
//Passing 0x0E for cursor blink
PORTA=0b01110;
toggle();
} |