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

📄 cdc_fw_v13_asm.asm

📁 一个利用51单片机实现对的简易功能的控制cd-rom的程序
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;*                           CD-ROM控制器  Firmware                        *
;***************************************************************************
;*  标题:CD-ROM控制器  firmware         版本:V1.3                          *
;*  更新日期:2004.09.14        10:30AM                                     *
;*  程序编写: 吴巍(创梦电子工作室)                                         *
;*  E-mail:cdream5@163.com                                                 *
;*  网址: Http://www.cdream5.com                                           *
;*  说明:用89C52控制光驱读音频CD(光驱改成CD机)                             *
;***************************************************************************
;*注:单片机89C52/S51   晶振12Mhz                                           *
;***************************************************************************
;*1.增加音量控制功能
;*2.修改一些显示问题
;*声明:本程序仅供个人研究学习
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



ORG 0000H
AJMP boot
ORG 00013H ;外部中断P3.3脚INT1入口地址 
AJMP INT 

ORG 030H
boot:
CODE_BASE EQU 0031h
STACK_START EQU 85h  

;ctrl bus
DA0 bit p2.5
DA1 bit p2.6
DA2 bit P2.7

;ctrl
ATA_nDIOR       bit   p3.7 ;read strobe
ATA_nDIOW       bit   p3.6 ;write strobe
ATA_nRESET      bit   p3.2
ATA_INTRQ       bit   p3.5 ;irq

;data bus
ATA_DATA_LS     data  p0
ATA_DATA_MS     data  p1

;ir_control_code
ir_code data 5bH

;display ctrl

DISP_E  bit p3.4           ;显示控制
RSPIN   EQU     P2.7
RWPIN   EQU     P3.0
EPIN    EQU     P3.1

;display data bus
LED_W  data p1  ;  数码管 位
LED_D  data p0  ;  数码管 笔划
LCM_D  data P0  ;  LCM BUS

;Key
play_key   bit p2.0
pause_key  bit p2.1
pre_key    bit p2.2
next_key   bit p2.3
stop_key   bit p2.4

packet_size     data  08h
start_track     data  09h
end_track       data  69h
tmp0            data  0ah
tmp1            data  0bh
tmp2            data  0ch
tmp3            data  0dh
start_M         data  0eh
start_S         data  0fh
start_F         data  10h
end_M           data  11h
end_S           data  12h
end_F           data  13h
audio_status    data  14h
current_track   data  60h
current_M       data  61h 
current_S       data  62h
current_F       data  63h
next_track      data  64h
media_type      data  67h 
volume_1        data  42h
volume_2        data  43h
sense_code      data  45h
show_all        data  46h

aba_t           data  16h
abb_m           data  18h
abb_s           data  19h

Err_cd_code     data  15h
toc_times       data  54h        
pause_da        data  53h
pause_db        data  52h

ir_temp data 50h
ir_key data 58h
ir_num data 51h 
driver_status data 59h                          

play_mode  data 4ch
track_a data 4fh              ;循环开始结束曲
track_b data 4dh            

a_bit data 65h
b_bit data 66h
DM_code data 68h

d_track data 6ah
d_s  data 6ch
d_m  data 6dh

n_s  data 6eh
n_m  data 6fh

E_M  data 57h             ;要显示用得M S T
E_s  data 56h
E_t  data 55h 



packet_tab      idata 70h
packet_cmd      data  70h
packet_1        data  71h
packet_2        data  72h
packet_3        data  73h
packet_4        data  74h
packet_5        data  75h
packet_6        data  76h
packet_7        data  77h
packet_8        data  78h
packet_9        data  79h
packet_10       data  7ah
packet_11       data  7bh
packet_12       data  7ch
packet_13       data  7dh
packet_14       data  7eh
packet_15       data  7fh

org CODE_BASE
 clr EA
 ;SETB EA ;打开CPU总中断请求
 clr ex0 ;关掉其他中断
 clr et1
 clr es
 clr et0
 SETB IT1 ;设定INT1的触发方式为脉冲负边沿触发
 SETB EX1 ;打开INT1中断请求 (红外线输入)
 mov ir_code,#0ffh
 SETB EA ;打开CPU总中断请求
 ljmp  start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;红外线控制程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INT: 
  CLR EA         ;暂时关闭CPU的所有中断请求
  ;call disp_o
  MOV R6,#10
