基于义隆单片机汇编模拟SPI总线

  • EM78P372N
  • 操作对象LT8920
  1 ;+++++++++++++++++++++++++++++
  2 ;            RF相关巨集
  3 ;+++++++++++++++++++++++++++++
  4 ;.........................................
  5 ;    RF相关IO口初始化配置
  6 ;SPI引脚
  7 ;    spi_ss        ==        PORT6.6        ;spi使能信号引脚
  8 ;    spi_clk        ==        PORT6.4        ;spi时钟信号引脚
  9 ;    spi_miso    ==        PORT6.0        ;spi主器件输入引脚
 10 ;    spi_mosi    ==        PORT6.1        ;spi主器件输出引脚
 11 ;    RF_Reset    ==        PORT6.5        ;RF芯片复位引脚,低电平复位
 12 ;.........................................
 13 Conf_IO_RF        MACRO
 14                 S_IOC_0
 15                 IOR        IOC60
 16                 AND        A,@0b10001100
 17             ;    OR        A,@0b00000001
 18                 IOW        IOC60
 19                 
 20                 ;Port7配置,P70,P71没有内部下拉和上拉
 21                 CLR        Port7        ;[0] 清空P7
 22                 S_IOC_0                ;[1] 设置为输入
 23                 MOV        A,@0x01        ;[2]
 24                 IOW        IOC70        ;[3]
 25                 ENDM
 26 ;........................................
 27 
 28 
 29 Collection_RF_Func    MACRO
 30 
 31 
 32 ;-----------------------------------
 33 ;Function: RF_Enter_Sleep_State
 34 ;Input:    None
 35 ;Output:   None
 36 ; 进入Sleep Mode 睡眠模式,在此模式电流只有 6uA
 37 ;-----------------------------------
 38 RF_Sleep:
 39     WDTC
 40     BANK    1
 41     MOV        A,@0x42
 42     MOV        RFReg_DataH,A
 43     
 44     MOV        A,@0x00
 45     MOV        RFReg_DataL,A
 46     
 47     MOV        A,@0x23
 48     MOV        RFReg_Addr,A
 49     BANK    0
 50     XCALL    RF_WriteReg
 51     ret
 52 ;------------------------------------
 53 ;Function: RF Wake Up    RF唤醒,需要2ms
 54 ;Input:    None
 55 ;Output:   None
 56 ;------------------------------------
 57 RF_Wakeup:
 58     BC        spi_ss
 59     DELAY_xms    2
 60 WAIT_T:
 61     BS        spi_ss
 62     BANK    1
 63     MOV        A,@0x02
 64     MOV        RFReg_DataH,A
 65     
 66     MOV        A,@0x00
 67     MOV        RFReg_DataL,A
 68     
 69     MOV        A,@0x23
 70     MOV        RFReg_Addr,A
 71     BANK    0
 72     XCALL    RF_WriteReg
 73     ret
 74 
 75 ;---------------------------------------
 76 ;    检查有没有接收到数据 读Reg48
 77 ;---------------------------------------
 78 RF_CheckPKT:
 79     WDTC
 80     BC        BitPKT
 81     BANK    1
 82     MOV        A,@48
 83     MOV        RFReg_Addr,A
 84     BANK    0
 85     XCALL    RF_ReadReg
 86     BANK    1
 87     JBS        RFReg_DataL.6        ;[0] PKT_Flag标志
 88     JMP        Check_PKT_EXIT        ;[1] 1:表示接收到数据
 89     JBC        RFReg_DataH.7        ;[0] CRC错误标志
 90     JMP        Check_PKT_EXIT        ;[1] 0:表示正确
 91     BS        BitPKT
 92 Check_PKT_EXIT:
 93     BANK    0
 94     RET
 95 ;---------------------------------------
 96 ;    读FIFO,读Reg50
 97 ;---------------------------------------
 98 RF_Read_FIFO:
 99     WDTC
