PDA

View Full Version : Problem converting 12F683 code to 12F1840



RossWaddell
- 13th March 2013, 00:23
I'm trying to port over code from a PIC12F683 to a PIC12F1840 as I need the USART Rx/Tx. I thought I had all the config changes right, but the button connected to MCLR doesn't work (well, at least the display doesn't change so I'm assuming the interrupt isn't being fired) and the LED just stays on - no blinking. Can someone please point me to where I'm going wrong? The code lists the pin connections (the clock is provided from the CLCKOUT/OSC2 pin on a PIC16F690).

PIC12F683 [working]



' ************************************************** *************
' Pin Connections
' ************************************************** *************

' GP0 -> LED output
' GP2 -> Mode Btn input
' GP5 -> CLCKIN (CLCKOUT from PIC16F690)


DEFINE OSC 20 ' Set oscillator 20Mhz

' ************************************************** *************
' Device Fuses
' ************************************************** *************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite

#CONFIG
__config _FOSC_EC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOD_ON & _CP_OFF & _CPD_OFF
#ENDCONFIG

' ************************************************** *************
' Initialization
' ************************************************** *************

GPIO = 0 ' Set initial value of port to 0
CMCON0 = %0000111 ' Turn off comparators
ANSEL.0 = 0 ' Digital only on LED pin
ANSEL.2 = 0 ' Digital only on button pin
ADCON0.0 = 0 ' ADC is disabled
TRISIO = %00100100 ' Make GPIO.2 input for mode button;
' GPIO.5 input for CLCKIN

' The INTEDG bit of the OPTION_REG register determines on which edge the
' interrupt will occur. When the INTEDG bit is set, the rising edge will
' cause the interrupt. When the INTEDG bit is clear, the falling edge will
' cause the interrupt.
OPTION_REG.6 = 1 ' 1=Rising edge (default) or button "PRESS";
' 0=Falling edge or button "RELEASE"

FlashMode_Default CON 0
EE_FlashMode DATA FlashMode_Default
FlashMode VAR BYTE
READ EE_FlashMode, FlashMode

LED_0 VAR GPIO.0 ' Alias GPIO.0 as "LED_0"
DUTY VAR BYTE
CYCLE VAR BYTE
STEP_CNTR VAR BYTE

Old_Flash_Mode VAR BYTE
LGHTS_ON_MS VAR WORD
LGHTS_OFF_MS VAR WORD

' ************************************************** *************
' Includes
' ************************************************** *************

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp3)

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

' ************************************************** *************
' ASM Interrupt Definitions
' ************************************************** *************

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

Cycle = 1

STEP_CNTR = 2


' Set defaults
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates

' Enable interrupt
INTCON = %10010000 ' Global int enabled (GIE), INTE enabled, INTF flag bit 0 clr

@ INT_ENABLE INT_INT ; GP Port Change Interrupt

Main:
' Check if flash mode has changed
IF FlashMode <> Old_Flash_Mode Then
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates
EndIF

' Fade in
For Duty = 0 TO 255 step STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay on LGHTS_ON_MS
HIGH LED_0
Pause LGHTS_ON_MS

' Fade out
For Duty = 255 TO 0 STEP -STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay off for LGHTS_OFF_MS
Pause LGHTS_OFF_MS

GOTO Main

SetFlashRates:
If FlashMode = 0 Then
LGHTS_ON_MS = 1500
LGHTS_OFF_MS = 500
ElseIf FlashMode = 1 Then
LGHTS_ON_MS = 500
LGHTS_OFF_MS = 1500
Else
LGHTS_ON_MS = 750
LGHTS_OFF_MS = 833
EndIf

RETURN

End

' ************************************************** *************
' [INT - interrupt handler]
' ************************************************** *************
Flash_Mode_Btn:
' Toggle flash mode between the 3 values (0, 1 or 2)
FlashMode = FlashMode + 1
If FlashMode > 2 Then FlashMode = 0

