I have been working this on this one for a while (2 months), salvaging some old code from a pong clone I made in PIC assembly years ago. I have all the math worked out, and I imagine the program in a pseudocode like format would look like this:
Using timer2, set postscaler bits to 1001, prescaler bits to 11. Initiate countdown at 12,500. Start timer. Whenever timer register overflows, decrement counter 1, and reset timer. When countdown reaches zero, flip bit corresponding to light off or on (if 1, change to 0, if 0 change to 1). Reset timer and countdown.
Relevant Information:
LED is wired to RB5.
Don't completely know how to implement a countdown variable (or any variable to begin with in assembly), even with referrence to pong clone, which I only understood part of.
Need to create 2 programs, one using interrupts and one not using interrupts.
Here is the actual code of what I have so far(which won't work, its incomplete), its not much (much of it was actually already done, only the part in the application labeled area was done by me), and I don't even know if it is right:
;; -- mode: asm; mode: outline-minor-mode; outline-regexp: ";;;+" --;;; skeleton.asm list p=16f1938 include "p16f1938.inc"
SETBSR macro target movlb (target >> 7) ; gpasm assember's BANKSEL doesn't work for exhanced 16F parts. ;; BANKSEL target ; Use this instruction for MPASM endm
;;; PIC16F1938 ;; fcs 22 July 2006
;; Here is a dummy program to illustrate the how to write an application ;; that can be used with the Pikme bootloader or with a hardware ;; programmer. ;; The bootloader ignores the first 32-word block of memory. ;; Put the application's interrupt code at 0x0020 (either put a jump ;; to your actual interrupt handler code there or put a retfie ;; instruction there. ;; Put the application's start code at 0x0024. ;; The interrupt vector is effectively 0x0020 (because the bootloader's ;; interrupt vector jumps to 0x0020) and the program must begin at ;; 0x0024. ;; So, ORG your interrupt code at 0x0020 and put interrupt code in ;; the first 4 instructions (e.g. rtfie, nop, nop, nop) and then start ;; the application at 0x0024. (The 3 'nop's are not actually necessary ;; as long is the 'org 0x0024' statement is present.) ;; uncomment and possibly edit following line if you include ;; any macros, etc. ;include "macros.inc" expand ;noexpand radix dec
;========================================================================== ; __CONFIG 0x3F10
__CONFIG _CONFIG1, _FCMEN_OFF & _IESO_OFF & _CLKOUTEN_ON & _BOREN_OFF & _CP_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_INTOSC __CONFIG _CONFIG2, _LVP_OFF & _BORV_19 & _STVREN_ON & _PLLEN_OFF & _VCAPEN_OFF & _WRT_OFF ;; Above configuration word will be ignored when using the bootloader but ;; will be programmed into the PIC when you use a hardware programmer.
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; First 32-word block. ;;; This is ignored by the bootloader but is not ignored when ;;; using a hardware programmer. ;;; By putting this code here, the very same hex file can be used either ;;; with the bootloader or with a hardware programmer. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x0000 goto UserApp
org 0x0004
ISR goto UserISR
;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; First block after protected memory. ;;; This is where the application's interrupt and application code ;;; go. ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x0200 ;; Your interrupt handler must be org'd at 0x0020. ;; Use a return from interrupt instruction (retfie) or put ;; a jump to your actual interrupt handler (goto xxxx). UserISR retfie nop nop nop
org 0x0204 ;; Your application *must* be org'd at 0x0204, because that is ;; the address where the bootloader jumps.
UserApp ;; put your application code here. This code sets the internal oscillator to 32 Mhz.
movlb (OSCCON >> 7) ; Use this statement if your assembler does not support Enhanced BANKSEL
;; BANKSEL TRISB ; Use this statement if your assembler supports it.
movlw 0xF0 ; 8 Mhz, internal OSC, PLL on movwf OSCCON
hsploop: btfss OSCSTAT,HFIOFR bra hsploop
pllloop: btfss OSCSTAT,PLLR bra pllloop
;; Reset the BSR to Bank 0 SETBSR PORTA
;; Main: This is where your applications goes. Make sure it is an infinite loop! main: bra main; relative branch main BCF TMR2; Clears register for timer 2.
SETBSR PORTB; Bank 0 movlw 0x01; move 0x01 to W movwf PORTB; move w to PORTB BCF PORTB,5; bit clear PORTB end
I guess my main issue is simply translating my outline into assembly code, particularly getting the countdown to work and setting up timer2. The part I have written in main is to turn the light on and off (I think). I also believe that if correct, the code I have so far can be used for both the interrupt using version as well as the non-interrupt version. However, at the point I am now, I am kind of lost code wise.