📄 mdfan.asm
字号:
;*************************************************************************************
;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 + -