News:

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

Main Menu

Problem with PIC16F15324

Started by Georgi, Jul 14, 2022, 03:32 PM

Previous topic - Next topic

Georgi

Hello,

I came across the PIC16F15324 and decided to try it, but I have the following problem.
When I use Interrupt, this part of the program is not executed:
main:
     High LATC.4
GoTo main

but this works fine:
Toggle LATC.1

When I turn off Interrupt, this part works:
main:
     High LATC.4
GoTo main

I don't know if I managed to explain the problem.
I'm making a mistake somewhere, but I can't find where. Please for your help.

This will save the text of your post, but it will not save attachments, poll or event information.

Georgi

Unfortunately when I try to publish the program it gives me an error.

top204

#2
Remove any percentage characters from your code and use "0b" instead, for binary values.

I have been on to the domain a few times and they have allowed some through, but some still cause the error.

Georgi

Device = 16F15324

Config1 FEXTOSC_OFF, RSTOSC_HFINT32, CLKOUTEN_OFF, CSWEN_ON, FCMEN_ON
Config2 MCLRE_OFF, PWRTE_ON, LPBOREN_OFF, BOREN_ON, BORV_LO, ZCD_OFF, PPS1WAY_OFF, STVREN_ON
Config3 WDTCPS_WDTCPS_31, WDTE_OFF, WDTCWS_WDTCWS_7, WDTCCS_SC
Config4 BBSIZE_BB512, BBEN_OFF, SAFEN_OFF, WRTAPP_OFF, WRTB_OFF, WRTC_OFF, WRTSAF_OFF, LVP_OFF
Config5 CP_ON

Declare Xtal = 4

Dim TICKS       As Byte
Dim X           As Byte

    OSCCON1 = 0b00000011 '

    CM1CON0.7 = 0 ' Comparator 1 off
    CM2CON0.7 = 0 ' Comparator 2 off

    ANSELA = 0b00000000      ' PORTA - digital
    ANSELC = 0b00000000     ' PORTC - digital

    T0CON0 = 0b10000000 'TMR0 enable, 8-bit timer, no postscaler
    T0CON1 = 0b01000110 'clock source = Fosc/4, prescaler rate = 1:64
    TMR0 = 0                ' Clear TMR0 MODULE REGISTER
   
    TRISA = 0b00000000             
    TRISC = 0b00000000
    LATA = 0b00000000
    LATC = 0b00000000   
               
    INTCON.7 = 1 ' global interrupt enable
    INTCON.6 = 1 ' peripheral interrupt enable
    PIE0.5 = 1 ' TMR0 interrupt enable

    On Interrupt GoTo tickint

    DelayMS 100
   
main:
    High LATC.4
 
    GoTo main   


    Disable
tickint:
    TICKS = TICKS + 1
   
    If TICKS < 75 Then tiexit
    TICKS = 0
    Toggle LATC.1
       
tiexit:
    PIR0.5 = 0
    Resume
             
End

Georgi

Quote from: top204 on Jul 14, 2022, 03:38 PMRemove any percentage chaarcters from your code and use "0b" instead, for binary values.

I have been on to the domain a few times and they have allowed some throug, but some still cause teh error.
Thank you, I was able to post the program.

trastikata

Quote from: Georgi on Jul 14, 2022, 03:48 PMThank you, I was able to post the program.

Is this the entire program, or just the parts you think are causing a problem?

Georgi

This is the program I use to find the problem. When I turn on the interrupt, the main program doesn't run ie. this line - High LATC.4. But I can see that the interrupt is executed because every 76 logins this line is executed - Toggle LATC.1.

When I don't use an interrupt, this line of the main program executes - High LATC.4.

This is my first time using this microcontroller, and I'm clearly making a mistake.
Where could the problem be?

Stephen Moss

I think there are a few things wrong here...
1) At best I think On Interrupt Goto should be On_Interrupt Goto, that said I think that is now a legacy and On_Hardware_Interrupt should be used (High priority interrupt on 18F devices, normal interrupt on non 18F)
2) I don't recall Disable and Resume being compiler commands, and if they are I doubt disable is used alone and Resume is not a normal termination for an interrupt routine.
3) It is always wise to use Context Save/Restore when it comes to interrupt handlers, see the interrupt section of the manual beginning page 458.
4) You have an If statement in your ISR with no corresponding EndIF

See if this works better
    On_Interrupt GoTo tickint

    DelayMS 100
 
main:
    High LATC.4
 
    GoTo main 

tickint:
Context Save
    TICKS = TICKS + 1
 
    If TICKS < 75 Then
      PIR0.5 = 0
    Else
      TICKS = 0
      Toggle LATC.1
    EndIf
Context Restore
           
End




Georgi

Thanks Stephen Moss. That's how it works.

It's weird, I've always used it that way. Ever since I bought the Proton, and now when I bought the Positron. The last microcontrollers I used are 16F18313, 16F18324, 16F18325. It works for them too. But, with this PIC16F15324 it didn't work.
It doesn't matter, I already solved the problem. Once again thank you.

John Lawton

You've been using the (old) PicBasic Pro syntax!

John

top204

