Multiple Topics (Sorry In Advance)

mikroC, mikroBasic and mikroPascal PRO for Microchip’s 32-bit PIC MCUs
Post Reply
Author
Message
ckelley
Posts: 9
Joined: 14 Feb 2019 22:28

Multiple Topics (Sorry In Advance)

#1 Post by ckelley » 13 Sep 2019 02:56

Let me preface this with the same disclaimer that I have added to all of the posts I have made on this forum, I am new to both PIC32 and the MikroElektronika MikroPascal compiler. I am using the following:
  • EasyPIC Fusion v7 Pro
  • MikroPascal Compiler
  • A quadrature AB encoder
Okay for the for the sake of simplification I am going to ask the following summarized questions:

In my pursuit of using the VTFT, quadrature AB encoder I ran into the following quirks / pitfalls.
  1. How do I go about correcting the timing scale for the generic Delay functions (Delay_ms, Delay_us, etc...). I noticed that the timing scale was off when casually using the Delay_ms(X) function. I am aware that for the timer interrupt there is a calculator for the the TMR1 register values to correct against different clock frequencies. Do I need to do anything in particular to do this same thing for the built-in library delay functions?
  2. I downloaded a package from LibStock in the hopes to have starting point when using the quadrature AB encoder. I found the following code:

    Code: Select all

    unit Rotary_Encoder;
    // interface
    
    var Rotary_Encoder_A : sbit; external; sfr; // to be defined in the using program
        Rotary_Encoder_B : sbit; external; sfr; // to be defined in the using program
    
    // Rotary encoder output: //
        Rotary_Direction: byte; // output result, to be reset to zero by the using program
    {  0: no rotation
       1: left rotation
       2: right rotation
    }
    
    Procedure Init_Rotary_Encoder;  // To be called once before calling Check_Rotary_Encoder
    procedure Check_Rotary_Encoder; // To be called every 1 millisecond. The result is in variable Rotary_Direction, see above
    
    implementation
    
    var Rotary_State : byte;
    { 0: both lines are 0
      1: both lines are 1
      2: both lines differ
    }
    
    Procedure Init_Rotary_Encoder;
    begin
      Rotary_Direction := 0; // no rotation detected
      Rotary_State     := 2; // for safety
    end;
    
    procedure Check_Rotary_Encoder;
    var Rotary_Val : byte;
    begin
      Rotary_Val := Rotary_Encoder_A + (Rotary_Encoder_B shl 1); // bit 0 = A, bit 1 = B
    
      case Rotary_val of
        0, 3: // both A and B are the same (0,0 or 1,1)
        begin
          Rotary_State := Rotary_Val.0;
        end
        else // A and B differ, A changed or B changed...
        begin
          if (Rotary_State <> 2) then // no detecion ongoing
          begin
            if Rotary_Val.0 <> Rotary_State // A changed?
            then Rotary_Direction := 1      // clockwise rotation, A changed before B
            else Rotary_Direction := 2;     // Counter clockwise rotation, B Changed before A
            Rotary_State := 2;
          end;
        end;
    
      end;
    end;
    end.

    In addition to the previous implementation, the following example is given:

    Code: Select all

    unit Rotary_Encoder_Example;
    
      uses Rotary_Encoder;
    
    var Counter: byte;
    // Rotary Encoder connections to the PIC
        Rotary_Encoder_A : sbit at RG6_bit;
        Rotary_Encoder_B : sbit at RG7_bit;
    //------------------------------------------------------------------------------
    
    //Timer1
    //Prescaler 1:8; PR1 Preload = 25000; Actual Interrupt Time = 1 ms
    procedure InitTimer1;
    begin
      T1CON            := 0x8010;
      T1IP0_bit        := 1;
      T1IP1_bit        := 1;
      T1IP2_bit        := 1;
      T1IF_bit         := 0;
      T1IE_bit         := 1;
      PR1              := 25000;
      TMR1             := 0
    end;
    
    procedure HW_Init;     // Minimal Hardware initialisation for Debug
    begin
      TRISG6_bit  := 1; // make input
      TRISG7_bit  := 1; // make input
    
      // Initialise the rotary encoder detection
      Counter     := 0;
      Init_Rotary_Encoder;
    
      // initialise timer
      InitTimer1;
    
      // Turn on all Interrupt handling in general (last thing to be done)
      TMR1        := 1;  // Timer1 Interrupt enable
      INTCON.PEIE := 1;  // Peripheral Interrupts enable
      INTCON.GIE  := 1;  // Interrupts global einschalten
    end;
    
    //------------------------------------------------------------------------------
    // Interrupt procedure
    //------------------------------------------------------------------------------
    procedure Timer1Interrupt(); iv IVT_TIMER_1; ilevel 7; ics ICS_SRS;
    begin
      T1IF_bit     := 0;
      begin
        Check_Rotary_Encoder; // check the rotary encoder inputs
      end;
    end;
    
    begin
    // Init Hardware for minimal functionality (debugging)
      HW_Init;
    
      while (True) do
      begin
        // Rotary encoder
        if Rotary_Direction > 0 then
        begin
          case Rotary_Direction of
            1: //
            inc(Counter);
            2: //
            dec(Counter);
          end;
          byteToStr(Counter, Strng);
          Rotary_Direction := 0; // reset to zero after usage
        end;
      end;  // while true ...
    end;
    However, I get an expected "end" but "begin" found error.

    Error Image: [img]
    end error.PNG
    end error.PNG (53.92 KiB) Viewed 2918 times
    [/img]

    If I place a
    end.
    above the InitTimer1 proceedure then the compiler stops complaining, but I am not sure why I would need and
    end.
    above the InitTimer1 proceedure.
