Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] LCD interface with PIC on different PORTbits

Status
Not open for further replies.

pkhow

Newbie level 2
Joined
Jul 28, 2016
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
17
Can any one help with some code or function to interface a PIC with 4x20 LCD from different Port Bits that most functions use. I find in 4bit mode they use the UPPER Nybble or the Lower .. I need to use bit1,2,3,4 so need to shift all 4 x bits up one bit. I have tried different code to get the correct shift and masking but have had no success and can not get it to work. I am hoping someone can help or has a function where you can select different PORTbits, I would appreciate any help:-(
 

Code:
void lcd_wr(unsigned char x){
       PORTB &= 0b11100001;
       x << = 1;
       x &= 0b00011110;
       PORTB |= x;
}

or

Code:
void lcd_wr(unsigned char x){
       PORTBbits.RB1 = (x & 1)? 1 : 0;
       PORTBbits.RB2 = (x & 2)? 1 : 0;
       PORTBbits.RB3 = (x & 4)? 1 : 0;
       PORTBbits.RB4 = (x & 8)? 1 : 0;
}

The second function has lesser interference with the other pins of PORTB and thus is more hardware independent.
 
  • Like
Reactions: pkhow

    pkhow

    Points: 2
    Helpful Answer Positive Rating
Try this.

Change sbit defines (mikroC) with #define for C18, Hi-Tech-C , CCS C and XC Compilers. Change LATxy_bit (mikroC PRO PIC) with LATxbits.LATxy for C18, Hi-Tech-C and XC Compilers.


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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#define PIC
//#define AVR
 
#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a 
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing 
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing 
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing 
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing 
                                         //display data RAM
 
#define EN_DELAY 300
#define LCD_STROBE {LCD_EN = 1; Delay_us(EN_DELAY); LCD_EN = 0; Delay_us(EN_DELAY);};
 
#ifdef PIC
sbit LCD_RS at LATB0_bit;
sbit LCD_EN at LATB2_bit;
sbit LCD_D4 at LATB4_bit;
sbit LCD_D5 at LATB3_bit;
sbit LCD_D6 at LATB7_bit;
sbit LCD_D7 at LATB1_bit;
 
sbit LCD_RS_Direction TRISB0_bit;
sbit LCD_EN_Direction TRISB2_bit;
sbit LCD_D4_Direction TRISB4_bit;
sbit LCD_D5_Direction TRISB3_bit;
sbit LCD_D6_Direction TRISB7_bit;
sbit LCD_D7_Direction TRISB1_bit;
#endif
 
#ifdef AVR
sbit LCD_RS at PORTB0_bit;
sbit LCD_EN at PORTB2_bit;
sbit LCD_D4 at PORTB4_bit;
sbit LCD_D5 at PORTB3_bit;
sbit LCD_D6 at PORTB7_bit;
sbit LCD_D7 at PORTB1_bit;
 
sbit LCD_RS_Direction DDB0_bit;
sbit LCD_EN_Direction DDB2_bit;
sbit LCD_D4_Direction DDB4_bit;
sbit LCD_D5_Direction DDB3_bit;
sbit LCD_D6_Direction DDB7_bit;
sbit LCD_D7_Direction DDB1_bit;
#endif
 
void LCD_Cmd(char out_char) {
 
    LCD_RS = 0;
 
    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE
    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
 
    if(out_char == 0x01)Delay_ms(2);
}
 
void LCD_Chr(char row, char column, char out_char) {
 
    switch(row){
 
        case 1:
        LCD_Cmd(0x80 + (column - 1));
        break;
        case 2:
        LCD_Cmd(0xC0 + (column - 1));
        break;
        case 3:
        LCD_Cmd(0x94 + (column - 1));
        break;
        case 4:
        LCD_Cmd(0xD4 + (column - 1));
        break;
    }
 
    LCD_RS = 1;
 
    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE
 
    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;    
    LCD_STROBE
}
 
void LCD_Chr_Cp(char out_char) {
 
    LCD_RS = 1;
 
    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE
 
    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;    
    LCD_STROBE
}
 
void LCD_Init() {
 
    Delay_ms(200);
 
    #ifdef PIC
    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;
    #endif
 
    #ifdef AVR
    LCD_RS_Direction = 1;
    LCD_EN_Direction = 1;
    LCD_D4_Direction = 1;
    LCD_D5_Direction = 1;
    LCD_D6_Direction = 1;
    LCD_D7_Direction = 1;
    #endif
 
    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;    
    
    Delay_ms(30);
 
    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;
 
    LCD_STROBE
 
    Delay_ms(30);
 
    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;
 
    LCD_STROBE
 
    Delay_ms(30);
 
    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;
 
    LCD_STROBE
 
    Delay_ms(30);
 
    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;
 
    LCD_STROBE
 
    Delay_ms(30);
 
    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}
 
void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}
 
void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}
 
void main() {
 
    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);
    LCD_Out(1,1,"LCD 20X4");    
    LCD_Out(2,1,"MCU ?");
    LCD_Out(3,1,"PIC Or AVR ?");
    LCD_Out(4,1,"Working For You ?");
 
    while(1) {
 
    }
}

 
  • Like
Reactions: pkhow

    pkhow

    Points: 2
    Helpful Answer Positive Rating
Please be careful with the 2nd code example that @xenos has posted in that it is vulnerable to the RMW problem.
You don't say what MCU you are using but if it has LAT registers then simply substitute the LAT for the PORT i that code and it will be OK.
If the MCU does not have LAY registers then you are better off using the first code example.
Susan
 

The MCU I am using is a PIC18F65K22. Thanks heaps for your help as I've been able to get it to work:razz:
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top