Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

A question about the PIC 16F1708

Status
Not open for further replies.

ljcox

Well-Known Member
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.

However, 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
 
Have you set ANSELC to zero. It defaults to analogue.

Mike.
Edit, also check out section 13-7 of the datasheet.
 
Last edited:
Thanks Mike. Yes I had ANSELC set to 0. I've been caught by that type of issue before with other PICs so I was aware of it.
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
 
Thanks Mike. Yes I had ANSELC set to 0. I've been caught by that type of issue before with other PICs so I was aware of it.
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

MPLABX is fine once you get used to it, and I find it better than 8.92 after a while of using it. I too was keen on sticking to 8.92 for far longer than I should have.

It's unlikely to be a fault in 8.92, as that's just an IDE feeding a separate assembler/linker - X may well use the same assembler/linker (I've never looked - or cared :D).

It's more likely to be a problem somewhere in your code, or your understanding of the datasheet, I've never used the device in question, but I'm assuming IOC is supported by port C? - historically IOC was only on port B (in fact it was always called 'interrupt on change on port B'. There may well be something (or a number of things) you need to disable, or enable, in order to use it.
 
MPLAB8.xx does support that chip... There are many registers associated with IOC on that chip... Negative / positive edge detect.. Change detect will only happen if you clear it properly... You have to Xor then and the port to clear the previous change...

Post your code or snippet of code so we can see...
 
MPLABX is fine once you get used to it, and I find it better than 8.92 after a while of using it. I too was keen on sticking to 8.92 for far longer than I should have.

It's unlikely to be a fault in 8.92, as that's just an IDE feeding a separate assembler/linker - X may well use the same assembler/linker (I've never looked - or cared :D).

It's more likely to be a problem somewhere in your code, or your understanding of the datasheet, I've never used the device in question, but I'm assuming IOC is supported by port C? - historically IOC was only on port B (in fact it was always called 'interrupt on change on port B'. There may well be something (or a number of things) you need to disable, or enable, in order to use it.
Thanks Nigel, I beg to differ. I have been using PICs for at least 15 years & have written dozens of PIC programmes & testing them successfully in MPLAB using a variety of PICs. This is the first time I've used the 16F1708. I'm using it as it has IOC on all ports.
If you look at the first thumbnail, it is an extract from the spec, all of the flags of all IOC, i.e. A, B & C go into the OR gate & if IOCIE is set they will wake the PIC from sleep.

But I found that a change to PORTA will cause it to exit sleep but the flags of PORTB & PORTC do not change when I change an input to these ports. The second thumbnail is an extract from the Initiation sub routine. As you can see, I have activated both IOCA & IOCC. The third thumbnail shows some temporary code (red arrow) I inserted to test and the results (green arrows). Only IOCAF changed.

Y es, I may have missed something, but I don't think so as it seems odd that IOC works for PORTA but not for B or C. I can post more of the code if you wish. I'll be grateful for any ideas you may have.

IOC.jpg Init.jpg mpl.jpg
 
Len, it looks like you're using the simulator. Can you try it on actual hardware?

Mike.
 
MPLAB8.xx does support that chip... There are many registers associated with IOC on that chip... Negative / positive edge detect.. Change detect will only happen if you clear it properly... You have to Xor then and the port to clear the previous change...

Post your code or snippet of code so we can see...
Thanks Ian. I read somewhere that the 16F1708 is not fully supported by 8.92 but I can't recall where. I posted some of the code in my response to Nigel above.

I have attached the sub routines that change the IOC settings & the last one that clears the flags below.

However, I don't think the changing & clearing is relevant to the issue because, in all the testing and experimenting I have done, I have never seen an IOC flag change for PORTs B or C.

See the third thumbnail in my reply to Nigel. I'll be grateful for any ideas you have.

shg sr.jpg
 
Len, it looks like you're using the simulator. Can you try it on actual hardware?

Mike.
Thanks Mike. Yes, that is my next step. But I won't be able to do it today. It will have to wait until at least Friday. I'll let you all know the result.
 
MPLABX is fine once you get used to it, and I find it better than 8.92 after a while of using it. I too was keen on sticking to 8.92 for far longer than I should have.

It's unlikely to be a fault in 8.92, as that's just an IDE feeding a separate assembler/linker - X may well use the same assembler/linker (I've never looked - or cared :D).

It's more likely to be a problem somewhere in your code, or your understanding of the datasheet, I've never used the device in question, but I'm assuming IOC is supported by port C? - historically IOC was only on port B (in fact it was always called 'interrupt on change on port B'. There may well be something (or a number of things) you need to disable, or enable, in order to use it.
I decided to try MPLABX again but ran into the same brick wall.The first thumbnail shows an extract from the "Converting an MPLAB 8 Project to MPLABX". But When I followed this procedure the window I saw is shown in the second thumbnail. The last time I tried to use X, I chose one of the options but it did not work. I don't recall what else I did but nothing worked. The Help was no help as they talk in MPLAB jargon much of which is meaningless to me. Any guidance will be appreciated.
 

Attachments

  • Convert 3a.jpg
    Convert 3a.jpg
    614.8 KB · Views: 377
  • MPLAB X 1.jpg
    MPLAB X 1.jpg
    110 KB · Views: 321
Ian, thanks for the offer.
This site has changed since I last used it. I presume the "Conversation" is the new PM.
So I started one & copied the code into it. I could not see how to attach the .asm file to the conversation.
 
just post it between code tags... I can copy it then
Thanks Ian, Here it is. I'm using RA5:4 & RC7:3 as inputs with IOC. To cut a long story short, I decided to not use the IOC flags to determine which input has changed. I do it in the sub routines pp1 ~ pp6. I hope you can find something I missed.

Code:
;Group Selector busier.
;internal 4 MHz oscillator
    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 rls        prtc, 7        ;release all p wires
#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 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
slp    call    clr_flgs    ;clear flags
    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
      
;Delay Sub Routines
delay_100m
    movlw    d'100'        ;delay 100 mS
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_50m      
    movlw    d'50'        ;delay 50 mS
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_30m  
    movlw    d'30'        ;delay 30 mS
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_20m  
    movlw    d'20'        ;delay 20 mS
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_10m  
    movlw    d'10'        ;delay 10 mS
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_5m
    movlw    0x05        ;delay 5 ms
    movwf    count_k
    movlw    0x01        ;times 1
    movwf    count_b
    goto    delay_n
delay_3m
    movlw    0x03        ;delay 3 ms
    movwf    count_k
    movlw    0x01        ;times 1
    movwf    count_b
    goto    delay_n
delay_2m
    movlw    0x02        ;delay 2 ms
    movwf    count_k
    movlw    0x01        ;times 1
    movwf    count_b
    goto    delay_n
delay_1m            ;1 ms
    movlw    0x01
    movwf    count_k
    movlw    0x01
    movwf    count_b
    goto    delay_n
delay_n
    movlw     0x07    ;complement of d'248'
    movwf    TMR0_k    ;TMR0 constant
dda    movfw    count_k    ;constant
    movwf    count_a  
ddb    movfw    TMR0_k    ;constant
    movwf    TMR0
    bcf        tmr0_of
    btfss    tmr0_of
    goto    $-1
    decfsz    count_a, f
    goto    ddb
    decfsz    count_b, f
    goto    dda
    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   0xF1  
    movwf    INLVLC        ;RC3:7 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        ;Make these inputs digital, not analogue
    clrf    ANSELB
    clrf    ANSELC
    banksel    SLRCONA        ;selects BANK 6
    clrf    SLRCONA        ;PORTA slew rate - clear for max slew rate
    clrf    SLRCONB
    clrf    SLRCONC
    banksel    WPUA        ;selects BANK 4
    clrf    WPUA        ;disable weak pull ups
    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
 
Hola ljcox,

I don't have the faintest idea if this could help you, but I recall solving a "hard" problem with the 18F4431, IIRC, simply by doing this: verifying the erratas for my silicon version and carefully reading the description for every pin involved. The last worked for many other micros as well.

Good luck.
 
Okay! Not sure what you want but!!!

The interrupt on PortC works okay for the first positive edge, then swaps to the negative edge.. BUT then you do not reset the positive edge so it stops working.. PortA seems to be on the positive edge only!
 
Okay! Not sure what you want but!!!

The interrupt on PortC works okay for the first positive edge, then swaps to the negative edge.. BUT then you do not reset the positive edge so it stops working.. PortA seems to be on the positive edge only!
Thanks Ian. You said that you would tell me why the IOC on PORTC did not work for me.
I have never seen it work on PORTC. What version of MPLAB are you using? I have 8.92.
I change both IOCA and IOCC from positive to negative edge after a positive edge is detected. But, as I said, the IOCC never works.
I'll take the advice given by atferrari and check the erratas.
 
Hola ljcox,

I don't have the faintest idea if this could help you, but I recall solving a "hard" problem with the 18F4431, IIRC, simply by doing this: verifying the erratas for my silicon version and carefully reading the description for every pin involved. The last worked for many other micros as well.

Good luck.
Thanks, I'll check the errata.
 
I change both IOCA and IOCC from positive to negative edge after a positive edge is detected. But, as I said, the IOCC never works.
Yes it does... but your chg_c changes pos to neg but chg_cn just cancels the negative...
I have never seen it work on PORTC. What version of MPLAB are you using? I have 8.92.
I have a copy of mpasmx in a folder in my root directory as the command line doesn't work well with paths with spaces...
I then use VSM along with Proteus for real time simulation..

If you follow the pp3 process, you'l see what I mean..
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top