• AVR Freaks

AnsweredHot![PIC16F616] Write to PORT A

Author
disconnected
New Member
  • Total Posts : 4
  • Reward points : 0
  • Joined: 2020/07/04 08:59:35
  • Location: 0
  • Status: offline
2020/07/13 15:45:18 (permalink)
0

[PIC16F616] Write to PORT A

Hello! I am a bit new to PIC controllers, and decided to use PIC16F616 to control relay with spst button, light some leds, open  photoFET for a while and so on and so forth. I've tested my program on a breadboard and it's worked just fine, but I used only I/O's on PORT C. Then I thought that there would be no problem to write something to PORT A and didnt check it (shame on me!). I've created a pcb, where one of my outputs connected to PORT A - it's RA2 in particularly, and then I tried to write to RA2 in the same way I write to PORT C I/O and nothing happens :) I've tested it on a breadboard and it's not working too :c So it's obvious, that I've made mistake somehow and I need to code it another way, but I can't find any information in datasheet or maybe I dont know where to look.

- I thought maybe it's open-drain and I can't drive a high level without a pull-up, but I didnt find anything about it in particularly.
- Or maybe it's something with latching? If it's so, could someone show me how to write correctly ;)

So that's how I write to PORT C, for example blinking with LED on RC3:


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <xc.h>
#include "header.h"

#define GPIO_LED    RC3
#define LOW 0x00
#define HIGH 0xFF


void main ()
{
    ANSEL = 0; // no analog GPIO
    ADCON0 = 0; // ADC and DAC converters off

    TRISC3 = 0x00; // set RC3 as output
    GPIO_LED    = LOW;
 
    while (1)
    {
    GPIO_LED = LOW;
    __delay_ms(2000);
    GPIO_LED = HIGH;
    }
}

And now I need to write HIGH and LOW to RA2.
#1
upand_at_them
Super Member
  • Total Posts : 585
  • Reward points : 0
  • Joined: 2005/05/16 07:02:38
  • Location: Pennsylvania
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/14 13:02:37 (permalink)
0
While I don't use C, this concerns me:
 
#define GPIO_LED RC3

 
That is going to depend on how RC3 is defined.  I would rather see this:
 
#define GPIO_LED PORTC, 3

 
Also, if you're not using the other port you should be making sure you don't have floating inputs.  My common practice setup would be:
 
ANSEL = 0
ADCON0 = 0
ADCON1 = 0
CM1CON0 = 0
CM2CON0 = 0
CM2CON1 = 0
PORTA = 0
PORTC = 0
TRISA = 0
TRISC = 0

// and then set whatever TRIS pins I need for inputs...

 
Also, setting individual port pin values is problematic due to the read-modify-write problem.  A solution is to write to a shadow register and write that show register value to the output port.
 
post edited by upand_at_them - 2020/07/14 13:09:08
#2
upand_at_them
Super Member
  • Total Posts : 585
  • Reward points : 0
  • Joined: 2005/05/16 07:02:38
  • Location: Pennsylvania
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/14 13:06:59 (permalink)
+2 (2)
Also, post the code that you have a problem with, not the code that you already know works.
#3
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: [PIC16F616] Write to PORT A 2020/07/14 13:27:46 (permalink)
+1 (1)
upand_at_them
Also, post the code that you have a problem with, not the code that you already know works.

+1
How can we debug the code that is NOT shown...
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
hexreader
Super Member
  • Total Posts : 1072
  • Reward points : 0
  • Joined: 2008/05/04 03:06:55
  • Location: England
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/14 13:32:42 (permalink)
+2 (2)
Your blinking code is wrong...
 
Change:
    while (1)
    {
        GPIO_LED = LOW;
        __delay_ms(2000);
        GPIO_LED = HIGH;
    }

to:
    while (1)
    {
        GPIO_LED = LOW;
        __delay_ms(2000);
        GPIO_LED = HIGH;
        __delay_ms(2000);
    }
 
post edited by hexreader - 2020/07/14 13:34:10

Experienced Hobbyist
#5
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: [PIC16F616] Write to PORT A 2020/07/14 13:36:02 (permalink)
+1 (1)
Indeed.
Plus the config bits are not shown. There's every chance the WDT is resetting the chip regularly too, which may give the impression the blink code was working.
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#6
disconnected
New Member
  • Total Posts : 4
  • Reward points : 0
  • Joined: 2020/07/04 08:59:35
  • Location: 0
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/14 13:55:18 (permalink)
0
Thanks for your reports! Indeed it was a mistake to not post a full code, so I made a mistakes in such a simple example, my appologies.

So this is my full code, it's a bit messy but I had an attempt to refactor it to switch case with good names but got some bugs, so I decided to revert it to this version for now. It's working fine with PORT C I/O's - button works, led blinks and relay switching signals as I expected. 

So this i my content of config bits, which remains in header.h:
...
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config IOSCFS = 8MHZ // Internal Oscillator Frequency Select bit (8 MHz)
#pragma config BOREN = OFF // Brown-out Reset Selection bits (BOR Disabled)
// Define oscillator frequency
#define _XTAL_FREQ 8000000
#define HIGH 1
#define LOW 0
....

And this is my main.c:


#include <stdio.h>
#include <stdlib.h>
// Supplementary libraries
#include <stdint.h>
#include <xc.h>
// Include configuration bits
#include "header.h"
//#define DEBUG_PLATFORM
#ifdef DEBUG_PLATFORM
#define GPIO_LED RC3
#define GPIO_RELE RC1
#define GPIO_BUTTON RC2
#define GPIO_PHET RA2
#else
#define GPIO_LED RC5
#define GPIO_RELE RC3
#define GPIO_BUTTON RC4
#define GPIO_PHET RA2
#endif


