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] unexpected problem about resetting pic 16f877a

Status
Not open for further replies.

MUKESH.K.S

Full Member level 1
Full Member level 1
Joined
Jan 31, 2014
Messages
98
Helped
14
Reputation
28
Reaction score
13
Trophy points
1,288
Location
KERALA
Visit site
Activity points
1,891
I am here with an very unexpected problem with 16f877a . In my circuit i used ports d,a& e as output port and ports d &c as output port. I have an 16*2 lcd display in my circuit. When i power the circuit the display works finely ie, it displays what i want. But the problem is pic doesn't senses any key press.
i used 10k and .1uf for the reset circuit . Then i removed the capacitor from the reset circuit and manually resetted the uc by connecting mclr to ground. After repeating this steps many times ,the uc starts reading the key press. It woks fine only after i manually resetting the uc several times .
What is the problem ? Please help me ....my code for setting the ports & circuit is given below


ADCON1=0X0F;
TRISD=0X00;
TRISA=0X00;
TRISB=0XFF;
TRISC=0XfF;
TRISE=0X00;
PORTE=0X02;
 

Attachments

  • password.pdf
    24.9 KB · Views: 101

There is some difference in 877 and 877A. You mention that you are using 877A chip but your circuit shows 877 chip. Confirm the chip. Your Keypad circuit is wrong. Google for 4X4 or 4X3 Keypad. If you are using 4X3 or 3X4 (12 Keys keypad) then you need only one PORT for the keypad interface (using digital IO). If you use ADC for keypad then you need only one ADC pin to interface Keypad.

Zip and post the Proteus file.



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
//ADCON1 = 0x8E;    //using ADC AN0 for Keypad
//TRISA = 0x01;
ADCON1 = 0X87;  //Using digital IO for Keypad (PORTB)
TRISA = 0x00;
PORTA = 0x00;
TRISB = 0xFF;
PORTB = 0x00;
TRISC = 0x0F;
PORTC = 0x00;
TRISD = 0x00;
PORTD = 0x00;
TRISE = 0x00;
PORTE = 0x00;

 

Attachments

  • scheme_keypad4x4 (1).gif
    scheme_keypad4x4 (1).gif
    57.8 KB · Views: 120
  • scheme_keypad4x4.gif
    scheme_keypad4x4.gif
    66.1 KB · Views: 112
Hi,

As Milan says there are more efficient ways to use a keypad.


Assume the design is one you have found some where ? - its just using one port pin for each key so providing the program code is correct there is no reason it should not work.

Like the LCD its using 11 ports to control it, whereas with some more efficient code you can use just 7.

Would be better if you posted the whole program code so we can see what happening

Are you building on a breadboard ?
 

Two more things. If WDT is enabled then it wil be the reason for MCU resetting.

One

wp100 is right. You switch(s) connections are right. I didn't check the switch(s) circuits carefully. You are using just a simple button circuit which keeps the port pin 1 all the time and goes 0 on key press. A better way is to use 4X3 keypad circuit using digital IO or ADC which will simplify your switch(s) input circuit and its related code.

Two

RE0 is driving an LED and Transistor. remove the LED circuit and connect LED across relay coil.
 
Last edited:

wp100 is right again. I had made a typo (0x86 ----> 0x87). I had calculated these values for ADCON1 to use PORTA as digital IO

0x0F
0x06
0x8F
0x86

and

0x8E or 0x0E if AN0 is used for ADC keypad.
 
Thanks in advance for the reply..... here is my whole project folder . my project is password lock
( password is 4104)

- - - Updated - - -

Thanks for the replies. I changed ADCON1 reg value as you mentioned, but the problem still there. The micro controller works fine after resetting it several times manually. I am also thinking about the matrix keyboard. But my doubt is that why i cant use all the ports of uc?
 

Attachments

  • New folder.rar
    101.4 KB · Views: 106

One problem I see is in KEY() function's switch() { } statement, break; is missing for all cases. Finding more bugs...

Edit:

Use this code to display LCD test


Code C - [expand]
1
2
3
4
5
6
void LCD_STRING(volatile unsigned char *temp1)
{
    while(*temp1)LCD_DATA(*temp1++);
}
 
LCD_STRING("LOCKED");



You should use something like this to check which key is pressed according to your key(s) circuit. Add debounce delay.


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
if(!(PORTC & 0x03)) {
 
    if(PORTB = 0x01) {
 
    }
    else if(PORTB = 0x01) {
 
    }
    else if(PORTB = 0x02) {
 
    }
    else if(PORTB = 0x04) {
 
    }
    else if(PORTB = 0x08) {
 
    }
    else if(PORTB = 0x10) {
 
    }
    else if(PORTB = 0x20) {
 
    }
    else if(PORTB = 0x40) {
 
    }
    else if(PORTB = 0x80) {
 
    }
 
}
else if(!PORTB) {
    if((PORTC & 0x03) == 0x01) {
 
    }
    else if((PORTC & 0x03) == 0x02) {
 
    }   
}

 
Last edited:
Explain how your system has to work. The code can be written in a better way.


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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#include <htc.h>
 
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 20000000
#endif
 
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & BOREN_OFF &
LVP_OFF & WRT_OFF & DEBUG_OFF & CPD_OFF & CP_OFF);
 
#define LEN_PASSWORD 4
 
char NUMBER[LEN_PASSWORD];
unsigned int PRESS = 0, i = 0;
bit KEYSTAT = 0, LOCK = 0;
 
void LCD_COMMAND(char cmd);
void LCD_DATA(char dat);
void LCD_STRING(char *str);
void KEY(char);
char ASCII(char);
void INITIAL(void);
void SETKEYSTAT();
 
void SETKEYSTAT() {
        KEYSTAT = 1;
}
 