100     CLR        R4                ;[0] 把数据的第一个地址给指针
101     MOV        A,@RF_Dat0        ;[1]
102     OR        R4,A            ;[2]
103     
104     BC        spi_ss
105     BANK    1                ;[0] Reg50是FIFO的入口
106     MOV        A,@0xB2            ;[1] 0x30 | 0x80 = 0xB2(地址高位置1,表示读操作)
107     MOV        RFReg_Addr,A    ;[2] 先通过spi总线写入地址,并读操作
108     BANK    0                ;[3]
109     XCALL    SPI_Write        ;[4]
110     nop
111     nop
112     XCALL    SPI_Read        ;[0] 读第一个字节,
113     BANK    1                ;[1] 第一个字节表示FIFO数据字节长度
114     MOV        A,RF_SPIBuf        ;[2] 
115     MOV        RF_Length,A        ;
116     MOV        R0,A            ;
117     INC        R4                ;
118     
119     XOR        A,@0x8            ;[0] 判断第一个字节是不是8,
120     JBS        Z                ;[1] 若不是,退出函数
121     JMP        RF_Read_FIFO_END;[2]
122     BANK    0
123 Read_FIFO_Loop:
124     WDTC
125     nop
126     xcall    SPI_Read        ;[0] 读取FIFO中的剩余数据
127     BANK    1                ;[1]
128     MOV        A,RF_SPIBuf        ;[2]
129     MOV        R0,A            ;[3]
130     INC        R4                ;[4]
131     DJZ        RF_Length        ;[5] 判断是否读完
132     JMP        Read_FIFO_Loop    ;[6]
133     BANK    0                ;[7]
134     
135 RF_Read_FIFO_END:
136     BS        spi_ss
137     BANK    0
138     RET
139 ;---------------------------------------
140 ;        频点切换
141 ;---------------------------------------
142 RFChannel_Chg:
143     WDTC
144     XCALL    RF_ChannelTable        ;选择频点
145     BANK    1
146     MOV        RF_Channel,A
147     MOV        RFReg_DataL,A
148     CLR        RFReg_DataH
149     BANK    0
150     XCALL    RF_WR_Reg7
151     
152     XCALL    RF_CLR_Point        ;清空读写指针
153     
154     BANK    1
155     CLR        RFReg_DataH
156     MOV        A,RF_Channel
157     OR        A,@0x80
158     MOV        RFReg_DataL,A
159     BANK    0
160     XCALL    RF_WR_Reg7
161     
162     RET
163 ;---------------------------------------
164 ;        写Reg7寄存器,设置接收频点
165 ;---------------------------------------
166 RF_WR_Reg7:
167     WDTC
168     BANK    1
169     MOV        A,@0x07
170     MOV        RFReg_Addr,A
171     BANK    0
172     XCALL    RF_WriteReg
173     RET
174 ;---------------------------------------
175 ;    写Reg7寄存器,设置一个不存在的接收频点
176 ;以解决以下问题:
177 ;1.    RF在准备接收期间,功耗最大,接收到数据后,停止接收 
178 ;    功耗会减小,电源电流有波动,造成低亮度下会抖动,这样
179 ;    在接收到数据后,再设置一个不存在的频点,使高功耗时间相对
180 ;    增加,这样,可以减轻电源电流不稳
181 ;2. 检测到RF接收到数据后,RF必须要重新设置为接收模式,
182 ;    否则,不能清除48号寄存器中PKT标志位
183 ;---------------------------------------
184 RF_WR_Reg7_NG:
185     WDTC
186     BANK    1
187     CLR        RFReg_DataH
188     MOV        A,@13            
189     OR        A,@0x80            
190     MOV        RFReg_DataL,A    
191     BANK    0                
192     XCALL    RF_WR_Reg7        
193     RET
194 ;---------------------------------------
195 ;        清空读写指针
196 ; 在52号寄存器中写入 0x8080 即可清空读写指针
197 ;---------------------------------------
198 RF_CLR_Point:
199     WDTC
200     BANK    1
201     MOV        A,@52
202     MOV        RFReg_Addr,A
203     MOV        A,@0x80
204     MOV        RFReg_DataH,A
205     MOV        A,@0x80
206     MOV        RFReg_DataL,A
207     BANK    0
208     XCALL    RF_WriteReg
209     RET
210 
211 ;--------------------------------------
212 ;SPI总线写8bit数据
213 ;IntPut: A,要写入RF的8bit数据
214 ;OutPut:    
215 ;--------------------------------------
216 SPI_Write:
217     WDTC
218     BANK    1
219     MOV        RF_SPIBuf,A        ;准备写入的 1 byte 数据
220     
221     MOV        A,@8
222     MOV        RF_SPICnt,A
223 SPI_WR_8Bit:
224     BS        spi_clk            ;[0]
225     RLC        RF_SPIBuf        ;[1]把RF_SPIBuf的最高位送给spi_mosi端口
226     JBC        C                ;[2]并产生一个下降沿,
227     BS        spi_mosi        ;[3]以使1bit数据传送给RF
228     JBS        C                ;[4]
229     BC        spi_mosi        ;[5]
230     BC        spi_clk            ;[6]
231     
232     DJZ        RF_SPICnt        ;[0]判断8bit数据是否都送给了RF
233     JMP        SPI_WR_8Bit        ;[1]
234     
235 SPI_Write_END:
236     BANK    0
237     RET
238 ;--------------------------------------
239 ;SPI总线读8bit数据
240 ;IntPut:
241 ;OutPut: A,从RF读取到的 1byte 数据
242 ;--------------------------------------
243 SPI_Read:
244     WDTC
245     BANK    1
246     
247     MOV        A,@8
248     MOV        RF_SPICnt,A
249 SPI_RD_8Bit:
250     BS        spi_clk            ;[0]提供一个下降沿时钟信号,读取1bit数据
251     nop                        ;[1]
252     nop                        ;[2]
253     BC        spi_clk            ;[3]
254     BANK    0
255     MOV        R5,R5            ;读Port5引脚,必要的
256     BANK    1
257     JBS        spi_miso        ;[0]把spi_miso引脚状态送入RF_SPI_Buf
258     BC        C                ;[1]
259     JBC        spi_miso        ;[2]
260     BS        C                ;[3]
261     RLC        RF_SPIBuf        ;[4]带进位左移
262     DJZ        RF_SPICnt        ;[0]判断8bit数据是否读完
263     JMP        SPI_RD_8Bit        ;[1]
264 SPI_Read_END:
265     MOV        A,RF_SPIBuf        ;把读取到的数据送给A,以节省ROM
266     BANK    0
267     RET
268 ;--------------------------------------
269 ;SPI总线写 2 Byte 数据到 RF 寄存器
270 ;IntPut:
271 ;         RFReg_Addr,要写入RF的寄存器地址
272 ;         RFReg_DataH,要写入RF寄存器的高8位数据
273 ;         RFReg_DataL,要写入RF寄存器的低8位数据
274 ;OutPut:    
275 ;--------------------------------------
276 RF_WriteReg:
277     WDTC
278     nop
279     nop
280     BC        spi_ss            ;操作读写spi需要把spi_ss引脚拉低
281     BANK    1
282     MOV        A,RFReg_Addr
283     XCALL    SPI_Write
284     nop            ;[0]地址与数据之间要有一段间隔,
285     nop            ;[1]时间资料未标出,实测1个nop指令即可
286                 ;[2]实际使用可以不用加,因为两次操作之间隔了几条指令足够了
287     BANK    1
288     MOV        A,RFReg_DataH
289     XCALL    SPI_Write
290     nop
291     nop
292     BANK    1
293     MOV        A,RFReg_DataL
294     XCALL    SPI_Write
295     BS        spi_ss
296 RF_WriteReg_END:
297     nop
298     nop
299     BANK    0
300     RET
301 
302 ;--------------------------------------
303 ;SPI总线从 RF 寄存器读取 2 Byte 数据 
304 ;IntPut:
305 ;         RFReg_Addr,要读取RF的寄存器地址
306 ;OutPut:
307 ;         RFReg_DataH,从RF寄存器读取到的高8位数据
308 ;         RFReg_DataL,从RF寄存器读取到的低8位数据
309 ;--------------------------------------
310 RF_ReadReg:
311     WDTC
312     nop                        ;两次操作spi间隔要大于250ns
313     nop                        ;为了防止连续操作,函数前后各加2个nop
314     BC        spi_ss
315     BANK    1
316     MOV        A,RFReg_Addr
317     OR        A,@0x80            ;bit7置1,读寄存器,0,写寄存器
318     XCALL    SPI_Write
319     nop
320     nop
321     XCALL    SPI_Read
322     BANK    1
323     MOV        RFReg_DataH,A
324     BANK    0
325     nop
326     nop
327     XCALL    SPI_Read
328     BANK    1
329     MOV        RFReg_DataL,A
330     BANK    0
331     BS        spi_ss
332     
333 RF_ReadReg_END:
334     nop
335     nop
336     BANK    0
337     RET
338 ;--------------------------------------
339 ;初始化RF
340 ;--------------------------------------
341 RF_Init:
342     WDTC
343     BANK    1
344     CLR        RFInit_Cnt
345     BANK    0
346 RF_Init_Start:
347     BANK    1                ;[0] 如果初始化不成功,再初始化2次
348     INC        RFInit_Cnt        ;[1] 三次初始化都不成功,就退出
349     MOV        A,RFInit_Cnt    ;[2] 初始化失败,不能使用遥控器操作
350     BANK    0                ;[3] 如有需要,在RF始化失败的情况下,做一个LED闪烁提示
351     SUB        A,@0x03            ;[4] 并使LED亮一个合适的值
352     JBS        C                ;[5]
353     JMP        RF_Init_END        ;[6]
354     
355 VDD_RST:
356     BC        RF_Reset        ;[0] VDD稳定后,确保RF芯片复位一次
357     Delay_xms    20            ;[1]
358     BS        RF_Reset        ;[2]
359     Delay_xms    20            ;[3] 等待晶振稳定
360     
361     BANK    1
362     CLR        RF_RegCnt        ;查表数据清零
363     BANK    0
364 Reg_Init:
365     WDTC
366     
367     BANK    1
368     INC        RF_RegCnt
369     BANK    0
370     XCALL    RF_RegTable        ;查表
371     BANK    1
372     MOV        RFReg_DataH,A    ;RF寄存器高8位数据
373     BANK    0
374     
375     BANK    1
376     INC        RF_RegCnt
377     BANK    0
378     XCALL    RF_RegTable        ;查表
379     BANK    1
380     MOV        RFReg_DataL,A    ;RF寄存器低8位数据
381     BANK    0
382     
383     BANK    1
384     INC        RF_RegCnt
385     BANK    0
386     XCALL    RF_RegTable        ;查表
387     BANK    1
388     MOV        RFReg_Addr,A    ;RF寄存器地址
389     BANK    0
390     
391     XCALL    RF_WriteReg        ;写RF寄存器
392 ;判断是否配置完了最后一个寄存器
393 RF_RegEND:        
394     XCALL    RF_RegTable
395     XOR        A,@0x2D
396     JBS        Z
397     JMP        Reg_Init
398 ;读取一个寄存器,判断是否成功写入数据,若不是,重新初始化,最多3次
399 RF_Check:    
400     BANK    1                ;[0] 读Reg0
401     mov        A,@0x00            ;[1] 判断读取的值,是否是 0x6FE0
402     mov        RFReg_Addr,A    ;[2]
403     MOV        A,@0            ;[3]
404     mov        RFReg_DataH,A    ;[4]
405     MOV        A,@0            ;[5]
406     MOV        RFReg_DataL,A    ;[6]
407     BANK    0                ;[7]
408     XCALL    RF_ReadReg        ;[8]
409     
410     BANK    1                ;[0] RFReg_DataH = 0x6F ?
411     MOV        A,RFReg_DataH    ;[1]
412     BANK    0                ;[2]
413     XOR        A,@0x6F            ;[3]
414     JBS        Z                ;[4]
415     JMP        RF_Init_Start    ;[5]
416     
417     BANK    1                ;[0] RFReg_DataL = 0xE0 ?
418     MOV        A,RFReg_DataL    ;[1]
419     BANK    0                ;[2]
420     XOR        A,@0xE0            ;[3]
421     JBS        Z                ;[4]
422     JMP        RF_Init_Start    ;[5]
423     
424 RF_Init_END:
425     nop
426     RET
427 ;---------------------------------------
428 ;        RF寄存器表格
429 ;---------------------------------------
430 RF_ChannelTable:
431     WDTC
432     BANK    1
433     INC        RF_ChannelCnt
434     MOV        A,RF_ChannelCnt
435     SUB        A,@1
436     JBS        C
437     CLR        RF_ChannelCnt
438     MOV        A,RF_ChannelCnt
439     BANK    0
440     
441     ADD        PC,A
442 ;    nop                ;注意这里不需要 nop
443 ;    RETL    23
444 ;    RETL    34        
445     RETL    03        ;RETL    @03,加不加"@"都行,校验码一样编译器自动识别RETL指令
446     
447 ;    RETL    15
448 ;    RETL    41        
449     RETL    76
450 
451 ;---------------------------------------
452 ;        RF寄存器查表表格
453 ;---------------------------------------
454 RF_RegTable:
455     WDTC
456     BANK    1
457     MOV        A,RF_RegCnt
458     BANK    0
459     ADD        PC,A
460     
461     nop        ;这个nop指令绝对不能少,也不能,因为执行到ADD    PC,A时,PC的预装载值已经自加了1 
462     
463     RETL    @0x48        ;RF寄存器高8位数据
464     RETL    @0x00        ;RF寄存器低8位数据
465     RETL    @0x20        ;RF寄存器地址 Reg32,该寄存器作用配置数据包的一些必要参数
466     
467     RETL    @0x3F
468     RETL    @0xC7
469     RETL    @0x21        ;Reg33,
470     
471     RETL    @0x20
472     RETL    @0x00
473     RETL    @0x22        ;Reg34
474     
475     RETL    @0x02
476     RETL    @0x00
477     RETL    @0x23        ;Reg35
478     
479     ;[0] Reg36,Reg37,Reg38,Reg39,四个寄存器为SYNCWORD(同步字)
480     ;[1] 接收与发射同步字必须相同,否则无法接收
481     ;[2] Reg32的 Bit[12:11] 可以配置同步字的长度,我们用两个同步字 Reg36,Reg39
482     RETL    @0x5D        
483     RETL    @0x26
484     RETL    @0x24        ;Reg36 同步字0
485     
486 ;    RETL    @0x15
487 ;    RETL    @0x28
488 ;    RETL    @0x25        ;Reg37 同步字1
489     
490 ;    RETL    @0x15
491 ;    RETL    @0x28
492 ;    RETL    @0x26        ;Reg38 同步字2
493     
494     RETL    @0x94
495     RETL    @0xFB
496     RETL    @0x27        ;Reg39 同步字3
497     
498     RETL    @0x44
499     RETL    @0x01
500     RETL    @0x28        ;Reg40
501     
502     RETL    @0xb0
503     RETL    @0x00
504     RETL    @0x29        ;Reg41
505     
506     RETL    @0xFD
507     RETL    @0xB0
508     RETL    @0x2A        ;Reg42
509     
510     RETL    @0x00
511     RETL    @0x0F
512     RETL    @0x2B        ;Reg43
513     
514     RETL    @0x6F
515     RETL    @0xE0
516     RETL    @0x00        ;Reg0
517     
518     RETL    @0x56
519     RETL    @0x81
520     RETL    @0x01        ;Reg1
521     
522     RETL    @0x66
523     RETL    @0x17
524     RETL    @0x02        ;Reg2
525     
526     RETL    @0x9C
527     RETL    @0xC9
528     RETL    @0x04        ;Reg4
529     
530     RETL    @0x66
531     RETL    @0x37
532     RETL    @0x05        ;Reg5
533     
534     ;Reg7配置射频 RX&TX, 要跳频使用,不在这里设置
535     
536     RETL    @0x6C
537     RETL    @0x90
538     RETL    @0x08        ;Reg8
539     
540     RETL    @0x48        ;此寄存器控制发射功率,对接收无影响
541     RETL    @0x00        ;最大功率:0x4800,其次是0x1840
542     RETL    @0x09        ;Reg9
543     
544     RETL    @0x7F
545     RETL    @0xFD
546     RETL    @0x0A        ;Reg10
547     
548     RETL    @0x00
549     RETL    @0x08
550     RETL    @0x0B        ;Reg11
551     
552     RETL    @0x00
553     RETL    @0x00
554     RETL    @0x0C        ;Reg12
555     
556     RETL    @0x48
557     RETL    @0xBD
558     RETL    @0x0D        ;Reg13
559     
560     RETL    @0x00
561     RETL    @0xFF
562     RETL    @0x16        ;Reg22
563     
564     RETL    @0x80
565     RETL    @0x05
566     RETL    @0x17        ;Reg23
567     
568     RETL    @0x00
569     RETL    @0x67
570     RETL    @0x18        ;Reg24
571     
572     RETL    @0x16
573     RETL    @0x59
574     RETL    @0x19        ;Reg25
575     
576     RETL    @0x19
577     RETL    @0xE0
578     RETL    @0x1A        ;Reg26
579     
580     RETL    @0x13
581     RETL    @0x00
582     RETL    @0x1B        ;Reg27
583     
584     RETL    @0x18
585     RETL    @0x00
586     RETL    @0x1C        ;Reg28
587     
588     RETL    @0x10
589     RETL    @0x00
590     RETL    @0x2C        ;Reg44
591     
592     RETL    @0x05
593     RETL    @0x52
594     RETL    @0x2D        ;Reg45
595     
596     ;[0] Reg50 是 FIFO 入口
597     ;[1] 发射端要发射数据,MCU要把该需要发射的数据从这里送入 FIFO(队列)
598     ;[2] 接收段要接收数据,MCU需要从这里读取 FIFO
599     
600     ;[0] Reg52, 该寄存器高 8bit 是FIFO写指针相关,低 8bit 是读指针相关
601     ;[1] 写指针:Bit[13:8]
602     ;[2] Bit15: 在 bit15 写入 1 ,写指针(bit[13:8])被清零,但不清空 TX FIFO 中的数据
603     ;[3] 读指针:Bit[5:0]
604     ;[4] Bit8: 在 bit8 写入 1 ,读指针(bit[5:0])被清零,但不清空 RX FIFO 中的数据
605     
606 
607 
608 
609 
610 
611                     ENDM
View Code

 

posted @ 2019-03-27 09:53  黑洞寻光  阅读(389)  评论(0)    收藏  举报