void checkButtonState (uint8_t *pState);
void main ()
{
    ANSEL = 0; // no analog GPIO
    ADCON0 = 0; // ADC and DAC converters off
#ifdef DEBUG_PLATFORM
    TRISC3 = 0x00; // set RC3 as output
    TRISC1 = 0x00; // set RC1 as output
    TRISC0 = 0x00; // set RC0 as output
    TRISC2 = 0xFF; // set RC2 as input
    TRISA2 = 0x00; // set RA2 as output
#else
    TRISC5 = 0x00; // set RC5 as output
    TRISC3 = 0x00; // set RC3 as output
    TRISC4 = 0xFF; // set RC4 as input
    TRISA2 = 0x00; // set RA2 as output
#endif

    GPIO_LED = LOW;
    GPIO_RELE = LOW;
    GPIO_BUTTON = LOW;
    GPIO_PHET = LOW;
    uint8_t state = 0;


    while (1)
    {
        checkButtonState(&state);
    }

}


void checkButtonState (uint8_t *pState)
{
    if (GPIO_BUTTON == 0x00)
    {
        __delay_ms(15); // debounce
        if (GPIO_BUTTON == 0x00)
        {
            __delay_ms(200);

            if (GPIO_BUTTON == 1)
            {

                 if (*pState == 1) // pedal is on
                 {
                      GPIO_PHET == 0xFF; // activate phet
                     *pState = 0; // turn pedal off
                     GPIO_LED = 0x00; // turn led off
                     GPIO_RELE = 0x00; // turn off rele
                     __delay_ms(60);
                     GPIO_PHET == 0x00;
                 }
                 else // pedal is off
                 {
                     GPIO_PHET == 0xFF; // activate phet
                     *pState = 1; // turn pedal on
                     GPIO_LED = 0xFF; // turn led on
                     GPIO_RELE = 0xFF; // turn on rele
                     __delay_ms(60);
                     GPIO_PHET == 0x00; 
                 }
             }
         }
     }
}



post edited by disconnected - 2020/07/14 14:01:35
#7
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: [PIC16F616] Write to PORT A 2020/07/14 15:03:44 (permalink) ☼ Best Answerby disconnected 2020/07/15 15:20:28
+4 (4)
ok, a few bits of general advice.
The config settings should be BEFORE the header includes, not after.
xc.h should be the first file included
You almost never need stdio.h in an embedded program, and often don't need stdlib.h either, so don't always include them the way you would in Windows.
 
Edit: Removed, I missed some of the source code.
You define a pointer (pState), but never initialise it. Uninitialised pointers are the source of many many bugs all around the world.
In this case, there is absolutely no need for it to be a pointer anyway. Change all references to "*pState" to just "State".
 
You are trying to write 0xFF to single bit variables in your TRIS code. Just use 0 or 1.
 
You are using "==" in assignment expressions, e.g.
GPIO_PHET == 0xFF; // activate phet

that should be
GPIO_PHET = 1; // activate phet

only use "==" in comparisons.
 
post edited by ric - 2020/07/15 01:46:20

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#8
disconnected
New Member
  • Total Posts : 4
  • Reward points : 0
  • Joined: 2020/07/04 08:59:35
  • Location: 0
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/15 00:50:24 (permalink)
0
Whoa, what a mistake :) I had to double check this before starting a thread. Thanks mate, this should fix my problem and I will test it, when I got home.


You said, that there is no need in a pointer, but I need to store this state value or my program will clear it after checkButtonState exit. And correct me if I'm wrong, but there is an initialization of a pointer, when I pass it with "&" to the function, so it's now store a correct adress of a state variable. Is it correct?


Another variant is to make function return uint8_t and assign its result to state, but pointer seems to feel more natural. I also probably need to check this pointer at the begining of a checkButtonState and return status (but no one will see) or maybe reset my program if there is a null pointer.
#9
ric
Super Member
  • Total Posts : 28009
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: [PIC16F616] Write to PORT A 2020/07/15 01:45:15 (permalink)
+1 (1)
disconnected
...
You said, that there is no need in a pointer, but I need to store this state value or my program will clear it after checkButtonState exit. And correct me if I'm wrong, but there is an initialization of a pointer, when I pass it with "&" to the function, so it's now store a correct adress of a state variable. Is it correct?

Oops, I must have missed a couple of lines when I scanned through your code, I thoiught it was all in main() and didn't see the function call.
Yes, as you say, you need to pass a pointer, or return the value.
Remember, this is a very limited 8 bit processor, passing pointers can be an expensive exercise.
You may well find that returning the value is more efficient.
XC8 outputs a ".lst" file showing the assembly language output from the compiler.
It can be VERY instructive to see what it has to do to implement your C code. Sometime something that loks trivial can take a lot of instructions to implement.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#10
disconnected
New Member
  • Total Posts : 4
  • Reward points : 0
  • Joined: 2020/07/04 08:59:35
  • Location: 0
  • Status: offline
Re: [PIC16F616] Write to PORT A 2020/07/15 15:20:20 (permalink)
+1 (1)
Yep! Problem solved, as it was mentioned before - I mixed up "==" with "=". Thanks a lot, and double check everything Smile: Smile
#11
Jump to:
© 2020 APG vNext Commercial Version 4.5