⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdfan.asm

📁 用24L01的2.4Ghz无线控制风扇的源程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*************************************************************************************
;IC Body:SN8P2613
;Author :Huang QingBei
;Discription:This file is composed of the main control program of MD fan.
;Resources:Use INT0 to receive IRQ form nRF24L01,T0 to time,TC0 to create buzzer.
;Version:1.0
;Version History:
;*************************************************************************************
CHIP	SN8P2613
//{{SONIX_CODE_OPTION
	.Code_Option	LVD		LVD_H		; 2.4V Reset Enable LVD36 bit of PFLAG for 3.6V Low Voltage Indicator
	.Code_Option	Reset_Pin	Reset
	.Code_Option	Watch_Dog	Disable
	.Code_Option	High_Clk	IHRC_16M	; Internal 16M RC Oscillator
	.Code_Option	Fcpu		Fosc/16
	.Code_Option	Security	Enable
	.Code_Option	Noise_Filter	Enable
//}}SONIX_CODE_OPTION

.nolist
	INCLUDESTD	MACRO1.H
	INCLUDESTD	MACRO2.H
	INCLUDESTD	MACRO3.H

	INCLUDE		MyMacro.h
.list

;--------------------------Constants Definition-----------------------

; SPI(nRF24L01) commands
	READ_REG	EQU	0x00  ; Define read command to register
	WRITE_REG	EQU     0x20  ; Define write command to register
	RD_RX_PLOAD	EQU     0x61  ; Define RX payload register address
	WR_TX_PLOAD	EQU     0xA0  ; Define TX payload register address
	FLUSH_TX	EQU     0xE1  ; Define flush TX register command
	FLUSH_RX	EQU     0xE2  ; Define flush RX register command
	REUSE_TX_PL	EQU     0xE3  ; Define reuse TX payload register command
	NO_Operation	EQU     0xFF  ; Define No Operation, might be used to read status register

; SPI(nRF24L01) registers(addresses)
	CONFIG		EQU	0x00  ; 'Config' register address
	EN_AA		EQU     0x01  ; 'Enable Auto Acknowledgment' register address
	EN_RXADDR	EQU     0x02  ; 'Enabled RX addresses' register address
	SETUP_AW	EQU     0x03  ; 'Setup address width' register address
	SETUP_RETR	EQU     0x04  ; 'Setup Auto. Retrans' register address
	RF_CH		EQU     0x05  ; 'RF channel' register address
	RF_SETUP	EQU     0x06  ; 'RF setup' register address
	STATUS		EQU     0x07  ; 'Status' register address
	OBSERVE_TX	EQU     0x08  ; 'Observe TX' register address
	CD		EQU     0x09  ; 'Carrier Detect' register address
	RX_ADDR_P0	EQU     0x0A  ; 'RX address pipe0' register address
	RX_ADDR_P1	EQU     0x0B  ; 'RX address pipe1' register address
	RX_ADDR_P2	EQU     0x0C  ; 'RX address pipe2' register address
	RX_ADDR_P3	EQU     0x0D  ; 'RX address pipe3' register address
	RX_ADDR_P4	EQU     0x0E  ; 'RX address pipe4' register address
	RX_ADDR_P5	EQU     0x0F  ; 'RX address pipe5' register address
	TX_ADDR		EQU     0x10  ; 'TX address' register address
	RX_PW_P0	EQU     0x11  ; 'RX payload width, pipe0' register address
	RX_PW_P1	EQU     0x12  ; 'RX payload width, pipe1' register address
	RX_PW_P2	EQU     0x13  ; 'RX payload width, pipe2' register address
	RX_PW_P3	EQU     0x14  ; 'RX payload width, pipe3' register address
	RX_PW_P4	EQU     0x15  ; 'RX payload width, pipe4' register address
	RX_PW_P5	EQU     0x16  ; 'RX payload width, pipe5' register address
	FIFO_STATUS	EQU     0x17  ; 'FIFO Status Register' register address

	MASK_IRQ_FLAGS  EQU     0x70	;bit mask of all INT in "Status" register
	MASK_RX_DR_FLAG EQU     0x40
	MASK_TX_DS_FLAG EQU     0x20
	MASK_MAX_RT_FLAG EQU    0x10
	RX_P_NO         EQU     0x0e

