Pic microcontroller, For loops jumping all over the map?

Thread Starter

Travm

Joined Aug 16, 2016
363
So i've got a pic16f1574 pwm driving some led's. What i'm trying to achieve is to have the LEDs dim to almost off, then increase brightness, then repeat.
What happens is they seem decrease properly, then skip the increase phase and go straight back to decrease, then randomly switch to increasing, skip the decrease and go straight back to increase, then randomly work properly for 1 cycle, then go back to whatever it feels like.
I expect its bad code, but i cant figure out whats wrong.
any thoughts?
usinc MPlabx and XC8
Main.c
C:
while (1)
    {   
        int i;
      for (i=600; i>2; i-=10)
        {     
       PWM1DCL = i;
       PWM1LDCON = 0x80;
       __delay_ms(100);
        }
       i=1;
        for (i = 1; i < 600; i+=10)
        {       
       PWM1DCL = i;
       PWM1LDCON = 0x80;
       __delay_ms(100);
        }  
       i=600;
    }
}
 
Last edited by a moderator:

Papabravo

Joined Feb 24, 2006
21,227
Aside from the redundant assignments to variable i on lines 11 an 18, I don't see an explanation for the behavior. Line 20 contains an unmatched curly brace. Would you care to share the rest of the code with us. The behavior sounds like an interrupt service routine gone bad or maybe a watchdog RESET.
 

Thread Starter

Travm

Joined Aug 16, 2016
363
Aside from the redundant assignments to variable i on lines 11 an 18, I don't see an explanation for the behavior. Line 20 contains an unmatched curly brace. Would you care to share the rest of the code with us. The behavior sounds like an interrupt service routine gone bad or maybe a watchdog RESET.
C:
/**
  Generated Main Source File

  Company:
    Microchip Technology Inc.

  File Name:
    main.c

  Summary:
    This is the main file generated using MPLAB(c) Code Configurator

  Description:
    This header file provides implementations for driver APIs for all modules selected in the GUI.
    Generation Information :
        Product Revision  :  MPLAB(c) Code Configurator - 3.15.0
        Device            :  PIC16F1574
        Driver Version    :  2.00
    The generated drivers are tested against the following:
        Compiler          :  XC8 1.35
        MPLAB             :  MPLAB X 3.20
*/

/*
    (c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
    software and any derivatives exclusively with Microchip products.

    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
    WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.

    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.

    MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
    TERMS.
*/

#include "mcc_generated_files/mcc.h"

/*
                         Main application
*/
void main(void)
{
    // initialize the device
    SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

    while (1)
    {
        // Add your application code
        int i;
    /*    for (i = 1; i < 600; i++)
        {
       __delay_ms(25);
       PWM1DCL = i;
       PWM1LDCON = 0x80;
      
        }
    */    for (i=600; i>2; i-=10)
        {
      
       PWM1DCL = i;
       PWM1LDCON = 0x80;
       __delay_ms(100);
        }
      
    
       i=1;
        for (i = 1; i < 600; i+=10)
        {
      
       PWM1DCL = i;
       PWM1LDCON = 0x80;
       __delay_ms(100);
        }
      
       i=600;
       /*for (i = 11; i < 75; i++)
        {
       __delay_ms(15);
       PWM1DCL = i;
       PWM1LDCON = 0x80;
      
        }
        for (i = 76; i < 400; i++)
        {   
      __delay_ms(5);
      PWM1DCL = i;
       PWM1LDCON = 0x80;
      
        }*/
    }
}
/**
End of File
*/
The Code,

I'm going over the datasheet again and thinking that maybe its an issue with the reload timing and the delay arguments. Not sure how to solve it though.
 

Thread Starter

Travm

Joined Aug 16, 2016
363
what's the data type of PWM1DCL?

read the datasheet.
i'm not finding the information regarding the data type. Its an 8-bit number? i dont see why int wouldnt work, so long as i keep the value at or below 8-bits.

The register is changing, and the pwm is changing. it just appears that the for loops are not functioning properly. Or there is some issue with the PWM being adjusted properly within in the loops.
 

Papabravo

Joined Feb 24, 2006
21,227
i'm not finding the information regarding the data type. Its an 8-bit number? i dont see why int wouldnt work, so long as i keep the value at or below 8-bits.

The register is changing, and the pwm is changing. it just appears that the for loops are not functioning properly. Or there is some issue with the PWM being adjusted properly within in the loops.
That would be great if you had actually kept the value below 8 bits, but you did not do that.

Question: What numbers can an 8 bit quantity represent?
Answer: an 8-bit quantity can represent [0:255] unsigned or [-128:127] signed.

Clearly 600 > 255, so what you are writing to the register is actually i %256 or the remainder left after dividing i by 256. I bet that produces an interesting show.
 
Last edited:

Thread Starter

Travm

Joined Aug 16, 2016
363
that would be grat if had actually kept the value below 8 bits, but you did not do that.

Question: What numbers can an 8 bit quantity represent?
Answer: an 8-bit quantity can represent [0:255] unsigned or [-128:127] signed.


Clearly 600 > 255, so what you are writing to the register is actually i %256 or the remainder left after dividing i by 256. I bet that produces an interesting show.
That made me laugh.
Thanks for pointing out my stupidity.
 

Thread Starter

Travm

Joined Aug 16, 2016
363
but did you?
I think we've already cleared that up, but thanks again.

I have got the two registers PWM1DCH and PWM1DCL working properly in full 16 bit now actually.

Only to find out that I soldered the 7 segment display port upside down, and the pin assignments dont work. Learning is fun.
 
Top