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.

Short C code for PIC16F627A builds but won't run properly

Status
Not open for further replies.
T

treez

Guest
Hello,
Our short C code builds but won’t run properly. (please find it attached)
(the output RB5, never goes high, even though the pulse train is definitely getting to the input pin RA2)
It is written in XC8 C in MPLAB.
The microcontroller is PIC16F627A
Do you know why it doesnt work as it should?



Code:
//This code simply  has an input "looking"
//at a train of pulses.
//When one of the pulses goes low, a delay is done....
//and then an output is taken high.

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#define  _XTAL_FREQ 4000000

#include <xc.h>
#include <stdint.h>



    uint8_t   count;
    uint8_t   count1;
    uint8_t   count2;

void main(void) {
    
    //Setup ports
    //    TRISA = 0b 1011 1100;   //ADC INS
    //    TRISB = 0b 00000001;    //ZCD & DALIRX..really 0x09
    
    TRISA = 0xBC;
    TRISB = 0x01;

                RA0 = 0;    //NC
                RA1 = 0;    //NC
                //RA2 = 0;    //ZERO X   ..input
                //RA3 = 0;    //on/off ..input
                //RA4 = 0;    //select zapper ..input
                //RA5 = 0;    //RA5 ..MCLR ..input
                RA6 = 0;    //RA6 ..LED failure ..output
                //RA7 = 0;    //failure ..input
                
                //RB0 = 0;    //SELECT OAMP ..INPUT
                RB1 = 0;    //LED ..ZAPPER ..OUTPUT
                RB2 = 0;    //LED OAMP ..OUTPUT
                RB3 = 0;    //NC ..OUTPUT
                RB4 = 0;    //ZAPPER SWITCH ..OUTPUT
                RB5 = 0;    //AC SWITCH ..OUTPUT
                RB6 = 0;    //PGC ...OUTPUT
                RB7 = 0;    //PGD  ..OUTPUT
 

        INTCON = 0x00;
        //OPTION_REG = 0b 10000111
        OPTION_REG = 0x87;
        //VRCON = 0b00;
        VRCON = 0x00;
        CMCON = 0x07;
        
        while (RA2 == 0);
        while (RA2 ==1);
        
        //At this point the pulse has just gone low
        
        __delay_ms(3);   //delay to get to the mains peak
        __delay_us(600);
        
        RB5 = 1;
        __delay_ms(1);
        RB5 = 0;
        
        while(1){;}
           
        
    return;
}
 

Have you stepped through this with a debugger?
Can you see the program stopping until RA2 goes high? Ditto going low again and therefore getting to the delay?
I doubt if any of the following are the problem here but they are bad practice.
On this device (which does NOT have LAT registers) be careful of RMW problems when writing to different bits in the same register in quick succession.
I suggest that you put the 'xc.h' include before the config pragma statements so the compiler knows the correct register and bit names for the settings.
There is no need for a 'return' statement after the main loop, especially as 'main ' is declared as void.
Susan
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
I'm not sure RAx and RBx directly address the pins, it might be better to use PORTA,x and PORTB,x instead or define the pins with their functional names.
In any case, if it runs it will only produce ONE pulse on RB5 before stopping. If you want it to produce 1mS pulses at every H->L transition of RA2, you need to extend the while loop so the operation repeats. You also need to double check the timing of the two delays for accuracy as there is a small overhead between one delay call and the next.

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
thanks, ill try your recomendations. Youre absolutely right we will want more pulses though at the moment i am just trying to get one.
We had ten blinks of a led before the "while (RA==0); while(RA==1); ".
The ten blinks of the led worked but we got no pulse on RB5
 

Proper Sequence of Settings (recommended):

1. #include header files
2. __Config
3. _XTAL_FREQ
4. variable declarations
main(){
5. INTCON = 0;
6. TRIS
7. PORT
8. Comparator & VRCON
9. enable interrupts (if you preferred, but recommended)
}
10. while(1){
read pins for status
}
Note: Instead of reading pins and drive LED on other pins, if you connect LED on comparator output, it will automatically Lit the LED when the condition met

pmk
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
The original code does set RB2 once. If you don't see it, you are either running a different code or have a hardware issue.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
Proper Sequence of Settings (recommended):

1. #include header files
2. __Config
3. _XTAL_FREQ
4. variable declarations
main(){
5. INTCON = 0;
6. TRIS
7. PORT
8. Comparator & VRCON
9. enable interrupts (if you preferred, but recommended)
}
10. while(1){
read pins for status
}
Thanks, i notice you didnt mention the OPTION_REG.
We thought this was needed to be set because of the timer needing to be assigned away from the watchdog.
Also, the timer scaler needs setting which is in the OPTION_REG.
..if the timer scaler is not set properly then the __delay_ms(3); type statements dont work, or may not work?
 

OPTION_REG does need to be set, it can be changed during program execution but needs some sensible value near the start before running the program loop.
Note that the prescaler settings and assignment only apply to TMR0 but the delay() routines most likely just use instruction loops so they may not be influenced by the settings anyway. Using a timer is a more accurate solution when exact delays are needed.

Brian.
 

_delay_ms() uses delay loop rather than timer, not affected by timer prescaler.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top