;User difined constants
	FREQ_TABLE_SIZE	EQU	15	;total 15 channels
	TX_ADDR_LENGTH	EQU	5	;5 bytes Tx address
;we use the following address when communicating with Writer
	TX_ADDR0_DEF	EQU	0x40	;default address
	TX_ADDR1_DEF	EQU	0x50
	TX_ADDR2_DEF	EQU	0x60
	TX_ADDR3_DEF	EQU	0x70
	TX_ADDR4_DEF	EQU	0x80
;Rx address of fan
	;RX_ADDR0_DEF	EQU	0x04	;default address
	;RX_ADDR1_DEF	EQU	0x05
	;RX_ADDR2_DEF	EQU	0x06
	RX_ADDR3_DEF	EQU	0x07
	RX_ADDR4_DEF	EQU	0x08
	
	RX_PLOAD_WIDTH	EQU	1	;1 byte command

	TX_CH_DEF	EQU	2	;default channel 2
	TX_PLOAD_WIDTH	EQU	4	;3 bytes access code and 1 byte command
;T0 source is slow clock,it vary according to Vcc and temperature,so if we adjust 
;the value of Vcc,we must adjust these values to make it interupt every 8 second.
	T0_RATE		EQU	00000000B
	T0C_VALUE	EQU	40
;normal mode,Fcpu=Fosc/16=1MHz(1us).Ftc0out=4kHz(Buzzer),Ftc0=2*Ftc0out=8kHz(125us).
;TC0RATE=111,TC0CLOCK=Fcpu/2=0.5MHz(2us),TC0C=256-(0.125*10^-3*1*10^6/2)=193
;The TC0 rate control bits exist in bit4~bit6 of TC0M. The
; value is from x000xxxxb~x111xxxxb.
	TC0_RATE	EQU	01110000B
	TC0C_VALUE	EQU	193

;normal mode,Fcpu=Fosc/16=1MHz(1us).Ftc0out=1kHz(Buzzer),Ftc0=2*Ftc0out=2kHz(500us).
;TC0RATE=101,TC0CLOCK=Fcpu/8=0.125MHz(8us),TC0C=256-(0.5*10^-3*1*10^6/8)=193
;The TC0 rate control bits exist in bit4~bit6 of TC0M. The
; value is from x000xxxxb~x111xxxxb.
	TC0_RATE_1k	EQU	01010000B
	TC0C_VALUE_1k	EQU	193

	BEEP_TIME_L	EQU	20	;beep long time 50ms*20=1000ms
	BEEP_TIME_S	EQU	2	;beep short time 50ms*2=100ms
	
;Define nRF24L01 interrupt flag's	
	IDLE            EQU	0x00  	;Idle, no interrupt pending
	MAX_RT          EQU	0x10  	;Max #of TX retrans interrupt
	TX_DS           EQU	0x20  	;TX data sent interrupt
	RX_DR           EQU	0x40  	;RX data received

;command
	MASK_COMM_MODE			EQU	11100000B
	MASK_COMM_KEY			EQU	00000111B
	MASK_COMM_KEY_POWER		EQU	00000001B	;bit mask corresponding to button "Power"
	MASK_COMM_KEY_SPEED		EQU	00000010B	;bit mask corresponding to button "Speed"
	MASK_COMM_KEY_TIME		EQU	00000100B	;bit mask corresponding to button "Time"

	COMM_MODE_NORMAL_KEY		EQU	00000000B	;normal key pressed event
	;COMM_MODE_ACCESS_CODE_REQ	EQU	00100000B	;request from Remote
	;COMM_MODE_ACCESS_CODE_REP	EQU	01000000B	;reply to Remote
	COMM_MODE_ACCESS_CODE_WRI	EQU	01100000B	;write by Control Panel
	COMM_MODE_ACCESS_CODE_READ	EQU	10000000B	;request from Control Panel
	COMM_MODE_ACCESS_CODE_RETURN	EQU	10100000B	;return to Control Panel
	COMM_MODE_TEST_BOARD		EQU	11100000B	;Control Panel “Board Test”Command to Fan


;power
	POWER_ON	EQU	0
	POWER_OFF	EQU	1
;speed
	SPEED_LO	EQU	0
	SPEED_MID	EQU	1
	SPEED_HI	EQU	2
;time
	TIME_NONE	EQU	0
	TIME_2H		EQU	1
	TIME_4H		EQU	2
	TIME_8H		EQU	3
;timer_count
	TIMER_COUNT_NONE	EQU	0	;no timer
	TIMER_COUNT_2H		EQU	4	;0.5hour*4=2hour
	TIMER_COUNT_4H		EQU	8	;0.5hour*8=4hour
	TIMER_COUNT_8H		EQU	16	;0.5hour*16=8hour

;access code request time allowed (form reset)
	ACC_CODE_TIME_ALLOWED	EQU	6	;counter_m=6,10s*6=60s


;-------------------------------------------------------------------

;--------------------------Variables Definition---------------------
.DATA

	AccBuf		EQU 	00h
	PFlagBuf	EQU 	01h
	counter_h	EQU	02h		;high counter,30min per unit
	counter_m	EQU	03h		;middle counter,10s per unit
	;counter_l	EQU	04h		;low counter,50 ms per unit
	irq_source	EQU	05h		;IRQ from nRF24L01,can be TX_DS,RX_DR,MAX_RT
	flag		EQU	06h		;all kinds of flags
	pload_width	EQU	07h		;pay load data width
	local_access_code0	EQU	08h	;hold the 1st byte of accss code
	local_access_code1	EQU	09h	;hole the 2nd byte of access code
	local_access_code2	EQU	0ah	;hole the 3nd byte of access code
	power		EQU	0bh		;button 'ON/OFF' state machine
	speed		EQU	0ch		;button 'Speed' state machine
	time		EQU	0dh		;button 'Time' state machine
	timer_count	EQU	0eh		;hold the timer limit
	channel		EQU	0fh		;hold the current channel value
	
	spi_data	EQU	10h		;input parameter of SPI_RW subroutine
	bit_count	EQU	11h	
	spi_reg_addr	EQU	12h		;input parameter of SPI_Read_Reg and SPI_Write_Reg subroutine
	spi_value	EQU	13h		;input parameter of SPI_Read_Reg subroutine and output parameter SPI_Read_Write subroutine
	spi_status	EQU	14h		;output parameter SPI_Read_Write subroutine
	status_temp	EQU	15h		;to hold the value of "Status" register
	ptr_table	EQU	16h		;pointer to channel table
	temp0		equ	17h
	temp1		equ	18h
	temp2		equ	19h

	EEPROMflag	equ 	1ah
	DataBuffer	equ 	1bh
	WorkingState	equ 	1ch
	ErrorCount	equ	1dh
	test_data0	equ	1eh
	test_data1	equ	1fh

	data_buf	EQU	20h
	command		EQU	data_buf	;explain what action to take
	access_code0	EQU	data_buf+1	;received from user,should be compared with local one
	access_code1	EQU	data_buf+2	;received from user,should be compared with local one
	access_code2	EQU	data_buf+3	;received from user,should be compared with local one
	
;-------------------------------------------------------------------

;---------------------------Port Definition-------------------------

;---------------------------Bit Flag Definition---------------------
	F_10S_ARRIVED	EQU	flag.0
	F_CHECK_CD	EQU	flag.1
	
	BIT_KEY_POWER	EQU	command.0
	BIT_KEY_SPEED	EQU	command.1
	BIT_KEY_TIME	EQU	command.2