In my previous post I has issues the getting the VTFT working, and after getting a working example from the technical support, I realized my real problem was the the hardware pattern I was using.

Any help would be appreciated!

Thanks in advanced,
ckelley

User avatar
stefan.filipovic
mikroElektronika team
Posts: 1135
Joined: 18 Dec 2018 10:30

Re: Multiple Topics (Sorry In Advance)

#2 Post by stefan.filipovic » 13 Sep 2019 08:52

Hi,

a) It's calculated by the compiler depending on which MCU frequency have you set in the project settings. So, you just need to set the clock settings in the Edit Project window properly for the chosen MCU frequency, and the compiler will generate accurate delays. You may find a predefined clock scheme in the compiler installation folder if you are using F795MX or MZ2048EFH microcontrollers.

b) Does the Rotary_Encoder_Example supposed to be a unit or the program?

Kind regards,
Stefan Filipović

ckelley
Posts: 9
Joined: 14 Feb 2019 22:28

Re: Multiple Topics (Sorry In Advance)

#3 Post by ckelley » 16 Sep 2019 15:37

Stefan, thanks for the response.
  1. From Project > Edit Project > MCU Clock Frequency [MHz], I have configured MZ2048ECH to 200MHz. This is how the project was configured when I saw the issues. To issue a 1 second delay using the Delay_ms library function, I used Delay_ms(1000). However, I see around a a 10-12 second delay instead. From what you are saying, this should work properly, and the configuration that I have was correct.
    • It appears to be functioning incorrectly despite being configured correctly. Are there any other factors that might affect the inaccuracy of the library delay functions?
    • Under the mPascal compiler installation path (\Documents\Mikroelektronika\mikroPascal PRO for PIC32\Schemes for me), there are no schemes for the MZ2048ECH MCU; there are only schemes for the MZ2048EFH MCU. From my understanding, this is probably because the ECH MCU has had issues on the MicroChip side, so there is limited if any support for this MCU directly.
  2. The rotary encoder code posted on my previous post is from LibStock. I downloaded a package that contained the implementation of the rotary encoder code, as well as an example of how to use this code. I currently have a VTFT project using an MZ2048ECH,and I am looking to incorporate a rotary encoder as a part of the visual user interface. The Rotary_Encoder_Example in the package that I downloaded was a program that used the Rotary_Encoder implementation. I was trying to, most likely incorrectly, to use this as a unit in another main program. I'm still getting used to this implementation of Pascal, it a little bit different of a flavor than what I'm used. In the IEC 61131-3 implementation of Pascal that I'm used to, units are Actions and actions can be nested, and share variable scope.
  3. I don't find the help file in the compiler to be of much use for getting started quickly. Is there a e-book guide, similar to the ones you have for C & basic for use with your compiler? It would be really helpful to me.

Thanks for the help,
-Caleb

User avatar
stefan.filipovic
mikroElektronika team
Posts: 1135
Joined: 18 Dec 2018 10:30

Re: Multiple Topics (Sorry In Advance)

#4 Post by stefan.filipovic » 17 Sep 2019 15:11

Hi Caleb,

a) You must adjust PLL configuration in the Edit Project window for your oscillator to get 200MHz MCU clock frequency.
I suggest you open up in some editor the clock scheme for EFH which you can find in the compiler installation path and change the MCU name at the very beginning to P32MZ2048ECH144. After that, you will be able to load that clock scheme in your project.

b) You will need to set implementation section and prototypes of procedures as shown in the first code you've posted here.

Code: Select all

Procedure Init_Rotary_Encoder;  // To be called once before calling Check_Rotary_Encoder
procedure Check_Rotary_Encoder; // To be called every 1 millisecond. The result is in variable Rotary_Direction, see above

implementation
...
c) Unfortunately, there are no ebooks for programming in mikroPascal PRO for PIC32. All available ebooks you can find here.

Kind regards,
Stefan Filipović

Post Reply

Return to “PIC32 PRO Compilers”