![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
For some reason the IOC does not seem to be working. I cannot figure out why, this is my first time using this feature. Also, I have a feeling that the TMR2 interrupt is not working either...I have been up all night trying to fix it and cannot figure it out.
Thanks for your help. Sean Code:
;dual 7-segment hex display controller for one byte List p=16f690 include P16F690.INC __CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF; & _INTRC_OSC_NOCLKOUT errorlevel -302 ;-----------------------VARIABLE REGISTER DEFINITIONS--------------------------- w_temp EQU 0x70 ; variable used for context saving status_temp EQU 0x71 ; variable used for context saving pclath_temp EQU 0x72 ; variable used for context saving Digit1 EQU 0xc1 Digit2 EQU 0xc2 temp EQU 0xc3 ;================================CODE================================== org 0x0000 goto Initialize ;***************************Interrupt_Routine************************** org 0x0004 ; interrupt vector location movf STATUS,W ; move status register into W register movwf status_temp ; save of contents of STATUS register movf PCLATH,W ; move pclath register into W register movwf pclath_temp ; save of contents of PCLATH register btfsc INTCON,RABIF goto ReadPort bcf PIR1,TMR2IF btfsc PORTB,h'05' goto Display1 btfsc PORTB,h'04' goto Display2 STATUS_RESTORE movf pclath_temp,W ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,W ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,F swapf w_temp,W ; restore pre-isr W register contents retfie ;***************************INITIALIZATION***************************** Initialize movlw b'00011000' movwf STATUS ;BANK 0 movlw b'00000000' movwf ADCON0 ;turns off ADC movlw h'ff' movwf T2CON ;TMR2 PS 1:16, TMR2 PostS 1:16, 0.06sec period movlw b'00111000' movwf STATUS ;BANK 1 movlw b'01000001' movwf OSCCON ;sets oscillator to 1MHz movlw b'00000001' movwf OPTION_REG ;1:16 PS, bsf PIE1,TMR2IE ;enable Timer2 interrupt movlw b'00111111' movwf TRISA ;PORTA I/O setup movlw b'00111111' movwf IOCA movlw b'11000000' movwf TRISB ;PORTB: RB4-5 outputs for Display select lines movlw b'00000000' movwf TRISC ;PORTC: Display Data movlw b'11011000' movwf STATUS ;BANK 2 movlw b'11000000' ;enable Interrupt on change movwf IOCB movlw h'00' movwf ANSEL ;analog disable ANS0-ANS7 movlw h'00' movwf ANSELH ;analog disable ANS8-ANS11 movlw b'00111000' movwf STATUS ;BANK 0 movlw b'00001000' movwf INTCON ;enable IOC for PortA, B main bsf INTCON,GIE bsf PORTB,h'04' bsf PORTB,h'05' movlw b'10011110' movwf PORTC nop nop goto $-1 ;idle loop ReadPort movf PORTB,W andlw b'11000000' iorwf PORTA,W movwf temp ;temp contains full input byte andlw h'0F' ;Least Significant Nibble call Table movwf Digit2 swapf temp,W andlw h'0F' ;Most Significant Nibble call Table movwf Digit1 goto STATUS_RESTORE Display1 bsf PORTB,h'04' ;disable display 2 movf Digit1,W movwf PORTC bcf PORTB,h'05' ;enable display 1 goto STATUS_RESTORE Display2 bsf PORTB,h'05' ;disable display 1 movf Digit2,W movwf PORTC bcf PORTB,h'04' ;enable display 2 goto STATUS_RESTORE Table andlw b'00001111' addwf PCL,F ;PORTC 76543210 ;Segment abcdefgh, active low retlw b'00000010' ;0 retlw b'10011110' ;1 retlw b'00100100' ;2 retlw b'00001100' ;3 retlw b'10011000' ;4 retlw b'01001000' ;5 retlw b'01000000' ;6 retlw b'00011110' ;7 retlw b'00000000' ;8 retlw b'00011000' ;9 retlw b'00010000' ;A retlw b'11000000' ;B retlw b'01100010' ;C retlw b'10000100' ;D retlw b'01100000' ;E retlw b'01110000' ;F END ;+++++++++++++++++++PORTC Pinout+++++++++++++++ ;++++PortC: 7 6 5 4 3 2 1 0 +++ ;++segment: a b c d e f g h +++ ;++++++++++++++++ _a_ +++++++++++ ;++++++++++++++++ | | +++++++++++ ;++++++++++++++++ f|_g_|b +++++++++++ ;++++++++++++++++ | | +++++++++++ ;++++++++++++++++ e| |c +++++++++++ ;++++++++++++++++ h -d- +++++++++++ ;++++++++++++++++++++++++++++++++++++++++++++++ |
|
|
|
|
|
|
(permalink) |
|
When this is done I will post the single sided pcb, schematic, and code in the projects section for public use. I figure a simple hex display like this would be useful for PIC projects where you need to confirm outputs but do not have the hardware for it ready.
|
|
|
|
|
|
|
(permalink) | |
|
Quote:
__________________
========================= Futz's Microcontrollers & Robotics ========================= Last edited by futz; 3rd February 2008 at 07:47 AM. |
||
|
|
|
|
|
(permalink) |
|
Hi,
May I know what is IOC? I didn't see w register being saved in the ISR, but restored *EDIT: Just found it from the datasheet, just ignore my question Besides, I found that your Digit1, Digit2 and temp are GPR that located in bank1, are you aware of that?
__________________
Superman returns..
Last edited by bananasiong; 3rd February 2008 at 08:24 AM. |
|
|
|
|
|
|
(permalink) |
|
I believe you must read the port then clear the interrupt flag to truely clear and reset the interrupt on change condition... At least that's how I remember doing it on the 12F683... And as the guys have mentioned, you need to save and restore W in your ISR too...
Have you enabled peripheral interrupts for Timer 2 (bsf INTCON, PEIE)? I did something similar to this awhile back for a Forum member using a 16F628A but I simply read the input port during each 8 msec Timer 2 display update interrupt interval. Mike Code:
list p=16F628A, b=8, c=102, n=71, t=on, st=off, f=inhx32
;******************************************************************
;* *
;* Filename: Forum 4477 IC v2.asm *
;* Author: Mike McLaren, K8LH *
;* Date: 14-Sep-07 (rev 29-Sep-07) *
;* *
;* 8 Bit BCD to Dual 7-Segment LED Decoder/Driver IC Firmware *
;* *
;* Uses a 16F628A with a 4-MHz INTOSC and Eric Gibbs standard *
;* multiplexed dual-digit common cathode display circuit *
;* *
;* Digit 1 (left) inputs are RA7..RA4 (msb..lsb) *
;* Digit 2 (right) inputs are RA3..RA0 (msb..lsb) *
;* Segments A..G connected to RB0..RB6 *
;* Common cathodes connect to RB7 via a 2 transistor circuit *
;* *
;* MPLab: 7.40 (tabs=8) *
;* MPAsm: 5.03 *
;* *
;******************************************************************
#include <p16f628a.inc>
errorlevel -302
radix dec
__config _MCLRE_OFF&_LVP_OFF&_WDT_OFF&_INTOSC_OSC_NOCLKOUT
;
; variables
;
Temp equ 0x20 ;
DigSel equ 0x21 ; digit select, '00000000' or '10000000'
W_ISR equ 0x70 ; ISR WREG
S_ISR equ 0x71 ; ISR STATUS
P_ISR equ 0x72 ; ISR PCLATH
;******************************************************************
;* Reset vector *
;******************************************************************
org 0x0000
Reset clrf STATUS ; force bank 0 |B0
clrf PORTA ; clear PORTA output latches |B0
clrf PORTB ; clear PORTB output latches |B0
goto Main ; |B0
;******************************************************************
;* Interrupt vector *
;******************************************************************
org 0x0004
;
; save MAIN program context
;
ISR movwf W_ISR ; save W-reg |B?
swapf STATUS,W ; doesn't change STATUS bits |B?
movwf S_ISR ; save STATUS reg |B?
clrf STATUS ; bank 0 |B0
movf PCLATH,W ; get PCLATH |B0
movwf P_ISR ; save PCLATH |B0
clrf PCLATH ; ISR is in bank 0 |B0
;
; update left or right display on alternating interrupt cycles
;
swapf PORTA,W ; W = hi nybble in b3..b0 bits |B0
btfss DigSel,7 ; left digit? yes, skip, else |B0
movf PORTA,W ; W = lo nybble in b3..b0 bits |B0
andlw b'00001111' ; mask off upper 4 bits |B0
call SegData ; get segment data in W |B0
iorwf DigSel,W ; add digit select bit in b7 |B0
movwf PORTB ; display new digit |B0
movlw b'10000000' ; mask for digit select bit |B0
xorwf DigSel,F ; toggle b7 digit select bit |B0
;
; restore MAIN program context
;
bcf PIR1,TMR2IF ; clear TMR2 interrupt flag bit |B0
movf P_ISR,W ; |B0
movwf PCLATH ; restore PCLATH |B0
swapf S_ISR,W ; |B0
movwf STATUS ; restore STATUS |B0
swapf W_ISR,F ; don't screw up STATUS |B0
swapf W_ISR,W ; restore W-reg |B0
retfie ; return from interrupt |B0
;******************************************************************
;* Subroutines *
;******************************************************************
;
SegData
movwf Temp ; save temporarily |B0
movlw high SegTable ; |B0
movwf PCLATH ; |B0
movlw low SegTable ; |B0
addwf Temp,W ; |B0
skpnc ; |B0
incf PCLATH,F ; |B0
movwf PCL ; |B0
SegTable
dt b'00111111' ; "0" -|-|F|E|D|C|B|A
dt b'00000110' ; "1" -|-|-|-|-|C|B|-
dt b'01011011' ; "2" -|G|-|E|D|-|B|A
dt b'01001111' ; "3" -|G|-|-|D|C|B|A
dt b'01100110' ; "4" -|G|F|-|-|C|B|-
dt b'01101101' ; "5" -|G|F|-|D|C|-|A
dt b'01111101' ; "6" -|G|F|E|D|C|-|A
dt b'00000111' ; "7" -|-|-|-|-|C|B|A
dt b'01111111' ; "8" -|G|F|E|D|C|B|A
dt b'01101111' ; "9" -|G|F|-|D|C|B|A
dt b'01110111' ; "A" -|G|F|E|-|C|B|A
dt b'01111100' ; "b" -|G|F|E|D|C|-|-
dt b'00111001' ; "C" -|-|F|E|D|-|-|A
dt b'01011110' ; "d" -|G|-|E|D|C|B|-
dt b'01111001' ; "E" -|G|F|E|D|-|-|A
dt b'01110001' ; "F" -|G|F|E|-|-|-|A
;******************************************************************
;* Main program *
;******************************************************************
;
; initialize
;
Main movlw h'07' ; |B0
movwf CMCON ; turn comparator off |B0
;
; setup ports and display sub-system variables
;
bsf STATUS,RP0 ; bank 1 |B1
movlw h'FF' ; |B1
movwf TRISA ; make Port A all inputs |B1
clrf TRISB ; make Port B all outputs |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf DigSel ; init b7 digit select bit |B0
;
; configure TIMER2 for 8-msec interrupts (4 MHz INTOSC) which
; provides a 62.5 Hz display refresh rate (at 50% duty cycle)
;
clrf TMR2 ; clear TMR2 register |B0
bsf STATUS,RP0 ; bank 1 |B1
clrf PIE1 ; clear interrupt enable bits |B1
bsf PIE1,TMR2IE ; except for TMR2 interrupts |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf PIR1 ; clear peripheral irq flags |B0
movlw b'01001001' ; '01001001' |B0
; '-1001---' postscale 10
; '-----0--' Timer 2 off
; '------01' prescale 4
movwf T2CON ; for 40-usec ticks (4-MHz) |B0
bsf STATUS,RP0 ; bank 1 |B1
movlw d'200'-1 ; 200 x 40-usec ticks for |B1
movwf PR2 ; 8-msec interrupts |B1
bcf STATUS,RP0 ; bank 0 |B0
bsf INTCON,GIE ; enable global irqs |B0
bsf INTCON,PEIE ; enable peripheral irqs |B0
bsf T2CON,TMR2ON ; start TMR2 |B0
;
Wait goto Wait ; loop indefinately |B0
;******************************************************************
end
![]() Last edited by Mike, K8LH; 3rd February 2008 at 09:13 AM. |
|
|
|
|
|
|
(permalink) |
|
Well I fixed the variable locations. That is what happens when you copy code from a different PIC's program. W is saved and restored in the ISR. The STAUTS_RESTORE label is still in the ISR. I use that label to return to the ISR. I will change the order of the flag clearing and see what happens.
|
|
|
|
|
|
|
(permalink) |
|
something else seems to be wrong too. I can get the digits to display properly (yesterday), and now when I do a test by disabling GIE and sending h'00' to PORTC, i get only the 3 vertical segments to light up. This happened suddenly to the last PIC that I used, and I trashed it. I do not understand why this is happening...I am using an hp 7-segment with 430ohm resistors, CA. How could the pins be getting damaged??
|
|
|
|
|
|
|
(permalink) |
|
here is the latest code. I removed the IOC. I wanted to learn how to use it, but now I just want to get this thing working.
Here is what the pins are doing: PORTA,B are tied low through 4.7k's, but are giving me 5V at the pins. PORTC pins (some of them) go to 5V when I write all 0's. When I write all 1's the pins bounce all over a 100mv to 300mv range, until I reconnect them to the LED, then they sit at 4V. What the heck is going on?! oh, and for some reason the picture linker is not working for the post...it didnt show. So I also gave the link. Code:
List p=16f690 include P16F690.INC __CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF; & _INTRC_OSC_NOCLKOUT errorlevel -302 ;-----------------------VARIABLE REGISTER DEFINITIONS--------------------------- w_temp EQU 0x40 ; variable used for context saving status_temp EQU 0x41 ; variable used for context saving pclath_temp EQU 0x22 ; variable used for context saving Digit1 EQU 0x43 Digit2 EQU 0x44 temp EQU 0x45 ;================================CODE================================== org 0x0000 goto Initialize ;***************************Interrupt_Routine************************** org 0x0004 ; interrupt vector location movf STATUS,W ; move status register into W register movwf status_temp ; save of contents of STATUS register movf PCLATH,W ; move pclath register into W register movwf pclath_temp ; save of contents of PCLATH register bcf PIR1,TMR2IF btfsc PORTB,h'05' goto Display1 btfsc PORTB,h'04' goto Display2 STATUS_RESTORE movf pclath_temp,W ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,W ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,F swapf w_temp,W ; restore pre-isr W register contents retfie ;***************************INITIALIZATION***************************** Initialize movlw b'00011000' movwf STATUS ;BANK 0 movlw b'00000000' movwf ADCON0 ;turns off ADC movlw h'ff' movwf T2CON ;TMR2 PS 1:16, TMR2 PostS 1:16, 0.06sec period movlw b'00111000' movwf STATUS ;BANK 1 movlw b'01000001' movwf OSCCON ;sets oscillator to 1MHz movlw b'00000001' movwf OPTION_REG ;1:16 PS, bsf PIE1,TMR2IE ;enable Timer2 interrupt movlw b'00111111' movwf TRISA ;PORTA I/O setup movlw b'11000000' movwf TRISB ;PORTB: RB4-5 outputs for Display select lines, 6 and 7 input movlw b'00000001' movwf TRISC ;PORTC: LED output pins movlw b'11011000' movwf STATUS ;BANK 2 movlw h'00' movwf ANSEL ;analog disable ANS0-ANS7 movlw h'00' movwf ANSELH ;analog disable ANS8-ANS11 movlw b'00111000' movwf STATUS ;BANK 0 bsf INTCON,PEIE main ; bsf INTCON,GIE bsf PORTB,h'04' bcf PORTB,h'05' movlw b'11111111' ;test movwf PORTC nop nop goto $-1 ;idle loop ReadPort movf PORTB,W andlw b'11000000' iorwf PORTA,W movwf temp ;temp contains full input byte andlw h'0F' ;Least Significant Nibble call Table movwf Digit2 swapf temp,W andlw h'0F' ;Most Significant Nibble call Table movwf Digit1 Display1 call ReadPort bsf PORTB,h'04' ;disable display 2 movf Digit1,W movwf PORTC bcf PORTB,h'05' ;enable display 1 goto STATUS_RESTORE Display2 bsf PORTB,h'05' ;disable display 1 movf Digit2,W movwf PORTC bcf PORTB,h'04' ;enable display 2 goto STATUS_RESTORE Last edited by Ambient; 3rd February 2008 at 09:57 PM. |
|
|
|
|
|
|
(permalink) |
|
Well I still don't know what IOC means, but do you have access to a debugger? Also the simulator is handy for figuring out how your code works with an interrupt. And why are you using the linker? Unless you're writing relocateable code (doesn't appear you are) you can skip the linker.
|
|
|
|
|
|
|
(permalink) | |
|
Quote:
|
||
|
|
|
|
|
(permalink) |
|
Ahh, that sounds right.
|
|
|
|
|
|
|
(permalink) |
|
"Interrupt on change". which line am I using the linker? I did say "linker" but I was referring to the image link for the schematic, which appears to be working now. The schematic is not the final version, this one is for testing. I am still trying to figure out how I burned out another PIC, and why PORTB is acting like outputs, not in. I updated the code in the last post, and just provided the link to the pic.
Last edited by Ambient; 3rd February 2008 at 09:56 PM. |
|
|
|
|
|
|
(permalink) |
|
Well I've not used the 16F690 but here's my take on things.
When saving the stack; using all bank memory will save you some grief. Code:
w_temp EQU 0x70 ; variable used for context saving status_temp EQU 0x71 ; variable used for context saving pclath_temp EQU 0x72 ; variable used for context saving |
|
|
|
|
|
|
(permalink) |
|
I am just using MPlab. But I have not used the debugger in it yet. I don't think it has a simulator. But since the pins seem to indicate that I toasted 2 PICs, I have to figure out why first. Maybe I will start from the beginning again.
I have those variables starting at 40h, won't they be in the same bank as 70h..72h? I thought that bank0 GPR went from 20h to 7fh. I do have a paintball counter project for the 16f690 that does work, so I will try programming the chip for that and popping it on the pcb. If it doesn't work I know I toasted the PIC. Last edited by Ambient; 3rd February 2008 at 10:24 PM. |
|
|
|
|
|
|
(permalink) |
|
MPLAB has an excellent simulator, really handy for watching those little oops that slip by.
Many 14bit core PICs have 70h thru 7Fh RAM common in all banks. This is really handy for ISR routines where you may not know what bank the call came from. PICs are pretty tough. |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Quik PIC Programming kit | Krumlink | General Electronics Chat | 5 | 27th January 2008 11:27 PM |
| Capturing and reproducing audio with a PIC | Fred.Amoson | Micro Controllers | 14 | 14th December 2007 08:21 PM |
| Problems switchin relay with PIC | Andy1845c | General Electronics Chat | 5 | 17th November 2007 06:13 PM |
| High ADC sampling rate PIC, 18F needed? | bananasiong | Micro Controllers | 24 | 28th October 2007 12:13 PM |
| Four PIC with One LCD.. | meera83 | Micro Controllers | 13 | 20th September 2007 06:40 AM |