Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] A question about the PIC 16F1708

Status
Not open for further replies.

ljcox

Full Member level 5
Joined
Feb 1, 2006
Messages
252
Helped
25
Reputation
50
Reaction score
23
Trophy points
1,298
Location
Melbourne Australia
Activity points
3,110
I used MPLAB 8.92 to write & test a .asm programme for the 16F1708 PIC.

I chose that PIC as it has Interrupt on Change on all inputs.

I have found that IOC only works on PORTA inputs.
When I change one of the PORTC inputs, the IOCCF flag does not change & the PIC won't exit Sleep - as it does for PORTA inputs.

Is this due to a fault in the MPLAB software, or am I missing something?

Any assistance will be appreciated.

Len
 

I've never used that device but it does appear that all pins have IOC ability.
The interrupt on change interrupt should occur and wake the device from sleep whenever any configured input changes state. I assume you have programmed all the individual enable pins and the pins logic level is rising or falling (or both) according to the edge polarity you have programmed. For example, if you have only selected IOC for a rising edge, are you expecting it to interrupt if the pin is grounded? You can enable detection of both edges. Make sure the pins are pulled or driven to the 'idle' state externally and not floating or configured as outputs.

Brian.
 

Hi,

If you really need help, then post your schematic and your code.

Klaus
 

I've never used that device but it does appear that all pins have IOC ability.
The interrupt on change interrupt should occur and wake the device from sleep whenever any configured input changes state. I assume you have programmed all the individual enable pins and the pins logic level is rising or falling (or both) according to the edge polarity you have programmed. For example, if you have only selected IOC for a rising edge, are you expecting it to interrupt if the pin is grounded? You can enable detection of both edges. Make sure the pins are pulled or driven to the 'idle' state externally and not floating or configured as outputs.

Brian.

Thanks Brian, I have done all of that and I change the config from rising edge to falling edge & vice versa as necessary. It works well with PORTA inputs but not PORTC.
I've successfully written code for many other applications using a variety of PICs. I also cleared ANSELA, B & C so the inputs are all digital.

So it appears to be a software fault in MPLAB. I understand that MPLAB 8.92 does not fully support the 16F1708, so I assume that is the issue.

I tried to use MPLABX but could not work out how to use it properly. So it looks as if I'll have to persevere with it & learn the ropes.
Len

- - - Updated - - -

Hi,

If you really need help, then post your schematic and your code.

Klaus

Thanks Klaus. I have had plenty of experience with writing code for a variety of PICs but never for this one. The circuit diagram is not relevant as I am an electronics engineer with plenty of design experience. Also, I have not yet programmed the PIC. I'm using MPLAB to check the code before I do the programming. It works well for PORTA inputs but not PORTC.

Here is the code. I deleted the delay sub routines to make it shorter. To cut a long story short, you will note that I did not use the IOC flags to determine which input has changed, I did it by comparing the current input state with the previous one. I use the IOC simply to awake the PIC from Sleep.

list P=16F1708
#include "p16f1708.inc"

__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _LVP_OFF

prta equ 0x0C ;PORTA
prtb equ 0x0D ;PORTB
prtc equ 0x0E ;PORTC

cblock 0x20
pvi ;Used to store the previous input values

TMR0_k ;constant used in delay routine
count_a ;used in delay routine
count_b ;used in delay routine
count_k
endc

cblock 0x70
tmp ;used in pp1 ~ 6
endc

#define p_1 prta, 5 ;p wire 1 state
#define p_2 prta, 4 ;p wire 2 state

#define p_3 prtc, 5 ;p wire 3 state
#define p_4 prtc, 4 ;p wire 4 state
#define p_5 prtc, 3 ;p wire 5 state
#define p_6 prtc, 6 ;p wire 6 state

#define pv_1 pvi, 1 ;previous p_1 state
#define pv_2 pvi, 2 ;previous p_2 state
#define pv_3 pvi, 3 ;previous p_3 state
#define pv_4 pvi, 4 ;previous p_4 state
#define pv_5 pvi, 5 ;previous p_5 state
#define pv_6 pvi, 6 ;previous p_6 state


