STM32F031+串口中断+DMA发送

Tulla ·
更新时间:2024-09-20
· 526 次阅读

一、GPIO配置

上一篇博文已经介绍了F0和F1系列的不同点,这里不再赘述,先上代码:
这里给出相关文档的下载路径:
链接: STM32F031G4中文编程手册.

/*GPIOA初始化配置 */ void GPIOA_Config() { GPIO_InitTypeDef GPIO_InitStructure; /*初始化GPIOA时钟*/ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /*复用 AF1,看手册*/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); /* 配置PA9 ,PA10 串口*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //设置端口复用 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;/* 推挽输出或开漏输出 */ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 无、上拉或下拉 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;//50MHZ GPIO_Init(GPIOA, &GPIO_InitStructure); /*485使能引脚*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA, GPIO_Pin_8);//初始化GPIOA8为低电平 }

这里在上一篇文章说过,GPIO要配置成复用功能映射表,此处补充一张复用图:
端口 A 通过 GPIOA_AFR 寄存器选择的复用功能

二、USART配置 /*串口初始化配置 */ void USART_Config(void) { USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /*初始化USART1时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitStructure.USART_BaudRate = 2500000;//设置串口波特率 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置流控制 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//设置工作模式 USART_InitStructure.USART_Parity = USART_Parity_No;//设置效验位 USART_InitStructure.USART_StopBits = USART_StopBits_1;//设置停止位 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//设置数据位 USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE);//使能串口 1 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; NVIC_Init(&NVIC_InitStructure); //初始化VIC寄存器 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断 } 三、DMA配置 void MYDMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输 DMA1_MEM_LEN = 11; DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE+0x28; //DMA外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_TX_BUF; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = DMA1_MEM_LEN; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel2, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 DMA_Cmd(DMA1_Channel2, ENABLE); //使能USART1 TX DMA1 所指示的通道 } void MYDMA_Send(void) { DMA_Cmd(DMA1_Channel2, DISABLE); DMA_SetCurrDataCounter(DMA1_Channel2, DMA1_MEM_LEN); DMA_Cmd(DMA1_Channel2, ENABLE); } 四、串口485发送函数

串口中断函数

//串口1中断服务函数 void USART1_IRQHandler(void) { uint8_t Res; //处理接收到的数据 if(USART_GetITStatus(USART1, USART_IT_RXNE)) { Res =UART_Recive();//读取串口接收到的数据 if(Res == 0x1A) { RS_485_send();//485+DMA发送函数 } } /* 清除串口接收标志位 */ USART_ClearFlag(USART1,USART_FLAG_RXNE); GPIO_ResetBits(GPIOA, GPIO_Pin_8); //接收模式 }

485发送函数

/* RS485发送 */ void RS_485_send(){ uint8_t i; GPIO_SetBits(GPIOA, GPIO_Pin_8);//设置为发送模式 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); DMA_Send(); while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); GPIO_ResetBits(GPIOA, GPIO_Pin_8); //接收模式 }

DMA发送函数

void DMA_Send(void) { USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送 MYDMA_Send(); if(DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET) { DMA_ClearFlag(DMA1_FLAG_TC2); } //这里可以放其他东西,与发送数据同时进行 // GPIO_ResetBits(GPIOA, GPIO_Pin_8); //设置485为接收模式 }

代码运行时485接收到数据产生中断,并对数据进行判断,符合条件会使用DMA+485讲数据发送出去。因为工作时间紧张,所有没有对代码做详细讲解,若有疑问自行留言,我看到会回复。此篇为STM32F0系列开篇,后面会继续更新内外部时钟切换,SPI连续发送24位甚至更多位数据,发送时钟连续,我在做这个的时候全网没找到相应介绍,真心难死我了,就到这里,下篇见,如若在我未更新便有人遇到SPI的问题,可在此留言催跟。


作者:呐咯密密



dma 中断 串口

需要 登录 后方可回复, 如果你还没有账号请 注册新账号