Author Topic: C nibble problem  (Read 1780 times)

0 Members and 1 Guest are viewing this topic.

Online PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 581
  • Country: gb
C nibble problem
« on: October 07, 2020, 04:38:10 pm »
I am running this simple programme on a PIC12F683:

Code: [Select]
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 4000000

#pragma config FOSC = INTOSCIO  // 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)
#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 CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

void main(void)
{
    TRISIO = 0;                   
   
    int count = 0;
    int temp = 0;
   
    while(count < 16)
    {
        GPIO = count;
        temp = count;
        GPIObits.GP4 = temp >> 3 & 1;        //because GP3 is input only
                 
        __delay_ms(500);
        count++;
    }
 
}

I have LEDs attached to the GPIO pins 4 and 2-0 because GPIO3 is input only. So, I write "count" to the GPIO register then right-shift it three times (via "temp") then "AND" it with b00000001 to get the digit that should be in position 3 and write it to GPIO4 where the final LED is connected.

I doesn't work. It looks like the lower 3 LEDs count and light very quickly (almost invisible) then GPIO4 lights normally for 500ms and the process repeats. It's as if it is ignoring the "delay" command when displaying the lower three.

If I comment out the "GPIObits, etc." line then it works perfectly with the LEDs lighting for the 500ms and counting as expected, of course GPIO4 doesn't light.

What can I be doing wrong?

Cheers.
« Last Edit: October 07, 2020, 04:40:43 pm by PerranOak »
You can release yourself but the only way to go is down!
RJD
 

Offline KrudyZ

  • Frequent Contributor
  • **
  • Posts: 340
  • Country: us
Re: C nibble problem
« Reply #1 on: October 07, 2020, 05:08:01 pm »
I would assemble the word in one go.

GPIO = (count & 0x07) | ((count << 1) & 0x10);

There are more parentheses than are strictly needed, but better be clear than getting bitten by operator precedence.
 

Offline oPossum

  • Super Contributor
  • ***
  • Posts: 1559
  • Country: us
  • Very dangerous - may attack at any time
Re: C nibble problem
« Reply #2 on: October 07, 2020, 05:53:22 pm »
Turn off all analog features. They can interfere with RMW (read-modify-write) operations.

Code: [Select]
GPIObits.GP4 = temp >> 3 & 1;   // This does RMW

Code: [Select]
// Turn off analog stuff
CMCON0 = 7;
ANSEL = 0;


 
The following users thanked this post: PerranOak, I wanted a rude username

Online PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 581
  • Country: gb
Re: C nibble problem
« Reply #3 on: October 08, 2020, 10:19:37 am »
Thank you oPossum this solved it. I am ashamed that I didn't remember ANSEL but I would never have thought of turning off the comparator.

KrudyZ: cheers - my code is a lot slicker now.
You can release yourself but the only way to go is down!
RJD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->