2
\$\begingroup\$

I am currently developing a circuit that 16 LDRs, 4 LM339N ICs and 1 PIC16F877A. I compare outputs of LDRs with an adjustable reference voltage. I achieved getting 0-5 V from LM339N. Now I send these values to 16F877A as digital inputs to check if one of them is HIGH. If I check only one value, it works well and I can get voltages between 0.12-5.01 V from digital output pin. But when I increase digital inputs to two or more, digital output gives 2.1 when it is low and 2.5V when it is high and it is not enough for me. I have tried defining;

TRISB = 0xFF;

TRISC = 0xF0;

TRISD = 0xF0;

reading values between RB0-7, RC4-7, RD4-7 and writing output to RD0. I have also tried neglecting ADC module and;

TRISB = 0xFF;

TRISA = 0x00;

reading values from RB0 and RB1 and writing to RA0. But no luck yet.

I am using 8 MHz HS crystal with two 22 pF capacitors. Pin 1 has a resistor with push button. PIC is supplied with 5.1 V from 11-32 pins and ground is connected to 12-31 pins. I don't have any prepared circuit diagram but if I cannot find any support from here, I can build it. I am using MPLAB X IDE v3.45 and PicKit2 for programming. The code is included below.


#define _XTAL_FREQ 8000000
#include 
// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG
void main(){
    ADCON1 = 6;
    CMCON = 7;
    TRISB = 0xFF;
    TRISA = 0x00;
    RA0 = 0;
    while(1){
        if(RB0 == 1){RA0 = 1;}else{RA0 = 0;}
        __delay_us(5);
        if(RB1 == 1){RA0 = 1;}else{RA0 = 0;} // Works well when I comment this line.
    }
}

Also tried building if/else if/else structure, not working too. Thanks in advance.

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

The problem is that you have different value for RB0 and RB1:

Suppose RB0=0, and RB1=1, the flow of the code is:

RA0=0 then delay 5us then RA0=1 then loop

If you hook an oscilloscope you will find that RA0 pin is actually toggling but reading the voltage pin using a voltmeter will average(generally speaking) this pulsed signal.

I didn't understand what are you trying to achieve here but you are controlling 1 output using 2 inputs which is really strange.

If you want to check if one of the inputs is high then you shall do the following:

while(1)
{
if((RB0==1)||(RB1==1))
RA0=1;
else
RA0=0;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thanks for your answer. Actually, I need to use 16 inputs to produce only one single output :) You are right about toggling, I changed the codes with yours. But nothing changed, I am still obtaining 2.1 - 2.5 V. \$\endgroup\$ Commented Nov 9, 2016 at 10:14
  • \$\begingroup\$ please measure the following: RB0, RB1 and RA0. If RB0 and RB1 are not toggling and are valid logic levels then RB0 should not toggle \$\endgroup\$
    – fhlb
    Commented Nov 10, 2016 at 10:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.