-1

I am having trouble finding a problem with the code, it's supposed to be in C language and I'm using a PIC16F877A and an L293D motor driver IC.

Here's the code:

#include <xc.h>
#include <stdint.h>
#include "config.h"
#define _XTAL_FREQ 4000000
//--[ Pin Definitions ]--
#define Rev RB0   // Reverse Direction Button
#define LV0 RB1   // 0% Speed Button
#define LV1 RB2   // 50% Speed Button
#define LV2 RB3   // 75% Speed Button
#define LV3 RB4   // 100% Speed Button
//================================
//--[ Function Declarations ]--
void PWM1_Set_Duty(uint16_t);
 
void main(void)
{
  //--[ Configuration For IO Pins ]--
  TRISB = 0x1F; // Low 5-pins are input pins
  // Set The Direction To Be Output Pins
  TRISD0 = 0;
  TRISD1 = 0;
  // Initially (0, 1) Say it's ClockWise rotation!
  // For Reversing The Direction Write (1, 0)
  RD0 = 0;
  RD1 = 1;
 
  //--[ Configure The CCP Module For PWM Mode ]--
  CCP1M3 = 1;


 CCP1M2 = 1;
  TRISC2 = 0; // The CCP1 Output Pin (PWM)
  // Set The PWM Frequency (2kHz)
  PR2 = 124;
  // Set The PS For Timer2 (1:4 Ratio)
  T2CKPS0 = 1;
  T2CKPS1 = 0;
  // Start CCP1 PWM !
  TMR2ON = 1;
 
  // The Main Loop (Routine)
  while(1)
  {
    if(Rev) // Reverse The Direction
    {
      RD0 = ~RD0;
      RD1 = ~RD1;
      __delay_ms(500); // Wait For The Button To Be Released
    }
    if(LV0) // 0% DC
    {
      PWM1_Set_Duty(0);
      __delay_ms(100); // Wait For The Button To Be Released
    }
    if(LV1) // 50% DC
    {
      PWM1_Set_Duty(250);
      __delay_ms(100); // Wait For The Button To Be Released
    }
    if(LV2) // 75% DC
    {
      PWM1_Set_Duty(375);
      __delay_ms(100); // Wait For The Button To Be Released
    }
    if (LV3) // 100% DC
    {
      PWM1_Set_Duty(500);
      __delay_ms(100); // Wait For The Button To Be Released
    }
    __delay_ms(10);  // Wait To Reduce The Simulation Overloading
  }
  return;
}
 
// Definition For PWM1_Set_Duty Function
void PWM1_Set_Duty(uint16_t DC)
{
  // Check The DC Value To Make Sure it's Within 10-Bit Range
  if(DC<1024)
  {
    CCP1Y = DC & 1;
    CCP1X = DC & 2;
    CCPR1L = DC >> 2;
  }
}

I tried compiling and editing it but I can't build and upload it.

Clifford
  • 88,407
  • 13
  • 85
  • 165
Abdou
  • 1
  • 1
    If it does not compile, just dumping the code is unhelpful. When the compiler fails it outputs _useful_ diagnostic information. You should include that in your question (and not via an off-site link or a screenshot - the verbatim text). – Clifford Dec 12 '22 at 20:49
  • Where for example are `RB0` etc. defined and how are they defined (should be `PORTBbits.RB0` for example. – Clifford Dec 12 '22 at 21:11
  • Even if you can compile it, one apparent problem is you are flipping `RD0` and `RD1` repeatedly in the `while` loop when `Rev` is set. It will cause a *hunting* of the motor. – tshiono Dec 12 '22 at 23:27
  • @Clifford the XC8 compiler recognizes even only bit labels and convert them to corresponding bit instructions. All these definitions are actually made in the PIC specific header file. So this shouldn't be a problem unless the OP doesn't select the correct PIC model in the project configuration. – Kozmotronik Dec 13 '22 at 05:46
  • 1
    @Kozmotronik I appreciate that, but the comment "_I can't build and upload it._" suggests it is not compiling/linking and awaiting the diagnostic log and without the build tools to try it, I am trying to determine why it might fail. I could not find reference to `RB0` macros in Microchip documentation, only `PORTBbits.RB0`, so I will take your word for it. – Clifford Dec 13 '22 at 12:24
  • Thank you @Clifford as a matter of fact the *I can't build and upload it* is an unclear and open expression. *I could not find reference to RB0 macros in Microchip documentation* AFAIK Microchip does not mention about bit definitions. I recommend you to have a look at specific PIC headers like *pic16f877a.h* in this case. There are tons of SFR definitions both for register and bit names and also some macros that all are very convenient. Microchip should have added all these convenient macros and definitions to their specific documentation or to XC8 manual altough they mention a few of them. – Kozmotronik Dec 13 '22 at 12:53
  • @Kozmotronik it is unclear, and why I requested clarification. The OP has not chosen to respond yet. I don't need to check the header, because I wouldn't choose to use a PIC16, just trying to get clarification, since it is entirely possible the issue does not need PIC16 expertise or dev kit to resolve. – Clifford Dec 13 '22 at 13:53
  • 1
    *I don't need to check the header, because I wouldn't choose to use a PIC16* - Never mind @Clifford it was only for your information. You may be interested or not, I cannot know that. But I can assure that using bit names like `RB0` or `RD0` is not an issue with *XC8* compilers. Let's see what the OP's update will be if he decides to return some day. – Kozmotronik Dec 13 '22 at 14:29

1 Answers1

1

This is a common error that every PIC XC8 newbies or even sometimes experienced ones can make. Of course @Abdou you're supposed to add the build outputs in order to see what the errors are. However, by looking a little to your code I could guess what the error is.
You're using __delay_ms() macro which is defined in the deeps of the xc.h header, but the headers cannot see the _XTAL_FREQ definition in order to calculate the delay values needed. What you need to do in this case is to move the crystal definition line above the xc.h header.

#define _XTAL_FREQ 4000000 // Must be located before the xc.h

#include <xc.h>
#include <stdint.h>
#include "config.h"
Kozmotronik
  • 2,080
  • 3
  • 10
  • 25