SB:  
  SJMP YS0       ;转到882微秒延时判断子程序
 SBB:            ;延时882微秒中判断P3.3脚是否出现高电平如果有就退出解码程序
  DJNZ R6, SB    ;重复'R6次,目的是检测在8820微秒内如果出现高电平就退出解码程序
                 ;以上完成对遥控信号的9000微秒的初始低电平信号的识别。
  JNB P3.3, $    ;等待高电平避开9毫秒低电平引导脉冲
  ACALL YS2      ;延时4.74毫秒避开4.5毫秒的结果码
  MOV R1,#5CH    ;设定1AH为起始RAM区
  MOV R2,#4 
 PP: 
  MOV R3,#8
  JJJJ: 
  JNB P3.3,$     ;等待地址码第一位的高电平信号
  call YS1      ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
  MOV C,P3.3     ;将P3.3引脚此时的电平状态0或1存入C中
  JNC UUU        ;如果为0就跳转到UUU
  call YS3
UUU: 
   MOV A,@R1     ;将R1中地址的给A
   RRC A         ;将C中的值0或1移入A中的最低位
   MOV @R1,A     ;将A中的数暂时存放在R1中
   DJNZ R3,JJJJ  ;接收地址码的高8位
   INC R1        ;对R1中的值加1,换下一个RAM
   DJNZ R2,PP    ;接收完16位地址码和8位数据码和8位数据反码,存放在5CH/5DH/5EH/5FH的RAM中
   mov a,5eh
   CPL A         ;对1AH取反后和1BH比较
   CJNE A,5fH,EXIT      ;如果不等表示接收数据发生错误,放弃
   cjne a,#0FFh,ir_rec  ;跳开#0FFh,如果按时间长,解出的码是#0FFh
   sjmp Exit
  ir_rec:
   ;mov ir_code,5fh
   ;call disp_o
   call ir_key_code
EXIT: 
   SETB EA ;允许中断
   RETI ;退出解码子程序

YS0:
  MOV R4,#220
 irD0:
   JB P3.3,EXIT
   DJNZ R4,irD0
   SJMP SBB 
 
YS1: 
  MOV R4,#20 ;延时子程序1,精确延时882微秒
 irD1: 
  MOV R5,#20
  DJNZ R5,$
  DJNZ R4,irD1 
  RET
YS2: 
  MOV R4,#10 ;延时子程序2,精确延时4740微秒 
 irD2:
  MOV R5,#235
  DJNZ R5,$
  DJNZ R4,irD2 
  RET
YS3: 
  MOV R4,#2;延时程序3,精确延时1000微秒
 irD3:
  MOV R5,#248
  DJNZ R5,$
  DJNZ R4,irD3
  RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;不同的遥控器键值修改此处
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IR_key_code:
  mov a,5dh               ;判断遥控器种类
  ;cjne a,#69h,irkc2
  ;ljmp IR_key_code_69
 ;irkc2:
 ;cjne a,#0cfh,irkc3
 ;ljmp IR_key_code_cf
 irkc3:
  cjne a,#0ffh,irkc4
  ljmp IR_key_code_ff
 irkc4:
 irkc5:
 irkc6: 
  ljmp ir_kcret