;Contral pin
	PIN_CTRL_LO	EQU	P1.7	;output
	PIN_CTRL_MID	EQU	P1.6	;output
	PIN_CHIP_RESET	EQU	P1.5
	PIN_CTRL_HI	EQU	P1.4	;output
;EEPROM I2C pin	
	PIN_I2C_SDA	EQU	P1.3	;output
	PIN_I2C_SCL	EQU	P1.2	;output
;LED pin
	PIN_LED_8H	EQU	P5.1	;output
	PIN_LED_4H	EQU	P5.0	;output
	PIN_LED_2H	EQU	P0.0	;output
	PIN_LED_HI	EQU	PIN_CTRL_HI	;multiplex with ctrl pin
	PIN_LED_MID	EQU	P1.0	;PIN_CTRL_MID
	PIN_LED_LO	EQU	P1.1	;PIN_CTRL_LO

;nRF24L01 pin
	PIN_IRQ_nRF24L01 EQU	P0.1	;input,Interrupt signal, from nRF24L01 
	PIN_SPI_MISO	EQU	P5.7	;input,Master In, Slave Out pin
	PIN_CE_nRF24L01	EQU	P5.6	;output,Chip Enable pin signal	 
	PIN_SPI_CLK	EQU	P5.5	;output,Serial Clock pin
	PIN_BUZZER	EQU	P5.4	;output
	PIN_SPI_CSN	EQU	P5.3	;output,Slave Select pin(to CSN, nRF24L01)	
	PIN_SPI_MOSI	EQU	P5.2	;output,Master Out, Slave In pin 

;---------------------------------------------
	SDA		equ	PIN_I2C_SDA
	SDA_IoSet	equ	@INT(PIN_I2C_SDA)-0x10.@BIT(PIN_I2C_SDA)
	SCL		equ	PIN_I2C_SCL
	SCL_IoSet	equ	@INT(PIN_I2C_SCL)-0x10.@BIT(PIN_I2C_SCL)

	I2CackFlag	equ	EEPROMflag.0
	I2CjoinErrorFlag	equ	EEPROMflag.1
	I2Csave		equ	EEPROMflag.2
;--------------------------------------------------------------------

;-----------------------------Code Section---------------------------
.CODE

	ORG 	00h
	jmp	Reset

	ORG 	08h
	jmp 	ISR

;---------------------------DigiTable Definition---------------------
	ORG 	10h
Freq_Agil_Table:
	DW	2,27,52,7,32,57,12,37,62,17,42,67,22,47,72

;--------------------------------------------------------------------
	INCLUDE		EEPROM24C02.ASM
	INCLUDE		nRF24L01.ASM
	INCLUDE		Misc.asm
	
Reset:
	movmi 	STKP, #07h  		;Initial stack pointer and disable global interrupt
	clr  	PFLAG 			;pflag = x,x,x,x,x,c,dc,z
	clr	OSCM			;Initial system mode
	clrwdt				;clear WatchDog Timer
	call 	ClrRAM 			;Clear RAM	
	call 	SysInit 		;System initial
	;-----------------------------
	jb1	PIN_IRQ_nRF24L01, User_Mode
	jb0	PIN_SPI_MISO, Test_Board	;IRQ,MISO=00,goto test board
User_Mode:
	;-----------------------------
	call	Start_Up_Fan		;run at Speed Mid while lit LED_Lo
	call	BeepLong		;beep for announcement of power-on
	call	Load_AccessCode		;load access code to local_access_code0,local_access_code1 and ptr_table		
	call	Get_Channel		;look up channel table to get a channel to stay	
	call	nRF24L01_Configure	;Configure RF,go to Rx Mode
	call	Init_T0			;T0 int occoured every 10s
	call	Enable_RF_INT		;begin to allow RF INT come in
;note that there are only 4 stack level in total,be careful of the use of subroutine
;not to call too deep in the program,or it will overflow
Main_Loop:
	SLOW			;go to Slow Mode
	GREEN			;go to Green Mode.MCU stops.Only wake-up by T0 and INT from RF
	nop			;MCU wake up here
	NORMAL			;go back to Normal mode when wake-up
	clrwdt			;clear WatchDog Timer
	call	Check_10s	;run at speed mid for the first 10s then change to speed low?
	call	Check_Auto_ShutDown	;it's timer set?need to auto shut down?
	call	Check_CD	;it's time to check CD?need to change to next channel? 
	
