完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
UART1.c
/******************************************************************************************** * 变 量 声 明 * *********************************************************************************************/ Stu_USART1_INFO Usart1_Info; /******************************************************************************************** * 函 数 声 明 * *********************************************************************************************/ unsigned int CirclePosition( unsigned int position, unsigned int length ) { if( position >= length ) position -= length; return position; } /******************************************************************************** * 函 数 名 : Usart1_ParameterInit * * 功 能 说 明 : UART1通信参数初始化 * * 形 参 : baudrate:波特率 * * 形 参 : parity:奇偶校验 * * 形 参 : databits:数据位 * * 形 参 : stopbits:停止位 * * 返 回 值 : 无 * *********************************************************************************/ void Usart1_ParameterInit(unsigned int baudrate,unsigned char parity,unsigned int databits,unsigned int stopbits ) { unsigned int i; Usart1_Info.Baudrate = baudrate; if( parity == 'N' ) { Usart1_Info.Parity = USART_Parity_No; } else if ( parity == 'E' ) { Usart1_Info.Parity = USART_Parity_Even; } else { Usart1_Info.Parity = USART_Parity_Odd; } if( databits == 8 ) { Usart1_Info.DataBit = USART_WordLength_8b; } else { Usart1_Info.DataBit = USART_WordLength_9b; } if( stopbits == 1 ) { Usart1_Info.StopBit = USART_StopBits_1; } else { Usart1_Info.StopBit = USART_StopBits_2; } Usart1_Info.RxIndex = 0; Usart1_Info.RxHead = 0; Usart1_Info.RxLength =0; Usart1_Info.TxIndex = 0; Usart1_Info.TxTail = 0; Usart1_Info.TxLength = 0; Usart1_Info.TxDMABusy = USART1_DMA_IDLE; for( i=0;i Usart1_Info.RxBuf = 0x00; Usart1_Info.TxBuf = 0x00; Usart1_Info.TxDMABuf = 0x00; } Usart1_Info.PreRxDMACounter = USART1_BUFLENGTH; Usart1_Info.OverTime =0; } /******************************************************************************** * 函 数 名 : Usart1_HardwareInit * * 功 能 说 明 : Usart1硬件初始化 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void Usart1_HardwareInit(void) { NVIC_InitTypeDef NVIC_InitStructure; //中断向量初始化结构体 GPIO_InitTypeDef GPIO_InitStructure; //GPIO初始化结构体 USART_InitTypeDef USART_InitStructure; //USART初始化结构体 // Configure the NVIC Preemption Priority Bits NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置优先级组 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //USART1全局中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断 NVIC_Init( &NVIC_InitStructure ); //使能串口时钟: USART1对应APB1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA时钟(设置TX/RX引脚)与复用时钟 //USART1发送引脚配置 GPIO_InitStructure.GPIO_Pin = USART1_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USART1_TX_PORT, &GPIO_InitStructure); //USART1接收引脚配置 GPIO_InitStructure.GPIO_Pin = USART1_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USART1_RX_PORT, &GPIO_InitStructure); //USART1参数设置 USART_InitStructure.USART_BaudRate = Usart1_Info.Baudrate; USART_InitStructure.USART_Parity = Usart1_Info.Parity ; USART_InitStructure.USART_WordLength = Usart1_Info.DataBit; USART_InitStructure.USART_StopBits = Usart1_Info.StopBit; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1, &USART_InitStructure); USART1->BRR = 0x271; //串口空闲中断(DMA模式) USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //启用 USART1 USART_Cmd(USART1, ENABLE); USART_ClearFlag(USART1, USART_FLAG_TC); } /******************************************************************************** * 函 数 名 : Usart1_DMAInit * * 功 能 说 明 : Usart1DMA初始化 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void Usart1_DMAInit(void) { NVIC_InitTypeDef NVIC_InitStructure; DMA_InitTypeDef DMA_Initstructure; // Configure the NVIC Preemption Priority Bits配置引脚优先级 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); //开启DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); |
|
|
|
//发送DMA配置
DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); // 关DMA通道 DMA_DeInit(DMA_USART1_TX_CHANNEL); // 恢复缺省值 DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器 DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.TxDMABuf; // 设置发送缓冲区首地址 DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralDST; // 设置外设为目的地址,内存缓冲区 ->外设寄存器 DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数 DMA_Initstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不做增加调整,调整不调整是DMA自动实现的 DMA_Initstructure.DMA_MemoryInc =DMA_MemoryInc_Enable; // 内存缓冲区地址增加调整 DMA_Initstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节 DMA_Initstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8位,1个字节 DMA_Initstructure.DMA_Mode = DMA_Mode_Normal; // 循环传输模式:DMA_Mode_Circular; 单次传输模式DMA_Mode_Normal; DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高 DMA_Initstructure.DMA_M2M = DMA_M2M_Disable; //启动发送DMA DMA_Init(DMA_USART1_TX_CHANNEL,&DMA_Initstructure); // 开启接收DMA通道,等待接收数据 // 开启发送DMA通道中断 DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TC, ENABLE); //DMA_IT_TC传输完成中断(transfer complete) DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TE, ENABLE); //DMA_IT_TE传输错误中断(transfer error) DMA_ClearFlag(DMA_USART1_TX_FLAG); // 清除DMA所有标志 DMA_Cmd(DMA_USART1_TX_CHANNEL,DISABLE); //启用DMA通道 //接收DMA配置 DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关DMA通道 DMA_DeInit(DMA_USART1_RX_CHANNEL); DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器 DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.RxBuf; // 设置发送缓冲区首地址 DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置外设为数据源,外设寄存器 ->内存缓冲区 DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数 DMA_Initstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不做增加调整,调整不调整是DMA自动实现的 DMA_Initstructure.DMA_MemoryInc =DMA_MemoryInc_Enable; // 内存缓冲区地址增加调整 DMA_Initstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节 DMA_Initstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8位,1个字节 DMA_Initstructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式:DMA_Mode_Circular; 单次传输模式DMA_Mode_Normal; DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高 DMA_Initstructure.DMA_M2M = DMA_M2M_Disable; //关闭存储器到存储器传输模式 //开启接收DMA通道 DMA_Init(DMA_USART1_RX_CHANNEL,&DMA_Initstructure); DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TC,ENABLE); DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TE,ENABLE); DMA_ClearFlag(DMA_USART1_RX_FLAG); DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE); //开启USART1的DMA模式 USART_DMACmd(USART1,USART_DMAReq_Rx|USART_DMAReq_Tx,ENABLE); } /******************************************************************************** * 函 数 名 : Usart1_SendtoTXbuf * * 功 能 说 明 : Usart1发送数据到TX缓存区 * * 形 参 : data:待发送数据首地址 * * length:待发送数据长度 * 返 回 值 : 无 * *********************************************************************************/ void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length ) { unsigned int i; if( length ) { for( i=0;i Usart1_Info.TxLength++; Usart1_Info.TxBuf[Usart1_Info.TxTail++]= data; //循环缓冲区装载数据 if( Usart1_Info.TxTail >= USART1_BUFLENGTH ) { Usart1_Info.TxTail -= USART1_BUFLENGTH; } } } } /******************************************************************************** * 函 数 名 : Usart1_SendtoTXDMAbuf * * 功 能 说 明 : Usart1发送数据到TX缓存区 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void Usart1_SendtoTXDMAbuf( void ) { unsigned int i; if( Usart1_Info.TxLength && ( Usart1_Info.TxDMABusy == USART1_DMA_IDLE ) ) { //有数据发送,往DMA缓冲区转移 for( i=0; i Usart1_Info.TxDMABuf = Usart1_Info.TxBuf[Usart1_Info.TxIndex++]; Usart1_Info.TxIndex = CirclePosition( Usart1_Info.TxIndex, USART1_BUFLENGTH ); } //启动DMA数据发送 DMA_SetCurrDataCounter(DMA_USART1_TX_CHANNEL,Usart1_Info.TxLength); Usart1_Info.TxLength = 0x00; Usart1_Info.TxDMABusy = USART1_DMA_BUSY; DMA_Cmd(DMA_USART1_TX_CHANNEL, ENABLE); } } /******************************************************************************** * 函 数 名 : USART1_IRQHandler * * 功 能 说 明 : Usart1中断处理函数 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void USART1_IRQHandler(void) { //DMA模式 unsigned int num; unsigned int Length; //DMA_GetCurrDataCounter if( USART_GetITStatus( USART1,USART_IT_IDLE ) == SET ) //整帧接收完成中断 { DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关闭接收DMA通道 //num = USART1->SR; num = USART1->DR; //读SR后读DR清USART_IT_IDLE标志 num = DMA_GetCurrDataCounter(DMA_USART1_RX_CHANNEL); //DMA接收数据后剩余缓存区间大小 //计算接收数据的长度 if( Usart1_Info.PreRxDMACounter >= num ) { Length = Usart1_Info.PreRxDMACounter - num; } else { Length = USART1_BUFLENGTH - num + Usart1_Info.PreRxDMACounter; } Usart1_Info.RxLength += Length; Usart1_Info.PreRxDMACounter = num; Usart1_Info.RxIndex = CirclePosition( Usart1_Info.RxIndex + Length, USART1_BUFLENGTH ); USART_ClearITPendingBit(USART1, USART_IT_IDLE); //清除中断标志 DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE); //重新开启DMA接收 } if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR USART_ReceiveData(USART1); //读DR } } /******************************************************************************** * 函 数 名 : DMA1_Channel2_IRQHandler * * 功 能 说 明 : 发送DMA中断处理函数 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void DMA1_Channel4_IRQHandler(void) { DMA_ClearFlag(DMA1_FLAG_GL4); //清除DMA发送完成标志 DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); //关闭发送DMA通道 Usart1_Info.TxDMABusy = USART1_DMA_IDLE; //发送通道空闲 } /******************************************************************************** * 函 数 名 : Usart1_Init * * 功 能 说 明 : Usart1初始化 * * 形 参 : 无 * * 返 回 值 : 无 * *********************************************************************************/ void Usart1_Init(void) { Usart1_ParameterInit(115200,'N',8,1); Usart1_HardwareInit(); Usart1_DMAInit(); } UART1.h #ifndef _BSP_UART1_H_ #define _BSP_UART1_H_ #include "stm32f10x.h" #define USART1_BUFLENGTH 256 #define DMA_USART1_RX_CHANNEL DMA1_Channel5 #define DMA_USART1_TX_CHANNEL DMA1_Channel4 #define DMA_USART1_RX_FLAG DMA1_FLAG_GL5 //DMA1_CHANNEL5全局中断标志 #define DMA_USART1_TX_FLAG DMA1_FLAG_GL4 //DMA1_CHANNEL4全局中断标志 #define USART1_DMA_IDLE 0x00 //USART3_DMA 空闲 #define USART1_DMA_BUSY 0x01 //USART3_DMA 忙 typedef struct { unsigned long Baudrate; //波特率 unsigned int Parity; //奇偶校验 unsigned int DataBit; //数据位 unsigned int StopBit; //停止位 unsigned char RxBuf[USART1_BUFLENGTH]; //接收缓存区长度 unsigned int RxIndex; // unsigned int RxHead; // unsigned int RxLength; //接收数据长度 unsigned int PreRxDMACounter; //DMA剩余缓存区间大小 unsigned char TxBuf[USART1_BUFLENGTH]; //发送缓存区长度 unsigned char TxDMABuf[USART1_BUFLENGTH ]; //DMA缓冲区 unsigned int TxIndex; // unsigned int TxTail; // unsigned int TxLength; //待发送数据长度 unsigned int TxDMABusy; //DMA发送忙信号 unsigned int OverTime; //通讯延时 } Stu_USART1_INFO; //GPIO定义 #define USART1_TX_PORT GPIOA #define USART1_TX_PIN GPIO_Pin_9 #define USART1_RX_PORT GPIOA #define USART1_RX_PIN GPIO_Pin_10 /******************************************************************************************** * 变 量 声 明 * *********************************************************************************************/ extern Stu_USART1_INFO Usart1_Info; /******************************************************************************************** * 函 数 声 明 * *********************************************************************************************/ extern void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length ); extern void Usart1_SendtoTXDMAbuf( void ); extern void Usart1_Init(void); extern unsigned int CirclePosition( unsigned int position, unsigned int length ); #endif |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1641 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1562 浏览 1 评论
990 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
691 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1610 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
655浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
525浏览 3评论
541浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
514浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 14:14 , Processed in 0.573214 second(s), Total 46, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号