IR_key_code_ff:                   
  mov a,5fh                 ;定义键值,将接收到红外线原码定义成具体的红外键值,
  
  cjne a,#0f6h,ir_confff2
  mov ir_key,#01h          ;1             将F6的红外码定义为 1 按键 键值为 #01H
  ljmp ir_kcret
 ir_confff2:
  cjne a,#0e2h,ir_confff3 
  mov ir_key,#02h          ;2             将E2的红外码定义为 2 按键
  ljmp ir_kcret
 ir_confff3:
  cjne a,#0e0h,ir_confff4
  mov ir_key,#03h          ;3
  ljmp ir_kcret
 ir_confff4:
  cjne a,#0f2h,ir_confff5 
  mov ir_key,#04h          ;4
  ljmp ir_kcret
 ir_confff5:
  cjne a,#0e6h,ir_confff6 
  mov ir_key,#05h          ;5
  ljmp ir_kcret
 ir_confff6:
  cjne a,#0e4h,ir_confff7 
  mov ir_key,#06h          ;6
  ljmp ir_kcret
 ir_confff7:
  cjne a,#0eeh,ir_confff8 
  mov ir_key,#07h          ;7
  ljmp ir_kcret
 ir_confff8:
  cjne a,#0eah,ir_confff9 
  mov ir_key,#08h          ;8
  ljmp ir_kcret
 ir_confff9:
  cjne a,#0e8h,ir_confff10 
  mov ir_key,#09h          ;9
  ljmp ir_kcret
 ir_confff10:
  cjne a,#0edh,ir_confff11 
  mov ir_key,#0ah          ;0
  ljmp ir_kcret
 ir_confff11:
  cjne a,#0aeh,ir_confff12  
  mov ir_key,#0bh          ;play/stop       将AE的红外码定义为 play/stop 按键,键值为#0Bh
  ljmp ir_kcret
 ir_confff12:
  cjne a,#0ech,ir_confff13  
  mov ir_key,#0ch          ;pause/resume    
  ljmp ir_kcret
 ir_confff13:
  cjne a,#0e1h,ir_confff14  
  mov ir_key,#0dh          ;forward          将E1的红外码定义为 forward 按键,键值为#0Dh
  ljmp ir_kcret
 ir_confff14:
  cjne a,#0f5h,ir_confff15  
  mov ir_key,#0eh          ;backward
  ljmp ir_kcret
 ir_confff15:
  cjne a,#0e5h,ir_confff16  
  mov ir_key,#0fh          ;next
  ljmp ir_kcret
 ir_confff16:
  cjne a,#0f1h,ir_confff17  
  mov ir_key,#010h         ;previous
  ljmp ir_kcret
 ir_confff17:
  cjne a,#0AFh,ir_confff18  
  mov ir_key,#11h          ;mode
  ljmp ir_kcret
 ir_confff18:
  cjne a,#0F8h,ir_confff19  
  mov ir_key,#12h          ;Enter
  ljmp ir_kcret
 ir_confff19:
  cjne a,#0b7h,ir_confff20  
  mov ir_key,#13h          ;setup
  ljmp ir_kcret
 ir_confff20:
  cjne a,#0b6h,ir_confff21  
  mov ir_key,#14h          ;programe
  ljmp ir_kcret
 ir_confff21:
  cjne a,#0ebh,ir_confff22 
  mov ir_key,#15h          ;Clr
  ljmp ir_kcret
 ir_confff22:
  cjne a,#0ADh,ir_confff23  
  mov ir_key,#16h          ;A-B
  ljmp ir_kcret
 ir_confff23:
  cjne a,#0aah,ir_confff24  
  mov ir_key,#17h          ;repeat
  ljmp ir_kcret
 ir_confff24:
  cjne a,#0efh,ir_confff25 
  mov ir_key,#18h          ;eject
  ljmp ir_kcret
 ir_confff25:
   cjne a,#0fch,ir_confff26 
   mov ir_key,#19h          ;volume+
   ljmp ir_kcret
 ir_confff26:
   cjne a,#0fdh,ir_confff27 
   mov ir_key,#1ah          ;volume-
   ljmp ir_kcret
 ir_confff27:
   mov ir_key,#0ffh
   ljmp ir_kcret  
 ir_kcret:

  ret
  
  
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;CD-ROM控制指令源代码;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; atomic routines
;
; Nb/ code assumes 1us clock cycle (12Mhz xtal clock)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

delay_100000us:
  mov   r7,#0c8h
delay_100000us_l0:
  mov   r6,#0f8h
delay_100000us_l1:
  djnz  r6,delay_100000us_l1
  nop
  djnz  r7,delay_100000us_l0
  ret
  
delay_10ms:
  mov   r7,#100
delay_10ms_l0:
  mov   r6,#100
delay_10ms_l1:
  djnz  r6,delay_10ms_l1
  nop
  djnz  r7,delay_10ms_l0
  ret  

;r5 = seconds
delay:
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  call delay_100000us
  djnz  r5,delay
  ret

