ARM汇编STM32F103VE串口中断发送接收
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//本文档是在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