最近也在学习ucos,之前没注意,在gui和串口通信上卡了很长时间,我的通信估计是1s钟一次,一次20个字符。之前通信的时候,触摸很卡,没法用的。于是想到把触摸中断,和串口中断改成汇编,但发送数据还是有点不科学的地方。偶然看到一本书中提到,串口通信在ucos中需要都使用汇编中断。现在没问题了,下面随便贴一下,各位多提意见。
1、触摸屏中断
段名以及部分跳转使用红色标出,由于启用x,y同时转换,总是会有点问题,所以选择了单独转换。
IMPORT newAD2XY
TouchISR
STMDB sp!,{r0-r12,lr}
;interrupt disable(not nessary)
mrs r0, CPSR
orr r0, r0, #0x80 ; and set IRQ disable flag
msr CPSR_cxsf, r0
LDR r0, =INTSUBMSK
LDR r1, [r0]
ORR r1,r1,#BIT_SUB_TC
STR r1, [r0]
BL IrqStart
LDR r0,=ADCTSC
LDR r1,[r0]
TST r1,#0x100
LDRNE pc ,=MYTOUCHOUT
LDR r1,=((0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(1))
STR r1,[r0]
LDR r0,=ADCDLY
LDR r6,[r0] ;r1 save adcdly
LDR r2,=1000
STR r2,[r0]
LDR r4,=0x0
LDR r5,=0x0
LDR r1,=16 ;loop to get x,y
LoopGetx
BL waitCON
LDR r0,=0x3ff
LDR r3,=ADCDAT0
LDR r3,[r3]
AND r3,r3,r0
ADD r4,r4,r3 ;x
SUBS r1,r1,#0x1
BNE LoopGetx
LDR r0,=ADCTSC
LDR r1,=((0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(2))
STR r1,[r0]
LDR r1,=16 ;loop to get x,y
LoopGety
BL waitCON
LDR r0,=0x3ff
LDR r3,=ADCDAT1
LDR r3,[r3]
AND r3,r3,r0
ADD r5 ,r5,r3 ;y
SUBS r1,r1,#0x1
BNE LoopGety
MOV r0,r4,LSR #4 ;LSR r1,r4,#4 ; x,y SW so r4,y
MOV r1,r5,LSR #4 ;LSR r0,r5,#4 ; x,y SW so r5,x
BL newAD2XY
LDR r0,=ADCDLY
STR r6,[r0]
LDR r0,=ADCTSC
LDR r1,=0x0d3
STR r1,[r0]
MYTOUCHOUT
LDR r0, =SUBSRCPND
LDR r1,[r0]
ORR r1,r1,#BIT_SUB_TC
STR r1,[r0]
LDR r0, =INTSUBMSK
LDR r1,[r0]
BIC r1,r1,#BIT_SUB_TC
STR r1,[r0]
LDR r0,=RSRCPND
LDR r1,=BIT_ADC
STR r1,[r0]
LDR r0,=RINTPND
STR r1,[r0]
MYIRQOUT
BL IrqFinish ;a1= return value 0:not context switch, otherwise:context switch
CMP a1, #0
LDRNE pc, =_CON_SWAP
LDR pc, = _NOT_CON_SWAP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
waitCON
LDR r0,=ADCCON
LDR r2,[r0]
ORR r2,r2,#0x01
STR r2,[r0]
waitCHECK
LDR r2,[r0]
TST r2,#0x1
BEQ waitCHECK
waitEC
LDR r2,[r0]
TST r2, #0x8000
BEQ waitEC
LDR r0,=RSRCPND
waitOK
LDR r2,[r0]
TST r2, #BIT_ADC
BEQ waitOK
MOV pc,lr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;end of touch
其中 newAD2XY是定义的c函数,使用的是五点校验屏幕的函数。
2、串口中断
;;;;;;;;;;;;;;begin COM 485RX
RxInt
STMDB sp!,{r0-r12,lr}
;interrupt disable(not nessary)
mrs r0, CPSR
orr r0, r0, #0x80 ; and set IRQ disable flag
msr CPSR_cxsf, r0
;End of interrupt
BL IrqStart
LDR r0,=SUBSRCPND ;判断 TX or RX
LDR r1,[r0]
TST r1,#BIT_SUB_RXD1
BEQ TxInt
LDR r0,=URXH1
LDR r1,[r0]
BL COMGetData
LDR r0, =INTSUBMSK
LDR r1,[r0]
BIC r1,r1,#BIT_SUB_RXD1
STR r1,[r0]
LDR r0, =SUBSRCPND
LDR r1,[r0]
ORR r1,r1,#BIT_SUB_RXD1
STR r1,[r0]
LDR r0,=RSRCPND
LDR r1,=BIT_UART1
STR r1,[r0]
LDR r0,=RINTPND
STR r1,[r0]
BL MYIRQOUT
TxInt
;;;;;;;;;;;;;;begin COM 485TX
BL COMSendData
LDR r0, =INTSUBMSK
LDR r1,[r0]
ORR r1,r1,#BIT_SUB_TXD1
STR r1,[r0]
LDR r0, =SUBSRCPND
LDR r1,[r0]
BIC r1,r1,#BIT_SUB_TXD1
STR r1,[r0]
LDR r0,=RSRCPND
LDR r1,=BIT_UART1
STR r1,[r0]
LDR r0,=RINTPND
STR r1,[r0]
BL MYIRQOUT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;end of 485
其中发送中断的触发在任务中使用:
void COMMonitor(){//发送数据,不对劲
U8 err=0;
static bool bflag=FALSE;
if( !bflag ) bflag=TRUE;
else{
OSMboxPend(SendMsg,0,&err);
}
//启动发送中断
rSUBSRCPND &= (BIT_SUB_TXD1);
rINTSUBMSK &= ~(BIT_SUB_TXD1);
}
void COMGetData(U8 da ,U8 dat1){
static U8* tmp,*tmp1,tmp2=0;
U32 dely;
U16 ofall=0;
tmp =&RcvData[rcvi];
tmp1=&RcvBufData;
__asm{
STRB dat1,[tmp]
ADD rcvi,rcvi,#0x01
CMP rcvi,#20
BNE out
//在条件容许的情况下,转移数据
SUB tmp,tmp,#19
LDRB da,[tmp]
CMP da,#0xAA
BNE out//引导字不对,out
LDRB da,[tmp+1]
LDRB dat1,[tmp+2]
CMP da,dat1
BNE out //命令字不一样,out
CMP da,#0x1
BLS out
CMP da,#0x60
BHS out //不在接收范围 out
MOV da,#0 //计算校验和
addtmp:
LDRB dely,[tmp+da]
ADD ofall,ofall,dely
ADD da,da,#1
CMP da,#18
BNE addtmp
LDRB da,[tmp+18]
LDRB dat1,[tmp+19]
ADD dely,dat1,da,LSL #8
MOV rcvi,0x0
CMP ofall,dely
BNE out
lopcopy:
LDRB da,[tmp],#1
STRB da,[tmp1],#1
ADD rcvi,rcvi,#1
CMP rcvi,#20
BNE lopcopy
MOV tmp2,0x1
MOV rcvi,0x0
out:
}
if(tmp2){
OSMboxPost(SendMsg,(void*)1);
tmp2=0;
}
}