' Save selected running light flash mode
WRITE EE_FlashMode, FlashMode
PAUSE 100

INTCON.1 = 0 ' Clear GP2/INT External Interrupt Flag
@ INT_RETURN



PIC12F1840 [not working]



#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use

' ************************************************** *************
' Pin Connections
' ************************************************** *************

' RA0 -> EUSART Tx
' RA1 -> EUSART Rx
' RA2 -> LED output
' RA3 -> Mode Btn input
' RA5 -> CLCKIN (CLCKOUT from PIC16F690)

DEFINE OSC 20 ' Set oscillator 20Mhz

DEFINE HSER_TXSTA 20h ; Set transmit status and control register
DEFINE HSER_BAUD 2400 ; Set baud rate

' ************************************************** *************
' Device Fuses
' ************************************************** *************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite

#CONFIG
__config _CONFIG1, _FOSC_ECH & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG

' ************************************************** *************
' Initialization
' ************************************************** *************

pause 100 ' As advised by Darrel Taylor for EEPROM issue

APFCON.2 = 0 ; Tx on RA0 for LCD display
APFCON.7 = 0 ; Rx on RA1

BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin

FVRCON = 0
ANSELA.2 = 0 ' Digital only on LED pin
ANSELA.3 = 0 ' Digital only on button pin
ADCON0.0 = 0 ' ADC is disabled
TRISA = %00001010 ' Make RA1 & RA3 input for Rx & mode button

' The INTEDG bit of the OPTION_REG register determines on which edge the
' interrupt will occur. When the INTEDG bit is set, the rising edge will
' cause the interrupt. When the INTEDG bit is clear, the falling edge will
' cause the interrupt.
OPTION_REG.6 = 1 ' 1=Rising edge (default) or button "PRESS";
' 0=Falling edge or button "RELEASE"

FlashMode_Default CON 0
EE_FlashMode DATA FlashMode_Default
FlashMode VAR BYTE
READ EE_FlashMode, FlashMode

LED_0 VAR PORTA.2 ' Alias PORTA.2 as "LED_0"
DUTY VAR BYTE
CYCLE VAR BYTE
STEP_CNTR VAR BYTE

Old_Flash_Mode VAR BYTE
LGHTS_ON_MS VAR WORD
LGHTS_OFF_MS VAR WORD

#IFDEF USE_LCD_FOR_DEBUG
LCD_INST CON 254 ' Instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
#ENDIF

' ************************************************** *************
' Includes
' ************************************************** *************

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp3)

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

' ************************************************** *************
' ASM Interrupt Definitions
' ************************************************** *************

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

Cycle = 1

STEP_CNTR = 2

' Set defaults
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates

' Enable interrupt
INTCON = %10010000 ' Global int enabled (GIE), INTE enabled, INTF flag bit 0 clr

@ INT_ENABLE INT_INT ; GP Port Change Interrupt

#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["FlashMode=", DEC FlashMode, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF

Main:
' Check if flash mode has changed
IF FlashMode <> Old_Flash_Mode Then
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates
EndIF

' Fade in
For Duty = 0 TO 255 step STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay on LGHTS_ON_MS
HIGH LED_0
Pause LGHTS_ON_MS

' Fade out
For Duty = 255 TO 0 STEP -STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay off for LGHTS_OFF_MS
Pause LGHTS_OFF_MS

GOTO Main

SetFlashRates:
If FlashMode = 0 Then
LGHTS_ON_MS = 1500
LGHTS_OFF_MS = 500
ElseIf FlashMode = 1 Then
LGHTS_ON_MS = 500
LGHTS_OFF_MS = 1500
Else
LGHTS_ON_MS = 750
LGHTS_OFF_MS = 833
EndIf

#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["FlashMode=", DEC FlashMode, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF

RETURN

End

