PDA

View Full Version : NCO Glitch



mpgmike
- 19th December 2017, 11:37
I'm sending NCO values from one PIC to another. The Comm protocol requires 2 bytes per NCO1INCx register; 1st identifies it, 2nd is the NCO1INCx value. Finally there is a "Start" command byte sent. I noticed shooting for 2.4 MHz that I only got 564 Hz. However, if I turn the NCO Module Off, then On again, I get the 2.4 MHz. Here is the code for the Receiver:



DEFINE OSC 8
DEFINE HSER_RCSTA 90h ;Enable serial port & continuous receive
DEFINE HSER_TXSTA 02h ;Disable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ;Clear overflow automatically
DEFINE HSER_BAUD 9600


;Configurations:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_OFF & _PWRTE_OFF & _WDTE_ON & _LPBOREN_OFF & _BOREN_ON & _BORV_LOW & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WRT_OFF & _LVP_OFF
__config _CONFIG4, _CP_OFF & _CPD_OFF
#ENDCONFIG


;Aliases:
;Prb VAR LATA.0 ;HF Generator Driver for Probes
;RX VAR PORTA.1 ;USART Receive
;TX VAR PORTA.2 ;USART Transmit
;MCLR VAR PORTA.3 ;!MCLR
;NC VAR PORTA.4 ;
;Wand VAR LATA.5 ;HF Generator Driver for IR LEDs


;Special Function Registers:
OSCCON1 = %00000010 ;INTTOSC, 1:4 Divider, 8 MHz
OSCFRQ = %00000011 ;8 MHz
TRISA = %00001110
ANSELA = 0
WPUA = 0
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 0 ;Unlock PPS
;RA0PPS = %00011101 ;Sets NCO Output to RA0, Pin 7
;RA5PPS = %00011101 ;Sets NCO Output to RA5, Pin 2
RA2PPS = %00010100 ;Sets USART TX to RA2, Pin 5
RXPPS = %00000001 ;Sets USART RX to RA1, Pin 6
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 1 ;Lock PPS
NCO1CON = %10000000
NCO1CLK = 1 ;NCO1 Clock = Fosc
PMD0 = %01000101
PMD1 = %00000101
PMD2 = %01100110
PMD3 = %01110011
PMD4 = %00000000
PMD5 = %00000111
VREGCON = 3 ;Lowest Power in SLEEP Mode
CPUDOZE = %10100100
INTCON = %01000000
TX1STA = %00000010 ;$02
RC1STA = %10010000 ;$90
BAUD1CON = %00000010
SP1BRGL = $0C ;Decimal 12, Yields 9600 BAUD
PIE1.5 = 1 ;RCIE, USART Receive Flag


;Variables:
NcoL VAR BYTE BANK0 SYSTEM ;USART NCO1INCL Value
NcoH VAR BYTE BANK0 SYSTEM ;USART NCO1INCH Value
NcoU VAR BYTE BANK0 SYSTEM ;USART NCO1INCU Value
Rec VAR BYTE BANK0 SYSTEM ;USART Receive Register Value


;Constants:
Begin CON %10010000 ;USART Command to Start NCO, $90
Halt CON %10010001 ;USART Command to Stop NCO, $91
IR CON $92 ;USART Command to Set NCO Output to LATA.5
Prb CON $93 ;USART Command to Set NCO Output to LATA.0
NcoL_Val CON %10000001 ;USART Command, Following is NcoL, $81
NcoH_Val CON %10000010 ;USART Command, Following is NcoH, $82
NcoU_Val CON %10000011 ;USART Command, Following is NcoU, $83


;Labels:
Main:
PIR1.5 = 0
PAUSE 50
DO
DO
LOOP WHILE PIR1.5 = 0
GOSUB Orders
LOOP


Run:
DO
IF PIR1.5 = 1 THEN
GOSUB Orders
ENDIF
PAUSE 1
LOOP


Slumber:
NCO1CON.7 = 0
@ DOZE
@ NOP
GOTO Main

Orders:
HSERIN [Rec]
; Rec = RC1REG
SELECT CASE Rec
CASE IS = $81
HSERIN [NcoL]
NCO1INCL = NcoL
CASE IS = $82
HSERIN [NcoH]
NCO1INCH = NcoH
CASE IS = $83
HSERIN [NcoU]
NCO1INCU = NcoU
CASE IS = $90
STKPTR = STKPTR - 1
PIR1.5 = 0
NCO1CON.7 = 1. ;Turn NCO On
PAUSE 500
NCO1CON.7 = 0. ;Turn NCO Off
PAUSE 500
NCO1CON.7 = 1. ;Turn NCO On
GOTO Run
CASE IS = $91
STKPTR = STKPTR - 1
PIR1.5 = 0
GOTO Slumber
CASE IS = $92
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 0 ;Unlock PPS
RA5PPS = %00011101 ;Sets NCO Output to RA5, Pin 2
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 1 ;Lock PPS
TRISA.0 = 1 ;Shuts Down Alt Pin LATA.0
CASE IS = $93
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 0 ;Unlock PPS
RA0PPS = %00011101 ;Sets NCO Output to RA0, Pin 7
PPSLOCK = $55
PPSLOCK = $AA
PPSLOCK = 1 ;Lock PPS
TRISA.5 = 1 ;Shuts Down Alt Pin LATA.5
END SELECT
PIR1.5 = 0
RETURN


There is a slight delay in getting the 2.4 MHz output, which for this application is acceptable. Just wondering if I might have overlooked something simple.

tumbleweed
- 19th December 2017, 11:51
Swap the order you're writing to the registers... U, H, then L.

When the NCO module is enabled, the NCO1INCU and
NCO1INCH registers should be written first, then the
NCO1INCL register. Writing to the NCO1INCL register
initiates the increment buffer registers to be loaded
simultaneously on the second rising edge of the
NCO_clk signal.

The registers are readable and writable. The increment
registers are double-buffered to allow value changes to
be made without first disabling the NCO module.

When the NCO module is disabled, the increment
buffers are loaded immediately after a write to the
increment registers.

mpgmike
- 19th December 2017, 13:13
Thank you, I'll try that.

mpgmike
- 19th December 2017, 15:30
Thanks Tumbleweed! That did the trick. Reversed the order of the Send, removed the On-Off-On in the Receiver, get my correct output right out the gate.