📄 shxj1.asm
字号:
;名称:
;日期:2006年7月10日
;编写:李洪佳
;芯片:CYGNAL C8051F021
;语言:汇编
;单片机用CYGNAL的C8051F021,调试用新华龙C8051F020开发板
;上位机发送控制命令给单片机,控制摄像机聚焦变倍,无命令时单片机向上位机传送深度数据
;UART0及UART1波特率设定为9600,波特率发生器为T2与T4,上位机发送每个命令的时间间隔为500毫秒
;单片机用UART0通过RS485与上位机通信,用UART1与摄像机通信实现对摄像机的控制
;---------------------------------------------------------------------------
;波特率=9600
;设定对摄像机控制的命令分别为:变倍-放大为“#,Z,+,CR,LF”,缩小为“#,Z,-,CR,LF”;聚焦-拉近为“#,F,+,CR,LF”,推远为“#,F,-,CR,LF”。
; * * * * *
;------------------------------------------------------------* 头文件*--------------------------------------------------------------------
; * * * * *
$include (c8051f020.inc) ; Include register definition file.定义寄存器
; ----------------
;----------------------------------------------------------)定义接收存储区(------------------------------------------------------------------
; ----------------
CTX485 BIT P3.7
DEEP_ADJ1 EQU 20H ;深度调整数据区
DEEP_ADJ2 EQU 21H
CTRL1 EQU 50H ;设定接收命令控制存储区1
CTRL2 EQU 51H ;设定接收命令控制存储区2
CTRL3 EQU 52H ;设定接收命令控制存储区3
CTRL4 EQU 53H ;设定接收命令控制存储区4
CTRL5 EQU 54H ;设定接收命令控制存储区5
DEEP_BUF0 EQU 55H ;深度数据缓存
DEEP_BUF1 EQU 56H
DEEP_BUF2 EQU 57H
DEEP_BUF3 EQU 58H
DEEP_BUF4 EQU 59H
DEEP_BUF5 EQU 5AH
DEEP_BUF6 EQU 5BH
DEEP_BUF7 EQU 5CH
PAGE_ADR1 EQU 5DH ;深度调整存储页
PAGE_ADR2 EQU 5EH
REC_COUNT EQU 5FH ;接收数据计数器
; ^^^VV^^^
;----------------------------------------------------------(中断向量)---------------------------------------------
ORG 0000H
LJMP START
ORG 0023H
LJMP DETERMINE
;---------------------------------------------------------iii禁止看门狗iii--------------------------------------------
; ^^^^^^^^^^^^^^^^
ORG 1000H
START: MOV WDTCN, #0DEH ;
MOV WDTCN, #0ADH ;禁止看门狗
MOV OSCXCN, #67H ;使用外部振荡22.1184MHz
; ~~~~~~~~~~~~~~~~~~
;------------------------------------------------------->等待外部时钟稳定<---------------------------------------------
; -_- -_-
CLR A ; wait at least 1ms
DJNZ ACC, $ ; wait ~512us
DJNZ ACC, $ ; wait ~512us
OSC_WAIT: ; poll for XTLVLD-->1
MOV A, OSCXCN
JNB ACC.7, OSC_WAIT
ORL OSCICN, #08H ; 选择外部振荡作为系统时钟源
ORL OSCXCN, #80H ; 使能时钟丢失检测
; **********
;------------------------------------------------------------*准备设置*----------------------------------------------------
; **********
MOV XBR2,#44H ;交叉开关允许,串口1允许
MOV XBR0,#04H ;使用串口0,TX0=P0.0,RX0=P0.1
MOV ADC0CN,#00H ;使能ADC0
MOV ADC0CF,#60H ;转换时钟1Mhz,增益1
MOV AMX0CF,#00H ;单端输入方式
MOV AMX0SL,#00H ;channel 0 即AIN0
MOV REF0CN,#03H ;ADC0 基准电压 VREF0
MOV EMI0CF,#00H ;片内存储方式
ORL P1MDIN,#0FFH ;设置P1数字输入方式
ORL P0MDOUT,#0F5H ;设置P0.0为推挽输出P0.1漏极输出P0.2推挽输出P0.3漏极输出
;ORL P1MDOUT,#40H ;设置P1.6为推挽输出(试验用)
ORL P3MDOUT,#0FFH ;P3为推挽输出
MOV SCON0,#50H ;设置串口0,工作方式1,REN0=1允许接收
MOV SCON1,#50H ;设置串口1,工作方式1,REN1=1允许接收
MOV RCAP2L,#0B8H ;设置定时器2波特率9600
MOV RCAP2H,#0FFH ;
MOV RCAP4L,#0B8H ;设置定时器4波特率9600
MOV RCAP4H,#0FFH ;
MOV T2CON,#34H ;启动定时器2作为串口uart0波特率发生器
MOV T4CON,#34H ;启动定时器4作为串口uart1波特率发生器
MOV PCON,#00H ;SMOD0=0波特率倍数为1,访问SCON的UART0方式设置位
MOV TCON,#00H
MOV REC_COUNT,#1 ;数据接收计数器初始值设定为1
MOV IE,#90H ;UART0中断使能
;-_-_-_-_-_-_-_-_-^_^-_-_-_-_-_-_------------------------------------------------------------------------------^_^
DATA_SEND: LCALL GETAD ;调用深度采集子程序
LCALL CONV ;调用码转换子程序
MOV IE,#90H ;ADC转换中断使ES0被硬件清零,此处重置UART0中断使能
CLR A ;清累加器
CLR TI ;清发送中断标志
MOV A,#24H ;发送$识别码
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF1 ;将深度数据第一位存入累加器
MOV SBUF0,A ;发送第一位深度数据
JNB TI,$
CLR TI
MOV A,DEEP_BUF2
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF3
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF4
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF5
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF6
MOV SBUF0,A
JNB TI,$
CLR TI
MOV A,DEEP_BUF7
MOV SBUF0,A ;发送第七位深度数据
CLR A
JNB TI,$
CLR TI
MOV R3,#10 ;延时89毫秒
DLOOP: LCALL DELAY ;调用延时子程序
DJNZ R3,DLOOP
LJMP DATA_SEND ;一组深度数据发送完成,返回发送下一组
;-----------------------------------------------------深度采集码段--------------------------------------------------------
GETAD: MOV R3,#10H ;1US;---------------------A/D CONVERTION SUB_PROGRAM,GET DEPTH DATA FROM A/D
MOV R5,#0H ;1US
MOV R6,#0H ;1US
MOV DEEP_BUF6,#00H
MOV DEEP_BUF7,#00H
CLR C
GETAD1: SETB AD0EN ;使能ADC0
LCALL GETADS ;2US call one AD convertion
MOV A,DEEP_BUF6
ADD A,R5 ;1US
MOV R5,A ;1US
MOV A,DEEP_BUF7 ;1US
ADDC A,R6 ;1US overflow carry
MOV R6,A ;1US
DJNZ R3,GETAD1 ;sampling 16 times and sum(quite to shift to left 4 bits),2US
CLR AD0EN
MOV A,R5 ;1US,sum 25US deal with low 8 bits
ANL A,#0F0H ;1US reserve the high half byte
SWAP A ;1US high half byte swap to low half byte
MOV R5,A ;1US
MOV A,R6 ;1US deal with high 8 bits
ANL A,#0FH ;1US
SWAP A ;1US
ORL A,R5 ;1US combinate into low 8 bits
MOV R5,A ;1US
MOV A,R6 ;1US
SWAP A ;1US
ANL A,#0FH ;1US
MOV R6,A ;calculate the average(quite to shift to right 4 bits),1US
CLR C ;1US
;----------------------------------------subtract AIR DEEP DATA -----------------------------------------------
;----------------------------------------------------------------------------------------------------------------
LCALL DAR
MOV A,R5 ;1US
SUBB A,DEEP_ADJ2 ;1US
MOV R5,A ;1US
MOV A,R6 ;1US
SUBB A,DEEP_ADJ1 ;1US
MOV R6,A ;1US
JNC GETAD2 ;2US
MOV R5,#00 ;1US the carry bit is a 1?if less than 400mV ,depth=00
MOV R6,#00 ;1US
SJMP GETAD6 ;2US
GETAD2: MOV DEEP_BUF6,R5 ;2US
MOV DEEP_BUF7,R6 ;2US
MOV R3,#8 ;1US
CLR C
GETAD3: MOV A,R5 ;1US,sum 120US
ADD A,DEEP_BUF6 ;1US
MOV R5,A ;1US
MOV A,R6 ;1US
ADDC A,DEEP_BUF7 ;1US
MOV R6,A ;1US
DJNZ R3,GETAD3 ;multiply 9,add 9 time,2US
MOV A,R5 ;1US,sum 19US
ANL A,#0F0H ;1US
SWAP A ;1US
MOV R5,A ;1US
MOV A,R6 ;1US
ANL A,#0FH ;1US
SWAP A ;1US
ORL A,R5 ;1US
MOV R5,A ;1US
MOV A,R6 ;1US
SWAP A ;1US
ANL A,#0FH ;1US00
MOV R6,A ;divide 16,1US(multiply 9/16,0.5625,exchange to mV,actually to decimeter(0.1m))
GETAD6: MOV DEEP_BUF6,R5 ;2US
MOV DEEP_BUF7,R6 ;2US
RET ;2US
;------------------------------------------------------- one AD conversion--------------------------------------------------
GETADS: CLR AD0EN ;关断ADC0,停止采集
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -