最近也在學習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;
}
}