Command_Handle:	
	mov	A, irq_source
	cmprs	A, #IDLE
	jz	Main_Loop		;wake-up by T0,go back to Main_Loop
	B0BCLR	FP01IEN			;disable INT from nRF24L01
	mov	A, irq_source
	cmprs	A, #RX_DR
	jz	Rx_Data_Ready		;INT triggerd by RX_DR
	cmprs	A, #TX_DS
	jz	Tx_Data_Sent		;INT triggerd by TX_DS
	cmprs 	A, #MAX_RT
	jz	Max_Retries		;INT triggerd by MAX_RT
	
Command_Handle_End:
	clr	irq_source
	B0BSET	FP01IEN			;enable INT from nRF24L01
	jmp	Main_Loop
	;nop
	;nop				;give some time to handle newly come in INT
	;jmp	Command_Handle		;is there any new INT come in when we are handling the last IRQ?

;===========================================================================
Rx_Data_Ready:
	rrc	status_temp		;A<-RRC status_temp
	and	A, #07h			;get low 3 bit for Pipe Number
	add 	A, #RX_PW_P0		;get Pipe address
	mov	spi_reg_addr, A		;write the address to read from
	call	SPI_Read_Reg		;read pay load width
	movmm	pload_width, spi_value
;Rx data and store in data_buf	
	clr	Y
	movmi	Z, #data_buf		;@YZ point to data_buf
	bclr	PIN_SPI_CSN		;enable SPI
	movmi	spi_data, #RD_RX_PLOAD
	call	SPI_RW			;we are now reading Rx pay load
Receive_Lop:	
	clr	spi_data
	call	SPI_RW			;read 1 byte data
	movmm	@YZ, spi_data		;store it to data_buf
	inc	Z			;point to the next byte in data_buf
	djnz	pload_width, Receive_Lop	;data end?
	bset	PIN_SPI_CSN		;disable SPI
	
	call	Flush_Rx_FIFO
	mov	A, command
	and	A, #MASK_COMM_MODE
	cmprs	A, #COMM_MODE_NORMAL_KEY
	jz	Normal_Key		;M[2..0]=000,normal key command
	cmprs	A, #COMM_MODE_ACCESS_CODE_READ
	jz	Access_Code_Read	;M[2..0]=001,access code request from user
	cmprs	A, #COMM_MODE_ACCESS_CODE_WRI
	jz	Access_Code_Wri		;M[2..0]=011,write access code command from worker
	;------------Board test command is sent by Writer----------------------
	cmprs	A, #COMM_MODE_TEST_BOARD
	jz	Test_Board		;M[2..0]=111,“Board Test”Command from Writer
	;----------------------------------------------------------------------
	jmp	Command_Handle_End	;unhandle command mode,return

;--------------------------------------------------------------------------	
Normal_Key:

	mov	A, command
	and	A, #MASK_COMM_KEY
	cmprs	A, #MASK_COMM_KEY_POWER
	jz	Handle_Power		;KEY[2..0]=001,'ON/OFF' command
	cmprs	A, #MASK_COMM_KEY_SPEED
	jz	Handle_Speed		;KEY[2..0]=010,'Speed' command
	cmprs	A, #MASK_COMM_KEY_TIME
	jz	Handle_Time		;KEY[2..0]=100,'Time' command
	jmp	Command_Handle_End	;unhandle command

Handle_Power:
	call	BeepShort		;beep for short while to indicate a valid command received
	mov	A, power
	cmprs	A, #POWER_ON		;we are now in 'POWER_ON' state?
	jz	Power_On2Off
Power_Off2On:				;we are now in 'POWER_OFF' state
	movmi	power, #POWER_ON	;a press in this state change the state to 'POWER_ON'

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -