CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Why my PIC speed decreasing when i create new variables

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Abravius



Joined: 18 May 2022
Posts: 4

View user's profile Send private message

Why my PIC speed decreasing when i create new variables
PostPosted: Wed May 18, 2022 11:58 pm     Reply with quote

Hi Everyone, I'm not the best in english... I will do my best Smile .

I'm trying to make a driver for the LED WS2812.

For now, I'm using the PIC16F1947 from the Explorer 8 board.

The driver is working correctly as long as I don't create new global variables.

In fact, When I add global variables, The pic speed decreases for a reason I don't understand...

Frame rate with no global variables : 33.20uS

Frame rate with global variables : 53uS

Note that, I'm using Assembler (my first time using Assembler) to send the data over the PIN and some C to prepare the colour.

Here is my code :

Code:
/*
 * File:   WS2812.h
 * Author: rionque
 *
 * Created on 17. mai 2022, 12:43
 */

//         /!\ THIS DRIVER WORKS ONLY WITH A 32MHZ PIC FREQUENCY /!\

//What PIN is used from the C port
#define SELECTED_PORTC_OUTPUT 5

//How many leds on the strip
#define LED_QTY 24

#byte PORTC =   0x00E
#byte LATC =    0x10E
#byte TRISC =   0x08E


//Array that contain the colour of each LED
static int LEDArray[3][LED_QTY];

//Initialisation of the selected PIN from the C port
void Init_NeoPixel()
{
#asm
    //Clear all the register for the C port
    BCF PORTC, SELECTED_PORTC_OUTPUT;
    BCF LATC, SELECTED_PORTC_OUTPUT;
    BCF TRISC, SELECTED_PORTC_OUTPUT;
#endasm
}


//Function used set a colour for a specific LED
//<_Led> : Selected LED
//<_R> :    Red setting
//<_G> :    Green setting
//<_B> :    Blue setting
void SetPixelRGB(int _Led, int _R, int _G, int _B)
{
    LEDArray[0][_Led] = _R;
    LEDArray[1][_Led] = _G;
    LEDArray[2][_Led] = _B;
}

//function used set a colour and the brightness for a specific LED
//<_Led> :  Selected LED
//<_R> :    Red setting
//<_G> :    Green setting
//<_B> :    Blue setting
//<_Br> :   Set the brightness for the selected LED
void SetPixelRGBB(int _Led, int _R, int _G, int _B, int _Br)
{
    int Lum = _Br * 0.392156863;
    LEDArray[0][_Led] = (_R / 100) * Lum;
    LEDArray[1][_Led] = (_G / 100) * Lum;
    LEDArray[2][_Led] = (_B / 100) * Lum;
}

//function used for set all the same colour for all the LED
//<_R> :    Red setting
//<_G> :    Green setting
//<_B> :    Blue setting
void FillStrip(int _R, int _G, int _B)
{
    for(int i = 0; i < LED_QTY; i++)
    {
        LEDArray[0][i] = _R;
        LEDArray[1][i] = _G;
        LEDArray[2][i] = _B;
    }
}

//function used for turn off all the LED
void ClearStrip()
{
    for(int i = 0; i < LED_QTY; i++)
    {
        LEDArray[0][i] = 0;
        LEDArray[1][i] = 0;
        LEDArray[2][i] = 0;
    }
}

//Function used for determinate the brightness for all the LED
//<_Brightness> :   Brightness setting for all the LED
void BrightnessSet(int _Brightness)
{
    int LUM = _Brightness * 0.392156863;
    for(int i = 0; i < LED_QTY; i++)
    {
        LEDArray[0][i] = (LEDArray[i] / 100) * LUM;
        LEDArray[1][i] = (LEDArray[i] / 100) * LUM;
        LEDArray[2][i] = (LEDArray[i] / 100) * LUM;
    }
}

//Function used for set colour for some selected LED
//<_LedMin> :   Start LED
//<_LedMax> :   Stop LED
//<_R> :        Red setting
//<_G> :        Green setting
//<_B> :        Blue setting
//<_Br> :       Brightness setting for all the LED
void SetManyLED(int _LedMin, int _LedMax, int _R, int _G, int _B, int _Br)
{
    //THERE IS A PROBLEM, NOT THE NEST METHOD
    int LUM = _Br * 0.392156863;
    if(_LedMax == 0)
        for(int i = _LedMin; i < LED_QTY - _LedMax; i++)
        {
            LEDArray[0][i] = (_R / 100) * LUM;
            LEDArray[1][i] = (_G / 100) * LUM;
            LEDArray[2][i] = (_B / 100) * LUM;
        }
    else
        for(int i = _LedMin; i < _LedMax - _LedMax; i++)
        {
            LEDArray[0][i] = (_R / 100) * LUM;
            LEDArray[1][i] = (_G / 100) * LUM;
            LEDArray[2][i] = (_B / 100) * LUM;
        }
}

//Function used to turn on LED with the specific color defined earlier
void showStrip()
{
    int LP0 = 0, LP1 = 0, LP2 = 0;
    for(int i = 0; i < LED_QTY; i++)
    {
        int _G = LEDArray[1][i];
        int _R = LEDArray[0][i];
        int _B = LEDArray[2][i];

//PARTIE EN ASSEMBLEUR POUR GARANTIR LA VITESSE DE TRAITEMENT EN NANOSECONDE
#asm
///////////////////////////////////////////////////////CONCERNE LA COULEUR VERTE
        SUB0:
        BTFSC LP0, 3;
        GOTO SUB1;
        INCF LP0, 1;

        BSF PORTC,SELECTED_PORTC_OUTPUT;
        NOP;
        BTFSS _G, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        RRF _G;
        GOTO SUB0;
   
///////////////////////////////////////////////////////CONCERNE LA COULEUR ROUGE
        SUB1:
        BTFSC LP1, 3;
        GOTO SUB2;
        INCF LP1, 1;

        BSF PORTC,SELECTED_PORTC_OUTPUT;
        NOP;
        BTFSS _R, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        RRF _R;
        GOTO SUB1;

////////////////////////////////////////////////////////CONCERNE LA COULEUR BLEU
        SUB2:
        BTFSC LP2, 3;
        GOTO SUB3;
        INCF LP2, 1;

        BSF PORTC,SELECTED_PORTC_OUTPUT;
        NOP;
        BTFSS _B, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        BCF PORTC,SELECTED_PORTC_OUTPUT;
        RRF _B;
        GOTO SUB2;
   
//////////////////////////////FIN DU CYCLE D'ENVOI//////////////////////////////
        SUB3:
        CLRF LP0;
        CLRF LP1;
        CLRF LP2;
#endasm
    }
}


Thank you in advance and have a nice day !
PrinceNai



Joined: 31 Oct 2016
Posts: 478
Location: Montenegro

View user's profile Send private message

PostPosted: Thu May 19, 2022 12:47 am     Reply with quote

Hi,

how are you using these functions and where are those new global variables? Your main code?
Abravius



Joined: 18 May 2022
Posts: 4

View user's profile Send private message

PostPosted: Thu May 19, 2022 1:55 am     Reply with quote

Hi,

There's my main code :

Code:
#include <16f1947.h>

//TRES IMPORTANT D'ACTIVER LE PLL
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, PLL
#use delay (clock = 32000000)

#include "WS2812.h"


int1 Alternance;
 int test, test1, test3;

void main()
{
    //ACTIVATION DU PLL ET OSCILLATEUR INTERNE EN 8MGHZ PERMETTANT D'OBTENIR
    setup_oscillator(OSC_PLL_ON);
   
    output_high(PIN_C4);
   
   
    Init_NeoPixel();
   
    while(TRUE)
    {
        if(Alternance)
        {
            FillStrip(0xFF, 0, 0);
        }
        else
        {
            FillStrip(0, 0, 0xFF);
        }
       
        showStrip();
        delay_ms(500);
        Alternance= !Alternance;
    }
}


I've tried the "#inline" with my function into the driver, no change.

I've declared 3 new global variables at the top of the main C, it's "test1", "test2" and test3". Just with that, the speed of the PIC decreases.
Abravius



Joined: 18 May 2022
Posts: 4

View user's profile Send private message

PostPosted: Thu May 19, 2022 2:00 am     Reply with quote

After looking at the ".lst" file with and without global variables, I've noticed some change into my assembler code (#asm) :

Without global variable :

Code:
#asm
.................... ///////////////////////////////////////////////////////CONCERNE LA COULEUR VERTE
....................         SUB0:
....................         BTFSC LP0, 3;
01F0:  BTFSC  69.3
....................         GOTO SUB1;
01F1:  GOTO   1FA
....................         INCF LP0, 1;
01F2:  INCF   69,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
01F3:  BSF    0E.5
01F4:  NOP
....................         NOP;
....................         BTFSS _G, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
01F5:  BTFSS  6D.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
01F6:  BCF    0E.5
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
01F7:  BCF    0E.5
....................         RRF _G;
01F8:  RRF    6D,F
....................         GOTO SUB0;
01F9:  GOTO   1F0
....................     
.................... ///////////////////////////////////////////////////////CONCERNE LA COULEUR ROUGE
....................         SUB1:
....................         BTFSC LP1, 3;
01FA:  BTFSC  6A.3
....................         GOTO SUB2;
01FB:  GOTO   204
....................         INCF LP1, 1;
01FC:  INCF   6A,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
01FD:  BSF    0E.5
01FE:  NOP
....................         NOP;
....................         BTFSS _R, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
01FF:  BTFSS  6E.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
0200:  BCF    0E.5
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
0201:  BCF    0E.5
....................         RRF _R;
0202:  RRF    6E,F
....................         GOTO SUB1;
0203:  GOTO   1FA
....................
.................... ////////////////////////////////////////////////////////CONCERNE LA COULEUR BLEU
....................         SUB2:
....................         BTFSC LP2, 3;
0204:  BTFSC  6B.3
....................         GOTO SUB3;
0205:  GOTO   20E
....................         INCF LP2, 1;
0206:  INCF   6B,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
0207:  BSF    0E.5
0208:  NOP
....................         NOP;
....................         BTFSS _B, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
0209:  BTFSS  6F.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
020A:  BCF    0E.5
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
020B:  BCF    0E.5
....................         RRF _B;
020C:  RRF    6F,F
....................         GOTO SUB2;
020D:  GOTO   204
....................     
.................... //////////////////////////////FIN DU CYCLE D'ENVOI//////////////////////////////
....................         SUB3:
....................         CLRF LP0;
020E:  CLRF   69
....................         CLRF LP1;
020F:  CLRF   6A
....................         CLRF LP2;
0210:  CLRF   6B
0211:  MOVLB  00
.................... #endasm


With global variables :
Code:
#asm
.................... ///////////////////////////////////////////////////////CONCERNE LA COULEUR VERTE
....................         SUB0:
....................         BTFSC LP0, 3;
00AA:  MOVLB  00
00AB:  BTFSC  6C.3
....................         GOTO SUB1;
00AC:  GOTO   0BC
....................         INCF LP0, 1;
00AD:  INCF   6C,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
00AE:  BSF    0E.5
00AF:  NOP
....................         NOP;
....................         BTFSS _G, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
00B0:  MOVLB  01
00B1:  BTFSC  20.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00B2:  GOTO   0B6
00B3:  MOVLB  00
00B4:  BCF    0E.5
00B5:  MOVLB  01
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00B6:  MOVLB  00
00B7:  BCF    0E.5
....................         RRF _G;
00B8:  MOVLB  01
00B9:  RRF    20,F
....................         GOTO SUB0;
00BA:  GOTO   0AA
00BB:  MOVLB  00
....................     
.................... ///////////////////////////////////////////////////////CONCERNE LA COULEUR ROUGE
....................         SUB1:
....................         BTFSC LP1, 3;
00BC:  BTFSC  6D.3
....................         GOTO SUB2;
00BD:  GOTO   0CD
....................         INCF LP1, 1;
00BE:  INCF   6D,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
00BF:  BSF    0E.5
00C0:  NOP
....................         NOP;
....................         BTFSS _R, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
00C1:  MOVLB  01
00C2:  BTFSC  21.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00C3:  GOTO   0C7
00C4:  MOVLB  00
00C5:  BCF    0E.5
00C6:  MOVLB  01
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00C7:  MOVLB  00
00C8:  BCF    0E.5
....................         RRF _R;
00C9:  MOVLB  01
00CA:  RRF    21,F
....................         GOTO SUB1;
00CB:  MOVLB  00
00CC:  GOTO   0BC
....................
.................... ////////////////////////////////////////////////////////CONCERNE LA COULEUR BLEU
....................         SUB2:
....................         BTFSC LP2, 3;
00CD:  BTFSC  6E.3
....................         GOTO SUB3;
00CE:  GOTO   0DE
....................         INCF LP2, 1;
00CF:  INCF   6E,F
....................
....................         BSF PORTC,SELECTED_PORTC_OUTPUT;
00D0:  BSF    0E.5
00D1:  NOP
....................         NOP;
....................         BTFSS _B, 0; //Condition permettant de déterminer quand la PIN doit être FALSE
00D2:  MOVLB  01
00D3:  BTFSC  22.0
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00D4:  GOTO   0D8
00D5:  MOVLB  00
00D6:  BCF    0E.5
00D7:  MOVLB  01
....................         BCF PORTC,SELECTED_PORTC_OUTPUT;
00D8:  MOVLB  00
00D9:  BCF    0E.5
....................         RRF _B;
00DA:  MOVLB  01
00DB:  RRF    22,F
....................         GOTO SUB2;
00DC:  MOVLB  00
00DD:  GOTO   0CD
....................     
.................... //////////////////////////////FIN DU CYCLE D'ENVOI//////////////////////////////
....................         SUB3:
....................         CLRF LP0;
00DE:  CLRF   6C
....................         CLRF LP1;
00DF:  CLRF   6D
....................         CLRF LP2;
00E0:  CLRF   6E
00E1:  MOVLB  00
.................... #endasm


I don't know why the compiler change my code Razz .
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Thu May 19, 2022 3:09 am     Reply with quote

What has happened is that memory by default is used from the bottom
'up'. Your new global variables are using enough bytes in the bottom
bank, that the local variables in your assembler routine have ended up
in the next bank up. Result the compiler is now having to bank switch
to access these.
Use #locate to force the global variables to be in the second bank. This
then should leave the space for the local variables in the assembler to
go back to the first bank.
If you look at the .sym file you can see where variables are placed.
Abravius



Joined: 18 May 2022
Posts: 4

View user's profile Send private message

PostPosted: Fri May 20, 2022 12:37 am     Reply with quote

Oh okay ! Thank you, I will try it !

For now, I've made the driver on PIC18F it's working perflectly with a frequency of 32MHz or 64MHz.

If you want it, I can send you my GitHub link.
bmete



Joined: 13 Jul 2023
Posts: 37

View user's profile Send private message

PostPosted: Wed Jul 19, 2023 1:57 am     Reply with quote

Hello everyone

Is it possible to operate WS2812B with PIC16F883? I dont need any sliding leds and also I dont need any high speed, I just want to turn on leds which I spesified order in the code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jul 19, 2023 3:55 am     Reply with quote

Yes, BUT.

The 'BUT', is because this controller needs a lot of quite accurately timed
pulses to access the LED's. This is why the author here is using a fast
clock and some parts are using assembler. The 883, is by modern standards
a slow chip, so it'll be doable, but quite hard. It is a chip designed to give
a lot of intensity levels for the LED's, not just simple ON/OFF. There are
much easier chips to drive if you only need ON/OFF.
If you want to use the 8212, I'd switch to a PIC that runs faster.
The commonest way to drive these chips is using spi, and selecting bit
patterns that give the required timing.
bmete



Joined: 13 Jul 2023
Posts: 37

View user's profile Send private message

PostPosted: Wed Jul 19, 2023 4:45 am     Reply with quote

Hello Ttelmah,

Unfortunatelly I already designed a PCB so I have to look an another chip which has a same package and same pin order with 16f883. I think it is pic16f18855. But its clock speed is 32MHz. What is your advice? Is 32MHz enough?

Also I operated the WS2812B module with arduino uno. After that I checked the clock speed of the Arduino uno's chip (Atmega328P). Its clock speed is 8MHz. This confused me.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jul 19, 2023 6:34 am     Reply with quote

The PIC takes four clock cycles to execute a single instruction. The Uno,
takes one.....
The DSPIC's take only two.
Then the DSPIC's can run off (say) a 8MHz clock at 120MHz.
Etc. etc.

You need to look at the MIPS rate, not the clock rate. The UNO is normally
16MIPS, so equivalent to a PIC at 64MHz!...

Yes the 16F18855, will do it. What you do is use SPI at 4MHz,
and then send 1000 for a 0 and 1110 for a 1. Using the nibbles of a byte
just make sure the code designs the patterns needed for this before
starting the send and reloads each byte ASAP so there are no breaks.
So a 36byte array with the data all ready to send. On a PIC, minimum
clock speed to do SPI at this rate is 16MHz. Doing this has been discussed
here before, so a search should find it. Was quite a few years ago though.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group