今天又解决了一项难题,这是一个用INT0接收MIDI串行码的程序,想法是这样的,开启INT0等候MIDI讯号,当起始BIT到来时,关闭INT0,写个定时时间为16US(一个MIDI BIT是32US)的值(TML—SHORT)入T0, 开启T0中断,开动T0,预计会在一个BIT的中点产生中断,接下来就写入定时时间为32us的值(TML)入T0,这样就能连续读到每个BIT中点的值,直到读完8个BIT,最后一个是停止BIT,无所谓,把读到的1byte写入缓冲就完成一对一个MIDI讯号的读取,实验结果是可行的,但是好好的键盘弹着弹着就会出现怪音,乱码。当然就开始怀疑硬件出问题了,连最名牌的音源发生器也怀疑是否有BUG,今天终于想出个办法,就是用逻辑分析仪观测输入的MIDI讯号,在软件内部加入setb p2.0, cpl p2.0 的命令,比较二者的时序,这才发现原来INT0 并非想象讯号来的时候马上就触发,而会延时6-7US(3.6M晶振),加上16US就是23US,已经接近一个BIT的尾端,若偶尔BIT有些延时就会读到BIT外的数值了,这就是乱码的由来,把16US 减为10US后,哈!神助啊,乱弹一万个键也不会错了,高兴之余,就把这波形和原码上载分享,庆祝一条大虫伏诛了。
但还在纳闷为何这名牌键盘产生的MIDI码也是时长时短的,没有规则,不可能吧?又怀疑是用廉价的24M逻辑分析仪了,但问题也算解决了,单片机的INT0是会有延时的,记住了。
单片机汇编语言源程序如下:
EXT_INT0: ;IF P3.2 H2L COME HERE SET TIMER, ONLY FIRST H2L WILL ACT
SETB P2.0
CLR EX0 ;STOP THE INTERRUPT_O
MOV TH0,#TMH ;load value to T0 high 8 bits a value
MOV TL0,#TML_SHORT ;load half value to T0 low 8 bits a value
;SETB PT0 ;set T0 interupt parity HIGH
SETB ET0 ;switch on T0 interrupt
SETB TR0 ;SWITCH ON T0 to run
;NOP
MOV R6,#8 ;9 BIT TO CHECK
RETI
TIMER_0: ;CHECK INPUT MIDI SIGNAL AT P3.2
CPL P2.0
PUSH ACC
JB 11H, STOPREADBIT
JB 10H, STARTREADBIT
SETB 10H
MOV R5, #00000000B ;FIRST BIT
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
JMP NEXTBIT
STARTREADBIT:
MOV A, P3 ;READ FROM PORT3
ANL A, #00000100B ;MASKING ALL EXCEPT P3.2 BIT
JNZ SETTOHIGH
CLR C
JMP CLOCKIN
SETTOHIGH:
SETB C
CLOCKIN:
MOV A, R5
RRC A
MOV R5, A
DEC R6
MOV A, R6
JNZ NEXTBIT
SETB 11H ;STOP BIT
JMP NEXTBIT
STOPREADBIT:
CLR 10H
CLR 11H
MOV A, R5 ;LOAD A WITH RECEIVED DATA BYTE
MOV @R1, A ;SAVE TO BUFFER
CLR TR0 ;STOP THE TIMER_0
SETB PX0 ;SET EXTERNAL INTERRUT PARITY TO HIGH
CLR IE0 ;CLEAR EXTERNAL INTERRUT FLAG
SETB IT0 ;SET AS H TO L AS INTERRUT METHOD
SETB EX0 ;REOPEN EXTERNAL INTERRUPT 0
CJNE R1, #LASTBUFFER, NEXTREADBUFFER
MOV R1, #FIRSTBUFFER
JMP NEXTBIT1
NEXTREADBUFFER:
INC R1 ;POINT TO NEXT BUFFER
CLR P2.0
JMP NEXTBIT1
NEXTBIT:
NOP
NOP
NOP
NOP
NOP
NOP
MOV TH0,#TMH ;load value to T0 high 8 bits a value
MOV TL0,#TML ;load value to T0 low 8 bits a value
NEXTBIT1:
POP ACC
RETI
EXT_INT1: ;USE FOR INFRA RED
CLR EX0 ;STOP MIDI
CLR EX1 ;STOP THE INTERRUPT_1
LCALL INFRARED
RETI
|