News:

Let's find out together what makes a PIC Tick!

Main Menu

dsPIC33EP256MU806 - TIMER1 problem [SOLVED]

Started by trastikata, Feb 07, 2023, 09:26 PM

Previous topic - Next topic

trastikata

Hello,

Just started working with dsPIC33EP256MU806 and testing some functionality, but I can't get the TIMER1 working as it should.

In the following test program the LED should go ON for 1 second then OFF for 3 seconds and start blinking fast. However after the LED went ON and OFF as it should, it turns ON and stays ON.

It looks like as if the program doesn't return from the ISR or does not reset the TMR1 Interrupt Flag. Maybe I am missing something?

Device = 33EP256MU806

Config FGS = GSS_OFF, GSSK_OFF, GWRP_OFF
Config FOSCSEL = FNOSC_PRIPLL, IESO_OFF
Config FOSC = FCKSM_CSDCMD, IOL1WAY_OFF, OSCIOFNC_ON, POSCMD_HS
Config FWDT = FWDTEN_OFF, PLLKEN_OFF, WDTPOST_PS32768, WDTPRE_PR128, WINDIS_OFF
Config FPOR = ALTI2C1_OFF, BOREN_OFF, FPWRT_PWR1
Config FICD = ICS_PGD1, JTAGEN_OFF, RSTPRI_PF
Config FAS = APL_OFF, APLK_OFF, AWRP_OFF

Declare Xtal = 140

Symbol LED = PORTB.3
Output LED

GoTo Main

Isr T1Interrupt
    Toggle LED
    TMR1 = 0        'Clear Timer1
    IFS0.3 = 0      'TMR1IF clear          
EndIsr

Main:
    SetOscillator()
    SetTimer1()
   
    High LED : DelayMS 1000
    Low LED : DelayMS 3000
   
    T1CON.15 = 1                'TMR1 on
   
    While 1 = 1 : Wend
   
 
 Proc SetOscillator()
    'Crystal = 24 MHz --> 140MHz Fp
    CLKDIV = %0000000000000001  'PLLPRE = 1 ; PLLPOST = 0
    PLLFBD = %0000000000100001  'PLLDIV = 33
EndProc

Proc SetTimer1()
    INTCON2.15 = 1              'GIE = 1
    TMR1 = 0                    'Clear Timer1
    PR1 = 60000                 'Period = xxx ms
    T1CON = %0000000000110000   'PS: 256
    IFS0.3 = 0                  'TMR1IF clear
    IPC0.14 = 0                 'IP = 1
    IPC0.13 = 0
    IPC0.12 = 1
    IEC0.3 = 1                  'T1IE = 1
EndProc


trastikata

Quote from: trastikata on Feb 07, 2023, 09:26 PMMaybe I am missing something?

Hmm, if I Toggle the LED, the LED stays high, but if I use a bit variable and High and Low the LED, then it works? I've posted the two codes not working and working, maybe an anomaly?

This doesn't work - when I use Toggle the LED stays ON.

Symbol LED = PORTB.3
Output LED

Isr T1Interrupt
    Toggle LED
    TMR1 = 0        'Clear Timer1
    IFS0.3 = 0      'TMR1IF clear           
EndIsr

But this works when I use a bit variable and High and Low the LED:

Symbol LED = PORTB.3
Output LED

Dim pB1 As Bit

Isr T1Interrupt
    Inc pB1
   
    If pB1 = 0 Then Low LED
    If pB1 = 1 Then High LED
   
    TMR1 = 0        'Clear Timer1
    IFS0.3 = 0      'TMR1IF clear           
EndIsr

Gamboa

Hi,
To do that I use LED = ~LED

Regards,
Gamboa
Long live for you

SCV

#3
or

LED = 1 - LEDAlso change the definition of LED to LED = Symbol LATB.5
In my Timer1 ISR I don't reset the TMR1.
'Setup timer 1 for 1mS period @ 140Mhz
                TMR1 = 0
                PR1 = 8750                                   ' Load Timer1 period for 1mS
                T1CON = %1010000000010000                    ' Start Timer1, div 8, int clock
                T1IF = 0                                     ' Reset the Timer1 flag
                T1IE = 1                                     ' Enable the interrupt

'===========================================
'   Interrupt routines here
'===========================================
Isr- T1Interrupt
COUNTER1:   UPDATE_1mS_FLAG = 1
            'Other stuff here

            T1IF = 0                           ' Reset the Timer1 interrupt flag
EndIsr-


'================================================

John Lawton

Quote from: trastikata on Feb 07, 2023, 09:26 PMMaybe I am missing something?

An interesting problem!

Gamboa's method should also work, does it?

I usually use LAT instead of PORT for outputs because of the read-modify-write issues
as described in: https://ww1.microchip.com/downloads/en/DeviceDoc/70000598c.pdf

- although I don't know whether that is the issue here.

Incidentally the timers are also complex. Microchip have a guide for this which might be useful: https://ww1.microchip.com/downloads/en/DeviceDoc/S11.pdf


tumbleweed

QuoteHmm, if I Toggle the LED, the LED stays high, but if I use a bit variable and High and Low the LED, then it works?
John's onto something with using LAT instead of PORT, although not because of RMW.

The compiler's setup for that chip is setting all the pins to analog mode, so when you do a toggle on the PORT pin it always reads a '0' and the pin output gets set.
'High' and 'Low' don't read the pin state first... they just set the LAT register.

