📄 dmx512trmtdemo.asm
字号:
;*********************************************************************************************
; Software License Agreement *
; The software supplied herewith by Microchip Technology Incorporated *
; (the "Company") is intended and supplied to you, the Company's *
; customer, for use solely and exclusively on Microchip products. *
; *
; The software is owned by the Company and/or its supplier, and is *
; protected under applicable copyright laws. All rights are reserved. *
; Any use in violation of the foregoing restrictions may subject the *
; user to criminal sanctions under applicable laws, as well as to *
; civil liability for the breach of the terms and conditions of this *
; license. *
; *
; THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, *
; WHETHER EXPRESS, IMPLIED OR STATU-TORY, INCLUDING, BUT NOT LIMITED *
; TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
; PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, *
; IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR *
; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. *
; *
;*********************************************************************************************
; File: DMX512TrmtDemo.asm
; DMX512 Transmitter demo
;
; This source code uses the PIC18F2420 to transmit a DMX-512 packet via
; the EUSART peripheral. An external 16MHz clock input is used.
; The DMX transmitter code is written as a polled state machine with
; 4 states. The state machine is called periodically from the main
; software loop and a jump table determines the present state.
; Timer0 is used to control the state machine timing, including length
; of the break signal and the spacing between transmitted bytes.
; The CCP module is configured to start an ADC conversion every 10msec.
; A potentiometer voltage is sampled with the ADC and the result is
; written to the first data slot in the DMX frame to control a remote
; device.
list p=PIC18F24J10 ; define targe processor
#include <P18F24J10.inc> ; include processor specific definition
;Configuration bits setup
CONFIG CCP2MX = ALTERNATE ; assign CCP2 output to pin RB3
CONFIG WDTEN = OFF ; To use ICD2 as a debugger disable Watch Dog Timer
CONFIG STVREN = ON ; Reset on stack overflow/underflow enabled
CONFIG XINST = OFF ; Instruction set extension and Indexed Addressing
; mode disabled (Legacy mode)
CONFIG CP0 = OFF ; Program memory is not code-protected
CONFIG FOSC = ECPLL ; EC oscillator, PLL enabled and under software
; control, CLKO function on OSC2
CONFIG FOSC2 = ON ; Clock selected by FOSC as system clock is enabled
; when OSCCON<1:0> = 00
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor disabled
CONFIG IESO = OFF ; Two-Speed Start-up disabled
CONFIG WDTPS = 32768 ; 1:32768
; Timing constants (assuming 16MHz clock input and assigned prescaler
; values to produce 1us tick)
#define T100US .256-.100 ; preload value for TMR0 to roll over in 100us
#define T60US .256-.60 ; 60us value
; Variables memory allocation
CBLOCK 0x008
DmxTxState ; State Variable
CountH ; 16-bit counter
CountL
TxBuffer: .512 ; allocate 512 bytes for the transmit buffer
ENDC
;****************************************************************************************
ORG 0x0000
Main
rcall InitTX ; initialize the I/O ports and TMR0
rcall SetupSerial ; initialize serial comm
rcall SetupADC ; initialize the ADC for the demo
;****************************************************************************************
;Main Application Loop
MainLoop
rcall DMXTransmit ; Execute the state machine
rcall CheckADC ; Check to see if ADC conversion is
; complete.
goto MainLoop
;****************************************************************************************
;DMX Transmit state machine
DMXTransmit
; The DMX transmit code is driven by the TMR0 roll-over
; events. Just return if a roll-over has not occured.
btfss INTCON,TMR0IF ; wait until TIMER0 roll-over
return
bcf INTCON,TMR0IF ; clear the flag
clrf PCLATH ; (assumes the jump table is located in
; the first page of program memory)
rlncf DmxTxState,W ; state x2 to account for PC byte
; addressing
andlw 0x0E ; reduce offset to valid range (0-14)
addwf PCL ; computed jump
; Jump Table
bra SENDMBB ; 0 IDLE period after each complete frame
bra SENDDATA ; 1 send one byte of data
bra SENDMAB ; 2 IDLE period between BREAK and START slot
bra SENDBREAK ; 3 BREAK synchronization signal
reset ; not used
reset ; not used
reset ; not used
reset ; not used
; DmxTxState = 3. Generates a Break Signal (100uSec)
SENDBREAK
bsf TRISC,5 ; tri-state pin RC5 to end break signal
movlw T100US ; preload TIMER0 for a roll over in 100us
movwf TMR0L
decf DmxTxState,F ; proceed to State2 SENDMAB
return
; DmxTxState = 2. Mark After Break (line IDLE for 100uSec) send a start code
SENDMAB
clrf CountL ; init 16-bit counter
clrf CountH
lfsr 1,TxBuffer ; init pointer to transmit buffer
clrf TXREG ; send NULL START CODE
movlw T60US ; pre-load TMR0 for a short delay (> (12bit x 4us) >48us)
movwf TMR0L
decf DmxTxState,F ; proceed to state1 SENDDATA
return
; DmxTxState = 1. wait for UART to complete transmission of current byte and an
; additional short amount of time
SENDDATA
btfsc CountH,1 ; check if 512 slot sent already
bra TXDone
btfss PIR1,TXIF ; make sure TX buffer is available
return
movff POSTINC1,TXREG ; send a new byte of data (use IND1 pointer to read
; data from TX buffer) automatically advance pointer 1
incf CountL,F ; increment 16-bit counter
btfsc STATUS,C
incf CountH,F
movlw T60US ; pre-load TMR0 for a short delay (> (12bit x 4us) >48us)
movwf TMR0L
return
TXDone
movlw T100US ; pre-load TMR0 for a 100us delay before the frame repeats
movwf TMR0L
decf DmxTxState,F ; proceed to next state SENDMBB
return
;DmxTxState = 0. sends Mark Before repeating the frame transmission
SENDMBB
movlw T100US ; pre-load the timer for 100us BREAK
movwf TMR0L
bcf INTCON,TMR0IF ; clear the flag
bcf TRISC,5 ; make pin RC5 an output
bcf LATC,5 ; pull pin RC5 low to force a break condition
movlw .3 ; proceed to State3 SENDBREAK
movwf DmxTxState
return
;****************************************************************************************
;CheckADC verify a new conversion result is available and copy the value to
; 6 channels/location in the TX buffer
CheckADC
btfss PIR1,ADIF ; check the flag for ADC conversion completed
return
bcf PIR1,ADIF ; clear the ADC flag
bcf PIR2,CCP2IF ; clear the Compare flag
lfsr 0,TxBuffer ; use indirect pointer IND0 to copy the conversion result
movff ADRESH,POSTINC0 ; to the first slot in the transmit buffer (->1)
movff ADRESH,POSTINC0 ; slot 2
movff ADRESH,POSTINC0 ; slot 3
movff ADRESH,POSTINC0 ; slot 4
lfsr 0,TxBuffer + .508
movff ADRESH,POSTINC0 ; slot 509
movff ADRESH,POSTINC0 ; slot 510
movff ADRESH,POSTINC0 ; slot 511
movff ADRESH,POSTINC0 ; slot 512
; Note: This code places the transmit data in the first 4 data slots
; and the last 4 data slots of the DMX data frame. This was done to
; make sure that the code worked properly with a 4-channel dimmer
; unit that was used during code development. Add code above as
; required to fill other slots with transmit data.
return
;****************************************************************************************
;Setup Serial port
SetupSerial
bsf TRISC,7 ; allow the UART RX to control pin RC7
bsf TRISC,6 ; allow the UART TX to control pin RC6
movlw 0x65 ; enable TX, 9-bit mode, high speed mode, 9th bit =1 (2 stop)
movwf TXSTA
movlw 0x80 ; enable serial port, disable receiver
movwf RCSTA
bsf BAUDCON,BRG16 ; select EUART 16-bit Asynchrnounou mode operation
movlw .15 ; init baud rate generator for 250k baud (assume Fosc=16MHz)
movwf SPBRG
return
;****************************************************************************************
;ADC setup
SetupADC
bsf TRISA,0 ; make RA0 an input pin
movlw 0x01 ; enable ADC and select input channel 0
movwf ADCON0
movlw 0x0E ; make only channel 0 an analog input pin
movwf ADCON1
movlw 0x35 ; ADC result left aligned and clock = Fosc/16
movwf ADCON2
;Set the CCP2 module in Compare mode with a 10mSec interval, CCPR2 = 10.000us
movlw 0x27
movwf CCPR2H
movlw 0x10
movwf CCPR2L
;A/D Conversion started by the Special Event Trigger of the CCP2 module
movlw 0x0B
movwf CCP2CON
;init Timer1 as the time base for CCP2
clrf TMR1H
clrf TMR1L
movlw 0x21 ; enable 16-bit Timer1, prescale 1:4 (1us tick@16MHz),
movwf T1CON ; internal clock
return
;****************************************************************************************
;InitTX init Timer0, clear TXbuffer, init state machine
InitTX
clrf CountL ; init 16-bit counter
clrf CountH
; clear Transmit buffer
lfsr 1,TxBuffer ; use IND1 pointer to address the RAM buffer
CBloop
clrf POSTINC1 ; clear the location pointed to by IND1 then increment pointer
incf CountL,F ; increment 16-bit counter
btfss STATUS,C
bra CBloop
incf CountH,F
btfss CountH,1 ; check if counter >= 512
bra CBloop
; init Timer0
movlw 0xC1 ; enable Timer0, as an 8-bit timer, use prescaler 1:4
movwf T0CON ; (1us tick@16MHz)
movlw T100US ; preload timer for 100us interval to roll over
movwf TMR0L
bcf INTCON,TMR0IF ; clear roll over flag
; init state machine
movlw .03 ; Start with BREAK state
movwf DmxTxState
bcf TRISC,5 ; make pin RC5 an output
bcf LATC,5 ; pull RC5 output low to force a break condition
return
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -