📄 pic_2.asm
字号:
;****************************************************************************************;
;* Direct Digital Synthesizer VFO using AD9850/51 *;
;* *;
;* Date : Sunday, 18 Jun 2006 *;
;* Author : C.V.Niras/VU3CNS *;
;* Copyright : (C) 2005 C. V. Niras *;
;* Email : cvniras@hamradio.in *;
;* *;
;* This program is free software; you can redistribute it and/or modify it under the *;
;* terms of the GNU General Public License as published by the Free Software *;
;* Foundation; either version 2, or (at your option) any later version. *;
;* *;
;* This program is distributed in the hope that it will be useful, but WITHOUT ANY *;
;* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *;
;* PARTICULAR PURPOSE. See the GNU General Public License for more details. *;
;* *;
;****************************************************************************************;
;****************************************************************************************;
;* This is the program for PIC 2 in DDS circuit. PIC 1 sends data in syncronous 9 bit *;
;* mode. PIC1 uses 32 bit for the freq, but sending only one byte (, i.e Freq/ 0x20000)*;
;* Only this is necessary for selecting bands up to 30MHz. *;
;* For selecting MODE (i.e. LSB/USB..) PIC 1 sends another byte data, and we need olny *;
;* the first two bits *;
;* 00 = No offset *;
;* 01 = CW offset *;
;* 10 = -SB offset *;
;* 11 = +SB offset *;
;* If 9th bit is set, it means the data sent was for MODE selection else BAND selection*;
;****************************************************************************************;
list p=16F628A ; list directive to define processor
#include <P16F628A.INC> ; processor specific definitions
errorlevel -302 ; suppress "not in bank 0" message
__CONFIG _WDT_OFF & _LVP_OFF & _INTOSC_OSC_NOCLKOUT & _BODEN_ON & _PWRTE_ON & _MCLRE_OFF
;----------------------------------------------------------------------------
;Constants
SPBRG_VAL EQU .25 ; set baud rate 9600 for 4Mhz clock
RX_BUF_LEN EQU .1 ; length of receive buffer
TX_BUF_LEN EQU RX_BUF_LEN ; length of transmit buffer
;----------------------------------------------------------------------------
#DEFINE NO_BAND_OP PORTB,0 ;
#DEFINE BANDS 9
#DEFINE BAND1 ((.1810000 + .2000000) / 2) ; 160m [ Calculate band centre in
#DEFINE BAND2 ((.3500000 + .3800000) / 2) ; 80m [ Hz, based on upper and lower
#DEFINE BAND3 ((.7000000 + .7100000) / 2) ; 40m [ frequency limits for that
#DEFINE BAND4 ((.10100000 + .10150000) / 2) ; 30m [ band.
#DEFINE BAND5 ((.14000000 + .14350000) / 2) ; 20m
#DEFINE BAND6 ((.18068000 + .18168000) / 2) ; 17m
#DEFINE BAND7 ((.21000000 + .21450000) / 2) ; 15m
#DEFINE BAND8 ((.24890000 + .24990000) / 2) ; 12m
#DEFINE BAND9 ((.28000000 + .29700000) / 2) ; 10m
#DEFINE MODE FLAG,0 ;
;----------------------------------------------------------------------------
; Variables
;----------------------------------------------------------------------------
CBLOCK 0x020 ; Bnak 0 bytes 0x20 to 0x6F(80 bytes)
ENDC
CBLOCK 0x70 ; Bank 0 cont. 0x70 to 0x7F 16 bytes
; General purposes
FLAG ; byte to store indicator flags
COUNT ;
RX_DATA ;
MODE_DATA ;
SAVE_STATUS ;
SAVE_W_REG ;
OLD_COUNT ;
OLD_RX_DATA ;
ENDC
CBLOCK 0x0A0 ; Bank 1 bytes 0xA0 to 0xEF
ENDC
;----------------------------------------------------------------------------
; Macros to select the register bank
; Many bank changes can be optimized when only one STATUS bit changes
BANK0 MACRO ; macro to select data RAM bank 0
BCF STATUS,RP0
ENDM
BANK1 MACRO ; macro to select data RAM bank 1
BSF STATUS,RP0
ENDM
;----------------------------------------------------------------------------
#DEFINE SCALE_FACTOR 0x20000 ; 20000 hex = 2 ^ 17
; Note - setBand() makes assumptions about
; this value - if it is changed then setBand
; must be changed to match.
ORG 0x05 ; Location after interruptvector
BAND_LO:
ADDWF PCL,F
RETLW ((BAND1 * .9) / .10) / SCALE_FACTOR
RETLW ((BAND2 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND3 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND4 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND5 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND6 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND7 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND8 * .19) / .20) / SCALE_FACTOR
RETLW ((BAND9 * .19) / .20) / SCALE_FACTOR
BAND_HI:
ADDWF PCL,F
RETLW ((BAND1 * .11) / .10) / SCALE_FACTOR
RETLW ((BAND2 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND3 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND4 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND5 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND6 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND7 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND8 * .21) / .20) / SCALE_FACTOR
RETLW ((BAND9 * .21) / .20) / SCALE_FACTOR
BAND_SELECT:
ADDWF PCL,F
RETLW 0x08 ; BAND 1
RETLW 0x10 ; BAND 2
RETLW 0x20 ; BAND 3
RETLW 0x40 ; BAND 4
RETLW 0x80 ; BAND 5
RETLW 0x00 ; BAND 6
RETLW 0x00 ; BAND 7
RETLW 0x00 ; BAND 8
RETLW 0x00 ; BAND 9
RETLW 0x01 ; NO BAND
BAND_SELECT_HI:
ADDWF PCL,F
RETLW 0x00 ; BAND 1
RETLW 0x00 ; BAND 2
RETLW 0x00 ; BAND 3
RETLW 0x00 ; BAND 4
RETLW 0x00 ; BAND 5
RETLW 0x40 ; BAND 6
RETLW 0x80 ; BAND 7
RETLW 0x01 ; BAND 8
RETLW 0x02 ; BAND 9
RETLW 0x00 ; NO BAND
MODE_SELECT:
ADDWF PCL,F
RETLW 0x00
RETLW 0x04
RETLW 0x08
RETLW 0x10
#IF ($ > 255)
MESSG ERR0R : TABLE OVERFLOWS
#ENDIF
TABLE_END
;----------------------------------------------------------------------------
;This code executes when a reset occurs.
ORG 0x0000 ; place code at reset vector
RESET: CLRF PORTA ;
CLRF PORTB ;
BSF STATUS,RP0 ; Select Bank 1
GOTO CONTINUE ;
;----------------------------------------------------------------------------
; Interrupt Vector
ORG 0x0004 ; place code at interrupt vector
GOTO INTERRUPT ;
;----------------------------------------------------------------------------
ORG TABLE_END
CONTINUE: MOVLW 0x00 ;
MOVWF TRISA ;
MOVLW 0x06 ;
MOVWF TRISB ;
MOVLW B'00010000' ; Slave, TX dis, Sync mode
MOVWF TXSTA ;
MOVLW B'00100000' ; Enable RCIE Interrupt
MOVWF PIE1 ;
BANK0 ; Select Bank0
MOVLW 0x07 ;
MOVWF CMCON ;
MOVLW B'01000000' ;
MOVWF INTCON ; Enable Peripheral interrupt
MOVLW B'11000000' ; Enable serial port, and Enable RX
MOVWF RCSTA ;
CLRF COUNT ;
MOVLW BANDS ; Load OLD_COUNT = No Band
MOVWF OLD_COUNT ;
CLRF FLAG ;
CLRF RX_DATA ;
CLRF OLD_RX_DATA ;
BSF NO_BAND_OP ;
BSF INTCON,GIE ;
BSF RCSTA,CREN ;
MAIN: BTFSC MODE ;
GOTO MODE_SEL ;
SET_BAND: MOVLW BANDS ;
MOVWF COUNT ;
BAND_LOOP: DECF COUNT,F
BTFSC COUNT,7 ; Check for counter 'underflow'
GOTO NO_BAND ; We've run out of bands to check!
MOVF COUNT,W
CALL BAND_LO
SUBWF RX_DATA,W ; Compare with lower freq of band
BTFSS STATUS,C ;
GOTO BAND_LOOP ; If below bottom of this band, skip to next
MOVF COUNT,W ;
CALL BAND_HI
SUBWF RX_DATA,W ; Compare with upper freq of band
BTFSC STATUS,Z ;
GOTO BAND_FOUND ; If equal to...
BTFSS STATUS,C ; ...or less than, we have a match.
GOTO BAND_FOUND ;
NO_BAND: MOVLW BANDS ; Load Count for NO band o/p
MOVWF COUNT ;
BAND_FOUND: MOVF COUNT,W ; check, any band changes
XORWF OLD_COUNT,F ;
MOVWF OLD_COUNT ;
BTFSC STATUS,Z ;
GOTO END_SEL ; N. Exit
MOVLW B'00111100' ; Clear band selection bits in PORTA
ANDWF PORTA,F ;
; CLRF PORTB ; Clear band selection bits of PORTB
; MOVF COUNT,W ; check the band is higher than 5
; SUBLW 0x04 ; ( i.e. count > 4)
; MOVF COUNT,W ;
; BTFSS STATUS,C ;
; GOTO USE_PORTA ;
;
; CALL BAND_SELECT ;
; MOVWF PORTB ;
; GOTO END_SEL ;
;
;USE_PORTA: CALL BAND_SELECT ;
; IORWF PORTA,F ;
; GOTO END_SEL ;
MOVF COUNT,W ;
CALL BAND_SELECT ;
MOVWF PORTB ;
MOVF COUNT,W ;
CALL BAND_SELECT_HI ;
IORWF PORTA,F ;
GOTO END_SEL ;
;NO_BAND: MOVF COUNT,W ;
; XORWF OLD_COUNT,F ;
; MOVWF OLD_COUNT ;
; BTFSC STATUS,Z ;
; GOTO END_SEL ;
; MOVLW B'00111100' ; Clear band selection bits in PORTA
; ANDWF PORTA,F ;
; CLRF PORTB ;
; BSF NO_BAND_OP ;
; GOTO END_SEL ;
MODE_SEL: MOVF RX_DATA,W ;
ANDLW 0x03 ;
XORWF OLD_RX_DATA,F ;
MOVWF OLD_RX_DATA ;
BTFSC STATUS,Z ;
GOTO END_SEL ;
MOVLW B'11100011' ;
ANDWF PORTA,F ;
MOVF OLD_RX_DATA,W ;
CALL MODE_SELECT ;
IORWF PORTA,F ;
GOTO END_SEL ;
END_SEL: SLEEP ; All work done! Go to sleep
NOP ;
GOTO MAIN ;
INTERRUPT:
MOVWF SAVE_W_REG ; Save W reg.
SWAPF STATUS,W ;
MOVWF SAVE_STATUS ; Save STATUS reg.
; BANK0 ;
BCF MODE ;
BTFSC RCSTA,RX9D ;
BSF MODE ;
MOVF RCREG,W ;
MOVWF RX_DATA ;
INT_EXIT: SWAPF SAVE_STATUS,W ;
MOVWF STATUS ; Restore STATUS reg.
SWAPF SAVE_W_REG,F ;
SWAPF SAVE_W_REG,W ; Restore W reg without changing STATUS.
RETFIE
;----------------------------------------------------------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -