ARM汇编STM32F103VE串口中断发送接收

//本文档是在STM32103VE中实现串口中断接收和中断发送数据,将采用循环边收边发将串口接收到的数据实时发送出去。
//串口接收发送代码用汇编编写。
//本软件测试在波特率115200通过串口软件从上位机发送6000字节的文档,单片机接收后将数据发送回上位机。


u8 recevie_num;
u8 recevie_send_data[200];

void USART_INIT(void);
void USART_SEND_DATA(u8* pp, u8 datalen);
void USART_RECEVIE_DATA(u8 *pp, u8 datalen);
u8 USART_GET_RECEVIE_LEN(void);

int main(void)
{
Stm32_Clock_Inint(); //*****初始化时钟
USART_INIT(); //*****串口初始化

while(1)
{
recevie_num = USART_GET_RECEVIE_LEN(); //接收到的数据个数
if(recevie_num != 0)//是否有数据需要发送
{
USART_RECEVIE_DATA(&recevie_send_data[0], recevie_num); //读取接收到的数据
USART_SEND_DATA(&recevie_send_data[0], recevie_num); //发送接收的数据
}
}
}





IMPORT MY_NVIC_Init

MAX_BUF_NUM EQU 200 ;数组最大接收发送值

PRESERVE8 ;堆栈对齐

AREA USART_DATA, DATA, READWRITE
BUF_RECEVIE SPACE MAX_BUF_NUM ;接收缓存
RECEVIE_CNT DCB 0 ;接收串口数据到数组的指针
RECEVIE_GET_CT DCB 0 ;接收到的数据个数
RECEVIE_DATA_CT DCB 0 ;读取数组数据的指针

BUF_SEND SPACE MAX_BUF_NUM ;发送缓存
SEND_CNT DCB 0 ;发送数组数据到串口的指针
SEND_SEND_CT DCB 0 ;要发送的数据个数
SEND_DATA_CT DCB 0 ;将要发送的数据装载到发送数组的指针

AREA USART_PRO, CODE, READONLY
;;;;;;;串口初始化;;;;;;
USART_INIT
EXPORT USART_INIT [WEAK]
PUSH {R0-R8, LR}

;开串口1时钟
LDR R0, =RCC_APB2ENR
LDR R1, [R0]
ORR R1, #Bit14
ORR R1, #Bit2
STR R1, [R0]

;配置串口管脚
LDR R0, =GPIOA_CRH
LDR R1, [R0]
AND R1, #0XFFFFF00F
ORR R1, #0X000008B0
STR R1, [R0]

;复位USART1,先置位 再清零
LDR R0, =RCC_APB2RSTR
LDR R1, [R0]
ORR R1, #Bit14
STR R1, [R0]
LDR R1, [R0]
BIC R1, #Bit14
STR R1, [R0]

;设置成9600波特率
LDR R0, =USART1_BRR
;MOV R1, #0X1D4C ;9600
MOV R1, #0X271 ;115200
;MOV R1, #0X3A98 ;4800
STR R1, [R0]

;USART1使能 发送使能 接收使能
;8位数据位 无校验
LDR R0, =USART1_CR1
LDR R1, =0X200C
STR R1, [R0]

;开启中断,开启数据接收中断
LDR R0, =USART1_CR1
LDR R1, [R0]
ORR R1, #0X0120
STR R1, [R0]

;中断分组,设置中断优先级,开启串口总中断
MOV R0, #0
MOV R1, #1
LDR R2, =USART1_IRQChannel
MOV R3, #2
BL MY_NVIC_Init

POP {R0-R8, PC}


;;;;;得到串口接收到的数据个数;;;;;
USART_GET_RECEVIE_LEN
EXPORT USART_GET_RECEVIE_LEN
PUSH {R1-R8, LR}
LDR R1, =RECEVIE_GET_CT ;接收

到的数据个数
LDRB R0, [R1]
POP {R1-R8, PC}


;;;;;从接收数组读取数据;;;;;
;void USART_RECEVIE_DATA(u8 *pp, u8 datalen);
USART_RECEVIE_DATA
EXPORT USART_RECEVIE_DATA
PUSH {R0-R8, LR}

MOV R6, #0
LOOP2
CPSID I ;由于RECEVIE_GET_CT变量在接收中断里面也用所以要先关闭中断不然变量值会不同步
LDR R5, =RECEVIE_GET_CT ;接收数组的数据个数
LDRB R2, [R5]
CMP R2, #0
BEQ DATA_ENPTY
SUB R2, #1
STRB R2, [R5]
CPSIE I

LDR R5, =RECEVIE_DATA_CT ;得到接收数组数据指针
LDRB R2, [R5]

LDR R3, =BUF_RECEVIE ;将数据从接收数组拷贝到目标地址
LDRB R4, [R3, R2]
STRB R4, [R0, R6]

ADD R2, #1 ;接收数组数据指针加1
CMP R2, #MAX_BUF_NUM
MOVEQ R2, #0
STRB R2, [R5]

ADD R6, #1
CMP R6, R1
BNE LOOP2
DATA_ENPTY
POP {R0-R8, PC}

;;;;;将要发送的数据装载到发送数组;;;;;
;void USART_SEND_DATA(u8* pp, u8 datalen);
USART_SEND_DATA
EXPORT USART_SEND_DATA
PUSH {R0-R8, LR}

MOV R6, #0
LOOP1
CPSID I ;由于SEND_SEND_CT变量在发送中断里面也用所以要先关闭中断不然变量值会不同步
LDR R2, =SEND_SEND_CT ;要发送数据的个数
LDRB R3, [R2]
CMP R3, #MAX_BUF_NUM
BEQ USART_SEND_FULL
ADD R3, #1
STRB R3, [R2]
CPSIE I

LDR R3, =SEND_DATA_CT ;得到发送数据数组指针
LDRB R5, [R3]

LDR R2, =BUF_SEND ;将要发送的数据装载到发送数组
LDRB R4, [R0, R6]
STRB R4, [R2, R5]

ADD R5, #1 ;发送数据数组指针加1
CMP R5, #MAX_BUF_NUM
MOVEQ R5, #0
STRB R5, [R3]

ADD R6, #1
CMP R6, R1 ;数据装载完成?
BNE LOOP1

LDR R0, =USART1_CR1 ;开发送中断
LDR R1, [R0]
ORR R1, #0X80
STR R1, [R0]
POP {R0-R8, PC}
USART_SEND_FULL ;发送满
POP {R0-R8, PC}

;;;;;从串口接收数据;;;;;;
USART_RECEVIE
EXPORT USART_RECEVIE
PUSH {R0-R8, LR}
LDR R0, =USART1_DR

LDR R1, =RECEVIE_GET_CT ;接收到的数据个数
LDRB R2, [R1]
CMP R2, #MAX_BUF_NUM
BEQ RECEVIE_FULL
ADD R2, #1
STRB R2, [R1]

LDR R1, =RECEVIE_CNT ;数据接收数组指针
LDRB R2, [R1]

LDRB R4, [R0] ;将数据从串口装载到数据接收数组
LDR R3, =BUF_RECEVIE
STRB R4, [R3, R2]

ADD R2, #1 ;数据接收数组指针加1
CMP R2, #MAX_BUF_NUM
MOVEQ R2, #0
STRB R2, [R1]
POP {R0-R8, PC}
RECEVIE_FULL ;接收满
POP {R0-R8, PC}


;;;;;发送数据到串口;;;;
USART_SEND
EXPORT USART_SEND
PUSH {R0-R8, LR}

LDR R0, =SEND_SEND_CT ;要发送数据的个数
LDRB R1, [R0]
CMP R1, #0
BEQ USART_SEND_END
SUB R1, #1
STRB R1, [R0]

LDR R0, =SEND_CNT ;要发送数据指针
LDRB R1, [R0]

LDR R4, =USART1_DR ;将数据发送数组的数据

发送到串口
LDR R2, =BUF_SEND
LDRB R3, [R2, R1]
STRB R3, [R4]

ADD R1, #1 ;要发送数据指针加1
CMP R1, #MAX_BUF_NUM
MOVEQ R1, #0
STRB R1, [R0]

POP {R0-R8, PC}
USART_SEND_END
LDR R0, =USART1_CR1 ;关闭发送中断
LDR R1, [R0]
BIC R1, #0X80
STR R1, [R0]
POP {R0-R8, PC}


;;;;;串口中断;;;;;;
USART1_IRQHandler
EXPORT USART1_IRQHandler
PUSH {R0-R8, LR}
LDR R0, =USART1_SR
LDR R1, [R0]
TST R1, #Bit5
BLNE USART_RECEVIE ;接收数据
POPNE {R0-R8, PC}
TST R1, #Bit7
BLNE USART_SEND ;发送数据
POP {R0-R8, PC}

ALIGN
END

相关文档
最新文档