void main(void)
{
    ADCON1 = 0X0F;
    CMCON = 0x07;
    CVRCON = 0x00;
    
    TRISA = 0x00;
    TRISB = 0xFF;
    TRISC = 0x0F;
    TRISD = 0x00;
    TRISE = 0x00;
 
    PORTE = 0x02;
 
    LCD_COMMAND(0X38);
    LCD_COMMAND(0X0C);
    LCD_COMMAND(0X01);
    INITIAL();
 
    while(1)
    {
 
        if(!(PORTC & 0x03)) {
            __delay_ms(50);
        
            switch(PORTB) {
                case(0x01): {
                        while(PORTB == 0x01);
                        PRESS++;
                        KEY(0X01);
                        SETKEYSTAT();
                        break;
                }
                case(0x02): {
                        while(PORTB == 0x02);
                        PRESS++;
                        KEY(0X02);
                        SETKEYSTAT();
                        break;
                }
                case(0x04): {
                        while(PORTB == 0x04);
                        PRESS++;
                        KEY(0X03);
                        SETKEYSTAT();
                        break;      
                }
                case(0x08): {
                        while(PORTB == 0x08);
                        PRESS++;
                        KEY(0X04);
                        SETKEYSTAT();
                        break;      
                }
                case(0x10): {
                        while(PORTB == 0x10);
                        PRESS++;
                        KEY(0X05);
                        SETKEYSTAT();
                        break;      
                }
                case(0x20): {
                        while(PORTB == 0x20);
                        PRESS++;
                        KEY(0X06);
                        SETKEYSTAT();
                        break;      
                }
                case(0x40): {
                        while(PORTB == 0x40);
                        PRESS++;
                        KEY(0X07);
                        SETKEYSTAT();
                        break;      
                }
                case(0x80): {
                        while(PORTB == 0x80);
                        PRESS++;
                        KEY(0X08);
                        SETKEYSTAT();
                        break;      
                }               
            };
        
        }
        else if(!PORTB) {
            __delay_ms(50);
        
            switch(PORTC & 0x03) {
                case(0x01): {
                        while(PORTB == 0x01);
                        PRESS++;
                        KEY(0X09);
                        SETKEYSTAT();
                        break;
                }
                case(0x02): {
                        while(PORTB == 0x02);
                        PRESS++;
                        KEY(0X00);
                        SETKEYSTAT();
                        break;
                }               
            };  
        }       
 
        if(KEYSTAT)
        {
            if(PRESS == 1)
            {
                LCD_COMMAND(0XC0);
                LCD_DATA('*');
            }
    
            if(PRESS == 2)
            {
                LCD_COMMAND(0XC1);
                LCD_DATA('*');      
            }
    
            if(PRESS == 3)
            {
                LCD_COMMAND(0XC2);
                LCD_DATA('*');
            }
    
            if(PRESS == 4)
            {
                LCD_COMMAND(0XC3);
                LCD_DATA('*');      
            }
        }
 
        if((PORTC & 0x04) == 0x04)
        {
            while((PORTC & 0x04) == 0x04);
    
            if((NUMBER[0] == 0X04) && (NUMBER[1] == 0X01) && (NUMBER[2] == 0X00) && (NUMBER[3] == 0X04))
            {
                if(LOCK == 0)
                {                   
                    LCD_COMMAND(0X80); 
                    LCD_STRING("LOCKED");
                    PORTE = 0X01;
                    __delay_ms(2000);
                    PRESS = 0;
                    LOCK = 1;
                    INITIAL();
                }
                else
                {                    
                    LCD_COMMAND(0X80); 
                    LCD_STRING("UNLOCKED");
                    PORTE = 0X02;
                    __delay_ms(2000);
                    PRESS = 0;
                    LOCK = 0;
                    INITIAL();
                }
            }
            else
            {
                LCD_COMMAND(0X80); 
                LCD_STRING("WRONG PASSWORD");
                __delay_ms(2000);
                PRESS = 0;
                INITIAL();
            }
        
        }
 
        if(PRESS == 0)
        {
            for(i = 0; i < 4; i++)NUMBER[i] = 0x00;
 
            i = 0;
        }
 
        if((PORTC & 0x04) == 0x04)
        {
            while((PORTC & 0x04) == 0x04);
    
            PRESS = 0;
            INITIAL();
        }
    }
}
 
void LCD_COMMAND(char cmd)
{
    PORTD = cmd;
    RA2 = 1;
    RA2 = 0;
    __delay_ms(10);
}
 
void LCD_DATA(char dat)
{
    PORTD = dat;
    PORTA = 0b000001;
    PORTA = 0b001101;
    PORTA = 0B000001;
    __delay_ms(10);
}
 
void LCD_STRING(char *str)
{
    while(*str)LCD_DATA(*str++);
}
 
void KEY(unsigned char TEMP)
{
    switch(PRESS)
    {
        case 1:
            NUMBER[0] = TEMP;
            break;
        case 2:
            NUMBER[1] = TEMP;
            break;
        case 3:
            NUMBER[2] = TEMP;
            break;
        case 4:
            NUMBER[3] = TEMP;
            break;
    };
}
 
char ASCII(char temp)
{
    if(temp > 0x09)
    {
        temp = temp + 0x07;
    }
 
    temp = temp + 0x30;
    return(temp);
}
 
void INITIAL(void)
{
    LCD_COMMAND(0X01); 
    LCD_COMMAND(0X0C); 
    LCD_COMMAND(0X80);
 
    LCD_STRING("ENTER PASSWORD");
    LCD_COMMAND(0XC0);
}

 

Attachments

  • MPLAB Hi-TECH PICC CODE-LOCK.rar
    92.5 KB · Views: 133
Last edited:
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top