Even with the original, and now redundant, Software Interrupt mechanism, the contexts still have to be saved and restored, otherwise, the code will overwrite SFRs and other variables. Just what it will overwrite depends on the program and the device used.

The Software interrupt mechanism is no longer valid in the compiler and will eventually be dropped altogether, because it is a very, very innefficient way of doing things, and was to replicate what the PBP did when people were transfering over from it. And when I developed the hardware interrupt mechanism for the compilers that did everyting for the user, so nothing would get overwritten, I decided to drop the software interrupt. It is, also, no longer in the manual. 

Georgi

Now I remember that before I bought the Proton, I used PicBasic Pro. It was a long time ago, but now due to a lack of microcontrollers I have to rewrite the programs for those I find. Usually old microcontrollers are either very expensive or not available at all.
This is good, one must develop and always learn something new.

top204

The hardware interrupt mechanism works on all device types that have an interrupt capability. i.e. Standard 14-bit core devices, enhanced 14-bit core devices, 18F devices, PIC24 devices, and dsPIC33 devices.


Georgi

Not to open a new topic, I will describe the problem here.
Until now I used microcontrollers with EEPROM, but now they are hard to find. I currently have a PIC16F15324 to sample.
The program that is here is in a shortened version. The idea is as follows. I have a button, when pressed, one of the programs is selected. The selection is saved so that when the power is turned on, it starts with the program already selected.

...
Dim B1  As Byte
Dim MODE As Byte
...

MODE = ERead 0

main:
    Button Butt,0,0,0,B1,0,loop1
        MODE = MODE + 1
        If MODE > 17 Then MODE = 0
        EWrite 0, [MODE]

loop1:
...

goto main

epp:
    EData 0
    Return

end

The problem is that this microcontroller has no EEPROM. I read on the forum about HEF memory, but I can't figure it out.

trastikata

Quote from: Georgi on Jul 24, 2022, 10:01 AMThe problem is that this microcontroller has no EEPROM. I read on the forum about HEF memory, but I can't figure it out.

Enable the SAF by setting WRTSAF = 1 (Storage Area Flash Write Protection bit) and SAFEN = 0  (SAF Enable bit).
Make sure your program is not occupying the upper 128 words.
Use SAF by first erasing a FLASH row on the 32 words boundary in the SAF
Write in the same SAF area over any previously erased and unprogrammed location
Read that FLASH address in your program whenever needed.
 

tnencon

Greetings to everyone;
I tried to write NVM read write and erase procedures for PIC16F15344. If anyone has the chance to try it, I would appreciate it if you could let me know the results.
I didn't have a chance to try it because I didn't have the PIC16F15344. Thanks in advance...

'*******************************************************************
Proc NVM_Write(NVM_Adress As Word,NVM_Data As Word)
'*******************************************************************
'Before writing to PFM, the word(s) to be written must
'be erased or previously unwritten. PFM can only be
'erased one row at a time. No automatic erase occurs
'upon the initiation of the write to PFM.
'*******************************************************************
    Dim GIEBitValue As Bit
    GIEBitValue = INTCONbits_GIE
    INTCONbits_GIE = 0
   
    PFM_Erase(NVM_Adress)
   
    NVMCON1bits_NVMREGS = 0 ' Deselect Configuration space
    NVMCON1bits_WREN = 1 ' Enable wrties
    NVMCON1bits_LWLO = 1 ' Only load write latches
    NVMADRL = NVM_Adress.LowByte
    NVMADRH = NVM_Adress.HighByte
    NVMDATL = NVM_Data.LowByte
    NVMDATH = NVM_Data.HighByte
    NVMCON1bits_LWLO = 0
    NVMCON2 = $55
    NVMCON2 = $AA
    NVMCON1bits_WR = 1
    Nop
    Nop
    INTCONbits_GIE = GIEBitValue
EndProc
'*******************************************************************
Proc PFM_Erase(NVM_Adress As Word)
    Dim GIEBitValue As Bit
    GIEBitValue = INTCONbits_GIE
    INTCONbits_GIE = 0 
    NVMADRL = NVM_Adress.LowByte
    NVMADRH = NVM_Adress.HighByte
    NVMCON1bits_NVMREGS = 0' Deselect Configuration space
    NVMCON1bits_FREE = 1' Specify an erase operation
    NVMCON1bits_WREN = 1' Allows erase cycles
    NVMCON2 = $55
    NVMCON2 = $AA
    NVMCON1bits_WR = 1
    Nop
    Nop
    NVMCON1bits_WREN = 0' Disable writes
    INTCONbits_GIE = GIEBitValue
EndProc
'******************************************************************* 
Proc NVM_Read(NVM_Adress As Word), Word                 
    Dim GIEBitValue As Bit
    GIEBitValue = INTCONbits_GIE
    INTCONbits_GIE = 0 
    NVMADRL = NVM_Adress.LowByte
    NVMADRH = NVM_Adress.HighByte
    NVMCON1bits_NVMREGS = 0' Deselect Configuration space
    NVMCON1bits_RD = 1' Initiate Read
    Nop
    Nop
    INTCONbits_GIE = GIEBitValue' Restore interrupt enable
    Result.LowByte = NVMDATL
    Result.HighByte = NVMDATH
 
EndProc

JonW