STM32F031+串口中断+DMA发送

一、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的问题,可在此留言催跟。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呐咯密密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值