#define Q_1 prtc, 2 ;Q1 on to busy P1
#define Q_2 prtc, 1 ;Q2 on to busy P2

#define Q_3 prtc, 0 ;Q3 on to busy P3
#define Q_4 prta, 2 ;Q4 on to busy P4
#define Q_5 prta, 1 ;Q5 on to busy P5
#define Q_6 prta, 0 ;Q6 on to busy P6

#define rls prtc, 7 ;release all p wires

#define tmr0_of INTCON, TMR0IF ;TMR0 overflow (bit 2)
#define c_bit STATUS, C
#define z_bit STATUS, Z

ORG 0x000
call Init

;Programme start
main
call clr_param
call delay_5m

bsf INTCON, 3 ;IOCIE
call clr_flgs ;clear flags
slp nop
sleep
nop

call clr_flgs ;clear flags
call delay_30m ;debounce

btfsc rls ;Release p wire high?
goto ppr ;Yes - process release

;determine which P wire(s)have changed

call pp1 ;process P1
call pp2 ;process P2
call pp3 ;process P3
call pp4 ;process P4
call pp5 ;process P5
call pp6 ;process P6

goto slp

ppr movlw 0x00 ;turn MOSFETs off - tempLC - to be 0x07
movwf prtc ;release P wires 1 ~ 3
movwf prta ;release P wires 4 ~ 6

call delay_100m
btfsc rls ;is rsl p wire still high?
goto $-2 ;Yes - wait

call delay_100m ;repeat to avoid possibility of a spike
btfsc rls ;is release p wire still high?
goto $-2 ;Yes - wait
goto slp ;No

; SUBROUTINES ------------------------------------------------------------------------------

pp1 movlw 0x20
movwf tmp

btfsc pv_1 ;previous P wire 1 (RA5)
goto pb1

btfss p_1 ;is p_1 (RA5) high?
return ;No => no change

btfsc Q_1 ;is Q1 on?
return ;Yes

call chg_a ;No - set the bit in IOCAN & clears same bit in IOCAP
bsf pv_1 ;indicates current value of p_1
return

pb1 btfsc p_1 ;is p_1 (RA5) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_an ;clear relevant bit
bsf Q_1 ;tempLC to be bcf ultimately
bcf pv_1 ;indicates current value of p_1
return
;------------------------------------------------------------------
pp2 movlw 0x10
movwf tmp

btfsc pv_2 ;previous P wire 2 (RA4)
goto pb2

btfss p_2 ;is p_2 (RA4) high?
return ;No => no change

btfsc Q_2 ;is Q2 on?
return ;Yes

call chg_a ;No - set the relevant bit in IOCAN & clears same bit in IOCAP
bsf pv_2 ;indicates current value of p_2
return

pb2 btfsc p_2 ;is p_2 (RA4) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_an ;clear relevant bit
bsf Q_2 ;tempLC to be bcf ultimately
bcf pv_2 ;indicates current value of p_2
return
;-------------------------------------------------------------------
pp3 movlw 0x20
movwf tmp

btfsc pv_3 ;previous P wire 3 (RC5)
goto pb3

btfss p_3 ;is p_3 (RC5) high?
return ;No => no change

btfsc Q_3 ;is Q3 on?
return ;Yes

call chg_c
bsf pv_3 ;indicates current value of p_3
return

pb3 btfsc p_3 ;is p_3 (RC5) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_3 ;tempLC to be bcf ultimately
bcf pv_3 ;indicates current value of p_3
return
;------------------------------
pp4 movlw 0x10
movwf tmp

btfsc pv_4 ;previous P wire 4 (RC4) value
goto pb4

btfss p_4 ;is p_4 (RC4) high?
return ;No => no change

btfsc Q_4 ;is Q4 on?
return ;Yes

call chg_c ;No
bsf pv_4 ;indicates current value of p_4
return

pb4 btfsc p_4 ;is p_4 (RC4) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_4 ;tempLC to be bcf ultimately
bcf pv_4 ;indicates current value of p_4
return
;--------------------------------
pp5 movlw 0x08
movwf tmp

