Short C code for PIC16F627A builds but won't run properly - Page 1
Forum section: electronics / general

author: ocset
author_rank: Super Contributor
timestamp: January 23, 2018, 08:55:20 pm
content: 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 PIC16F627ADo you know why it doesn’t 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 0x09TRISA = 0xBC;TRISB = 0x01;RA0 = 0; //NCRA1 = 0; //NC//RA2 = 0; //ZERO X ..input//RA3 = 0; //on/off ..input//RA4 = 0; //select zapper ..input//RA5 = 0; //RA5 ..MCLR ..inputRA6 = 0; //RA6 ..LED failure ..output//RA7 = 0; //failure ..input//RB0 = 0; //SELECT OAMP ..INPUTRB1 = 0; //LED ..ZAPPER ..OUTPUTRB2 = 0; //LED OAMP ..OUTPUTRB3 = 0; //NC ..OUTPUTRB4 = 0; //ZAPPER SWITCH ..OUTPUTRB5 = 0; //AC SWITCH ..OUTPUTRB6 = 0; //PGC ...OUTPUTRB7 = 0; //PGD ..OUTPUTINTCON = 0x00;//OPTION_REG = 0b 10000111OPTION_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;}

author: rstofer
author_rank: Super Contributor
timestamp: January 23, 2018, 10:23:34 pm
content: How are you capturing that single 1 ms pulse? It seems to me that it could be over and done with in a blink.I would reorganize the code such that I got a continuous output every time I had a transition on the input.

author: Howardlong
author_rank: Super Contributor
timestamp: January 23, 2018, 10:35:32 pm
content: It looks like it runs fine here, using theAC244053AC162053 debug header as I didn't have a production chip. I also have a non-A PIC16F628 production chip (a bit more flash & RAM than the 627, but the same datasheet) and it works fine with that too.A nice 970us high pulse on RB5 when I take RA2 high, good enough for the girls I go out with.Edit: corrected header part number.

author: ocset
author_rank: Super Contributor
timestamp: January 24, 2018, 06:17:22 am
content: Thanks,We are looking at it with a scope on sample/hold

author: AndyC_772
author_rank: Super Contributor
timestamp: January 24, 2018, 08:32:06 am
content: This isn't just the usual ANSEL trap, is it? Do GPIO pins come up in analogue mode on this device?

author: JPortici
author_rank: Super Contributor
timestamp: January 24, 2018, 09:12:45 am
content: No, that's taken care of by CMCONI don't like to read pins this way.. it should work but i always ran into problems.i like to sample the PORT and then operate on the sampled value.Code:uint8_t porta_buf;[..]porta_buf = PORTA;while(!(porta_buf & (1 << 2))) {// same as while(RA2 == 0), gets optimized at compile timeporta_buf = PORTA;}while((porta_buf & (1 << 2))) {//same as while(RA2 == 1)porta_buf = PORTA;}[..]

author: @rt
author_rank: Super Contributor
timestamp: January 24, 2018, 12:02:13 pm
content: Have you flashed an LED to prove the pic is clocking?You have ms delays, so plant of time to shadow your port registers as above yes,and an easy program to debug the old fashioned way.You could insert LED outputs inside both of those while loops,change the first while to an IF, and put the second while loop inside it, etc.

author: mikerj
author_rank: Super Contributor
timestamp: January 24, 2018, 12:22:42 pm
content: Quote from: JPortici on January 24, 2018, 09:12:45 amAgreed, the code that the OP posted is risking the usual PIC Read-Modify-Write problems during initialisation where he is setting multiple pins on the same port consecutively. Unless the PIC has a latch register (LATx) then this should be avoided, by writing the entire PORT initialisation value in one go in this case, or by using a shadow register for RMW operations.However this shouldn't normally be a problem for the output pulse since there is a significant delay between setting and clearing the pin.