from the startup code:
    setm.w ANSELB
    setm.w ANSELC
    setm.w ANSELD
    setm.w ANSELE
    setm.w ANSELG
'setm.w' should be 'clr.w' to set the pins to digital.


John Lawton

Yes, ANSELB will have to be cleared.

With many parts you can't offer a simple bit of code to flash an LED without all the configuration code as well, or it probably won't work :)

trastikata

Thank you all for the help.

Indeed the problem was with the analog function. Manually clearing ANSELB resolves the issue with the Toggle command.

I have used "Declare All_Digital = True" and assumed it would have taken care of the analog ports but it seems the command is not working.

Did Les remove that declare command or this is a bug?

John Lawton

Quote from: trastikata on Feb 08, 2023, 04:51 PMI have used "Declare All_Digital = True" and assumed it would have taken care of the analog ports but it seems the command is not working.

Did Les remove that declare command or this is a bug?
I don't believe he has, however I don't use it. I recall him saying it may not work with all devices (because Microchip love to move the goalposts), so I think it is better to configure the PIC I/O by hand.

The ANSEL registers have been present for some time, I came across them when I used the 18F25K22 series (and wondered why digital I/O didn't work). Why they don't default to zero is a mystery.

tumbleweed

Pins default to analog mode in case the voltage on the pin isn't a valid logic level which could cause the input stage to oscillate or increase current consumption.

It's a pain, but since they all do that it's one of the first things to check since the registers and settings change from device to device.

Stephen Moss

Quote from: trastikata on Feb 08, 2023, 04:51 PMI have used "Declare All_Digital = True" and assumed it would have taken care of the analog ports but it seems the command is not working.
The All_Digital declare was rendered obsolete quite sometime ago now and produces no code, I believe it does produce a warning message at compile time to that effect. It is only really retained for backwards compatibility so that errors are not thrown up when compiling older code.

It was rendered obsolete due to the fact the compiler was altered to automatically set all pins to digital at compile time, of course there is always the possibility that it will not work either because of an simple error or that something was missed due to any changes Microchip may have made in how that is handled from one device to another.
Personally, I always set the relevant registers in code myself anyway just to be sure I know what state they are in.         

John Lawton

Quote from: Stephen Moss on Feb 09, 2023, 08:49 AMThe All_Digital declare was rendered obsolete quite sometime ago now and produces no code, I believe it does produce a warning message at compile time to that effect. It is only really retained for backwards compatibility so that errors are not thrown up when compiling older code.

No code generated, but I get no warning messages either when compiling for a PIC18F24J50

QuoteIt was rendered obsolete due to the fact the compiler was altered to automatically set all pins to digital at compile time, of course there is always the possibility that it will not work either because of an simple error or that something was missed due to any changes Microchip may have made in how that is handled from one device to another.       
It's news to me that the compilers sets all the I/O to digital inputs :)
Anyway, I agree it is better to do the config manually and that way you learn more about the device as you have to scour the datasheet to do so!

John

trastikata

I too normally set all port registers manually, but this time because it was simple code test I decided to declare All_Digital = True for the ease of use.

After that it never crossed my mind that it might be not working and thus the reason for the "strange" behavior. Anyway, thank you all for the help.

top204

#13
Microchip constantly change what setting will change a pin from analogue to digital and vice-versa. For some devices it is cleared for digital mode and some others it is set for digital mode. ?? :-O

I got so fed up with it and the logistics of adding to a dynamic mechanism were too much, so I had to remove the All_Digital directive, and created a pseudo mechanism to write the SFRs that need writing in the device's .def file when they are created, so it will run before the user's program starts.

But, I am only human and I do get somethings incorrect with some of the more obscure devices, or I do not have the time to scour all the datasheets.

However, this means the SFRs can be easily changed, and the forum notified that changes are required, or a new .def file uploaded for users to use. For example, near the end of the 33EP256MU806.def file is the code:

'
'----------------------------------------------------------------------------------
' Make analogue pins digital
' This section may be added too for extra SFRs
'
#IfnSym __SYSCOM_LIBRARY_OFF_       ' Has the library been disabled in the compiler?
    PMCON = 0
    PADCFG1bits_PMPTTL = 1
    ANSELB = $FFFF
    ANSELC = $FFFF
    ANSELD = $FFFF
    ANSELE = $FFFF
    ANSELG = $FFFF
#EndIfSym

So this needs to be changed to:

'
'----------------------------------------------------------------------------------
' Make analogue pins digital
' This section may be added too for extra SFRs
'
#IfnSym __SYSCOM_LIBRARY_OFF_      ' Has the library been disabled in the compiler?
    PMCON = 0
    PADCFG1bits_PMPTTL = 1
    ANSELB = $0000
    ANSELC = $0000
    ANSELD = $0000
    ANSELE = $0000
    ANSELG = $0000
#EndIfSym

And saved. But make sure it is edited with notepad or something similar, because a word processor will add invisible command characters to the file.

Once saved, it will always alter the correct SFRs before program start-up, and if notified on the forum, I will make the changes to the .def file for the next update.

The same changes can be made to the family that a device belongs too, but check the datasheets first because microchip change for the sake of change, even on the same device family. The SFRs are in all relevant 8-bit and 16-bit device .def files.