btfsc pv_5 ;previous P wire 5 (RC3) value
goto pb5

btfss p_5 ;is p_5 (RC3) high?
return ;No => no change

btfsc Q_5 ;is Q5 on?
return ;Yes

call chg_c ;No
bsf pv_5 ;indicates current value of p_5
return

pb5 btfsc p_5 ;is p_5 (RC3) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_5 ;tempLC to be bcf ultimately
bcf pv_5 ;indicates current value of p_5
return
;-----------------------------
pp6 movlw 0x40
movwf tmp

btfsc pv_6 ;previous P wire 6 (RC6) value
goto pb6

btfss p_6 ;is p_6 (RC6) high?
return ;No => no change

btfsc Q_6 ;is Q6 on?
return ;Yes

call chg_c ;No
bsf pv_6 ;indicates current value of p_6
return

pb6 btfsc p_6 ;is p_6 (RC6) high?
return ;Yes => no change

call delay_30m ;blink period
call clr_cn ;clear relevant bit
bsf Q_6 ;tempLC to be bcf ultimately
bcf pv_6 ;indicates current value of p_6
return
;-------------------------------------------------------------------
chg_a
banksel IOCAP
movfw tmp
iorwf IOCAN, f ;set respective bit in IOCAN
comf tmp, w
andwf IOCAP, f ;clear respective bit in IOCAP

banksel PORTA
return

chg_c
banksel IOCAP
movfw tmp
iorwf IOCCN, f ;set respective bit in IOCCN
comf tmp, w
andwf IOCCP, f ;clear respective bit in IOCCP

banksel PORTA
return

clr_an
banksel IOCAN
comf tmp, w
andwf IOCAN, f ;clear respective bit in IOCAN

banksel PORTA
return

clr_cn
banksel IOCAF ;selects Bank 7
comf tmp, w
andwf IOCCN, f ;clear respective bit in IOCCN

banksel PORTA
return

clr_flgs ;Clear flag(s) IOCAF & IOCCF
banksel IOCAF ;selects Bank 7
movlw 0xFF
xorwf IOCAF, w
andwf IOCAF, f ;this resets IOCAF - see spec p. 147

movlw 0xFF
xorwf IOCCF, w
andwf IOCCF, f ;this resets IOCCF - see spec p. 147

banksel PORTA ;selects Bank 0
return

clr_param
clrf prta ;tempLC - to be set prta ultimately
clrf prtc ;tempLC - to be set prtc
clrf tmp
clrf pvi
return

Init
banksel TRISA ;selects BANK 1
movlw 0x38
movwf TRISA ;RA5:3 i/p - RA3 is MCLR & not used

clrf TRISB ;RB7:0 o/p
movlw 0xF8
movwf TRISC ;RC7:3 i/p

movlw 0x81 ;prescaler 1:4, internal clock
movwf OPTION_REG ;disable RB pull up resistors

banksel INLVLA ;selects Bank 7
movlw 0x30
movwf INLVLA ;RA5:4 set for Schmitt Trigger

movlw 0x30
movwf IOCAP ;RA5:4 set for positive edge change
clrf IOCAN ;RA5:4 negative edge change not used initially

movlw 0xF8
movwf IOCCP ;RC7:3 set for positive edge change
clrf IOCCN ;RC6:3 negative edge change not used initially

banksel ANSELA ;selects BANK 3
clrf ANSELA
clrf ANSELB
clrf ANSELC

banksel SLRCONA ;selects BANK 6
clrf SLRCONA
clrf SLRCONB
clrf SLRCONC

banksel WPUA ;selects BANK 4
clrf WPUA
clrf WPUB
clrf WPUC

banksel PORTA ;selects BANK 0
movlw 0x00 ;tempLC to be 0x07
movwf PORTA
movwf PORTC ;turn MOSFETs off

bsf INTCON, IOCIE ;bit 3 : awake on IOC
bsf INTCON, TMR0IE ;bit 5 : enable TMR0 overflow
return

end
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top