' ************************************************** *************
' [INT - interrupt handler]
' ************************************************** *************
Flash_Mode_Btn:
' Toggle flash mode between the 3 values (0, 1 or 2)
FlashMode = FlashMode + 1
If FlashMode > 2 Then FlashMode = 0

' Save selected running light flash mode
WRITE EE_FlashMode, FlashMode
PAUSE 100

INTCON.1 = 0 ' Clear GP2/INT External Interrupt Flag
@ INT_RETURN

HenrikOlsson
- 13th March 2013, 06:24
I thought I had all the config changes right, but the button connected to MCLR doesn't work (well, at least the display doesn't change so I'm assuming the interrupt isn't being fired) and the LED just stays on - no blinking.
I'm confused....
Your code sets up DT-Ints to use INT_INT as the interrupt source for your handler but you say that you have the button connected to MCLR (RA3) which is not the INT-pin. RA3 has Interrupt on change capability and the comment at the INT_ENABLE says you're enabling IOC interrupt but you aren't.

I'm pretty sure that you don't need to (or even should) set the GIE or INTE bits when using DT-INTS, it handles all that for you via the @ INT_ENABLE macro. You also don't need to clear the interrupt flag in the handler since you've asked DT-Ints to do that for you.

/Henrik.

Ioannis
- 13th March 2013, 13:46
Also your clock is internal or external?

Ioannis

RossWaddell
- 13th March 2013, 14:53
Also your clock is internal or external?

Ioannis
I'm using an external clock configuration (hence FOSC_ECH) - the CLCKOUT/OSC2 pin from a PIC16F690 (which has a 20Mhz crystal connected to OSC1 & OSC2) connects to the PIC12F1840's CLCKIN/OSC1 pin.

RossWaddell
- 13th March 2013, 15:00
I'm confused....
Your code sets up DT-Ints to use INT_INT as the interrupt source for your handler but you say that you have the button connected to MCLR (RA3) which is not the INT-pin. RA3 has Interrupt on change capability and the comment at the INT_ENABLE says you're enabling IOC interrupt but you aren't.

I'm pretty sure that you don't need to (or even should) set the GIE or INTE bits when using DT-INTS, it handles all that for you via the @ INT_ENABLE macro. You also don't need to clear the interrupt flag in the handler since you've asked DT-Ints to do that for you.

/Henrik.

Thanks Henrik. There are only 6 I/O pins on the 12F1840 and in trying to keep the EUSART Rx/Tx pins free I mistakenly connected the button input to RA3/MCLR (I do that for another code project). I do indeed want to use the INT interrupt, regardless of the comment. I've rejigged the code to this (I'm not at home so I haven't tested it yet):



#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use

' ************************************************** *************
' Pin Connections
' ************************************************** *************

' RA0 -> EUSART Tx
' RA1 -> EUSART Rx
' RA2 -> Mode Btn input (INT interrupt)
' RA4 -> LED_0
' RA5 -> CLCKIN (CLCKOUT from PIC16F690)

DEFINE OSC 20 ' Set oscillator 20Mhz

DEFINE HSER_TXSTA 20h ; Set transmit status and control register
DEFINE HSER_BAUD 2400 ; Set baud rate

' ************************************************** *************
' Device Fuses
' ************************************************** *************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite

#CONFIG
__config _CONFIG1, _FOSC_ECH & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG

' ************************************************** *************
' Initialization
' ************************************************** *************

pause 100 ' As advised by Darrel Taylor for EEPROM issue

APFCON.2 = 0 ; Tx on RA0 for LCD display
APFCON.7 = 0 ; Rx on RA1

BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin

FVRCON = 0
ANSELA.2 = 0 ' Digital only on button pin
ANSELA.4 = 0 ' Digital only on LED pin
ADCON0.0 = 0 ' ADC is disabled
TRISA = %00000110 ' Make RA1 & RA2 input for Rx & mode button

' The INTEDG bit of the OPTION_REG register determines on which edge the
' interrupt will occur. When the INTEDG bit is set, the rising edge will
' cause the interrupt. When the INTEDG bit is clear, the falling edge will
' cause the interrupt.
OPTION_REG.6 = 1 ' 1=Rising edge (default) or button "PRESS";
' 0=Falling edge or button "RELEASE"

FlashMode_Default CON 0
EE_FlashMode DATA FlashMode_Default
FlashMode VAR BYTE
READ EE_FlashMode, FlashMode

LED_0 VAR PORTA.4 ' Alias PORTA.4 as "LED_0"
DUTY VAR BYTE
CYCLE VAR BYTE
STEP_CNTR VAR BYTE

Old_Flash_Mode VAR BYTE
LGHTS_ON_MS VAR WORD
LGHTS_OFF_MS VAR WORD

#IFDEF USE_LCD_FOR_DEBUG
LCD_INST CON 254 ' Instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
#ENDIF

' ************************************************** *************
' Includes
' ************************************************** *************

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp3)

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

' ************************************************** *************
' ASM Interrupt Definitions
' ************************************************** *************

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

Cycle = 1

STEP_CNTR = 2

' Set defaults
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates

; Henrik Olson says I don't need this
; -----------------------------------
;INTCON = %10010000 ' Global int enabled (GIE), INTE enabled, INTF flag bit 0 clr
; -----------------------------------

;INTCON = %10010000 ' Global int enabled (GIE), INTE enabled, INTF flag bit 0 clr

' Enable interrupt
@ INT_ENABLE INT_INT ; GP Port Change Interrupt

#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["FlashMode=", DEC FlashMode, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF

Main:
' Check if flash mode has changed
IF FlashMode <> Old_Flash_Mode Then
Old_Flash_Mode = FlashMode
GOSUB SetFlashRates
EndIF

' Fade in
For Duty = 0 TO 255 step STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay on LGHTS_ON_MS
HIGH LED_0
Pause LGHTS_ON_MS

' Fade out
For Duty = 255 TO 0 STEP -STEP_CNTR
PWM LED_0, Duty, Cycle
Next

' Stay off for LGHTS_OFF_MS
Pause LGHTS_OFF_MS

GOTO Main

SetFlashRates:
If FlashMode = 0 Then
LGHTS_ON_MS = 1500
LGHTS_OFF_MS = 500
ElseIf FlashMode = 1 Then
LGHTS_ON_MS = 500
LGHTS_OFF_MS = 1500
Else
LGHTS_ON_MS = 750
LGHTS_OFF_MS = 833
EndIf

#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["FlashMode=", DEC FlashMode, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF

RETURN

End

' ************************************************** *************
' [INT - interrupt handler]
' ************************************************** *************
Flash_Mode_Btn:
' Toggle flash mode between the 3 values (0, 1 or 2)
FlashMode = FlashMode + 1
If FlashMode > 2 Then FlashMode = 0

' Save selected running light flash mode
WRITE EE_FlashMode, FlashMode
PAUSE 100

INTCON.1 = 0 ' Clear RA2/INT External Interrupt Flag
@ INT_RETURN


I've commented out the line re: set the GIE or INTE bits but left the clearing of the interrupt flag in my handler. Are you sure I don't need that?

HenrikOlsson
- 13th March 2013, 16:24
OK, give it a try and see if it springs to life.


I've commented out the line re: set the GIE or INTE bits but left the clearing of the interrupt flag in my handler. Are you sure I don't need that?



ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _Flash_Mode_Btn, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

Since you have the ResetFlag "switch" set to Yes, then no you shouldn't have to reset the flag manually. I don't think there's any harm in doing it though, except wasting execution cycles.

/Henrik.

RossWaddell
- 13th March 2013, 17:02
Thanks so much, Henrik - I greatly appreciate the help. I'll try it without the clearing the interrupt flag too.

RossWaddell
- 14th March 2013, 01:55
It's alive! It's alive!

Noobie mistakes there, so thanks for being patient.