read_cycle:
  mov   ATA_DATA_LS,#0ffh
  mov   ATA_DATA_MS,#0ffh
  clr   ATA_nDIOR
  mov   a,ATA_DATA_LS
  mov   b,ATA_DATA_MS
  setb  ATA_nDIOR
  ret

read_cycle_ls:
  mov   ATA_DATA_LS,#0ffh
  clr   ATA_nDIOR
  mov   a,ATA_DATA_LS
  setb  ATA_nDIOR
  ret

write_cycle:
  mov   ATA_DATA_LS,a
  mov   ATA_DATA_MS,b
  clr   ATA_nDIOW
  nop
  setb  ATA_nDIOW
  ret

write_cycle_ls:
  mov   ATA_DATA_LS,a
  clr   ATA_nDIOW
  nop
  setb  ATA_nDIOW
  ret

wait_irq:
  ;setb  ATA_INTRQ
  jnb   ATA_INTRQ,wait_irq
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; cylinder register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_cyl_high_register:
;mov   ATA_ADDR,#10110000b
  setb DA2
  CLR  DA1
  SETB DA0  
  call read_cycle_ls
  ret

get_cyl_low_register:
;  mov   ATA_ADDR,#10010000b
  setb DA2
  CLR  DA1
  CLR  DA0 
  call read_cycle_ls
  ret

set_cyl_high_register:
;  mov   ATA_ADDR,#10110000b
  setb DA2
  CLR  DA1
  SETB DA0 
  call write_cycle_ls
  ret

set_cyl_low_register:
;mov   ATA_ADDR,#10010000b
  setb DA2
  CLR  DA1
  CLR  DA0
  call write_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; a = cmd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set_cmd_register:
;  mov   ATA_ADDR,#11110000b
  setb DA2
  SETB DA1
  SETB DA0
  call write_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; ret: a = ls  b = ms
get_data:
;  mov   ATA_ADDR,#00010000b
  CLR  DA2
  CLR  DA1
  CLR  DA0
  call read_cycle
  ret

; a = ls  b = ms
set_data:
;  mov   ATA_ADDR,#00010000b
  CLR  DA2
  CLR  DA1
  CLR  DA0
  call write_cycle
  ret

; a = ls
set_data_ls:
;  mov   ATA_ADDR,#00010000b
  CLR  DA2
  CLR  DA1
  CLR  DA0
  call write_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; device/head register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_devhead_register:
;  mov   ATA_ADDR,#11010000b
  setb  DA2
  SETB  DA1
  CLR   DA0
  call read_cycle_ls
  ret

set_devhead_register:
;  mov   ATA_ADDR,#11010000b
  setb  DA2
  SETB  DA1
  CLR   DA0
  call write_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; error register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ERROR_REG_AMNF  bit acc.0
ERROR_REG_TK0NF bit acc.1
ERROR_REG_ABRT  bit acc.2
ERROR_REG_MCR   bit acc.3
ERROR_REG_IDNF  bit acc.4
ERROR_REG_MC    bit acc.5
ERROR_REG_UNC   bit acc.6
ERROR_REG_RES   bit acc.7

get_error_register:
;  mov   ATA_ADDR,#00110000b
  CLR  DA2
  CLR  DA1
  SETB DA0
  call read_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sector register's
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_sector_c_register:
;  mov   ATA_ADDR,#01010000b
  CLR   DA2
  SETB  DA1
  CLR   DA0
  call read_cycle_ls
  ret

get_sector_n_register:
;  mov   ATA_ADDR,#01110000b
  CLR   DA2
  SETB  DA1
  SETB  DA0
  call read_cycle_ls
  ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; status register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STATUS_REG_ERR  bit acc.0
STATUS_REG_IDX  bit acc.1
STATUS_REG_CORR bit acc.2
STATUS_REG_DRQ  bit acc.3
STATUS_REG_DSC  bit acc.4
STATUS_REG_DF   bit acc.5
STATUS_REG_DRDY bit acc.6
STATUS_REG_BSY  bit acc.7

get_status_register:
;  mov   ATA_ADDR,#11110000b
  setb  DA2
  SETB  DA1
  setb  DA0
  call read_cycle_ls
  ret

bsy_wait:
  nop
  nop
  nop
  nop
  call get_status_register
  jb    STATUS_REG_BSY,bsy_wait
  ret

⌨️ 快捷键说明

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