完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
22.1 直接存储器访问
22.1.1 DMA功能框图讲解 DMA(Direct Memory Access)—直接存储器存取,是单片机的一个外设,它的主要功能 是用来搬数据,但是不需要占用 CPU,即在传输数据的时候,CPU 可以干其他的事情,好 像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以 是 SRAM 或者是 FLASH。DMA 控制器包含了 DMA1 和 DMA2,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存 在于大容量的单片机中。 Memory:Flash Sram P:外设 DMA2:5个通道 存在于大容量 互联型 仲裁器:处理多个DMA请求 1.软件阶段:DMA_CCRx 通道优先级 2.硬件阶段:通道编号小的优先级大,DMA1的优先级高于DMA2的优先级 22.1.2 DMA相关库函数讲解 typedef struct { //外设地址 uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */ //存储器地址 uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */ //传输方向 uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination. This parameter can be a value of @ref DMA_data_transfer_direction */ //传输数目 uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel. The data unit is equal to the configuration set in DMA_PeripheralDataSize or DMA_MemoryDataSize members depending in the transfer direction. */ //外设地址增量模式 uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not. This parameter can be a value of @ref DMA_peripheral_incremented_mode */ //存储器地址增量模式 uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not. This parameter can be a value of @ref DMA_memory_incremented_mode */ //外设数据宽度 uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width. This parameter can be a value of @ref DMA_peripheral_data_size */ //存储器数据宽度 uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width. This parameter can be a value of @ref DMA_memory_data_size */ //模式选择 uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx. This parameter can be a value of @ref DMA_circular_normal_mode. @note: The circular buffer mode cannot be used if the memory-to-memory data transfer is configured on the selected Channel */ //通道优先级 uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx. This parameter can be a value of @ref DMA_priority_level */ //存储器到存储器模式 uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer. This parameter can be a value of @ref DMA_memory_to_memory */ }DMA_InitTypeDef; */}DMA_InitTypeDef; 外设数据宽度和存储器数据宽度不对应 22.2 存储器到存储器代码讲解 22.2.1 M to M 把内部的FALASH(代码)数据传输到内部的SRAM(变量) bsp_dma_mtp.h #ifndef BSP_DMA_MTP_H #define BSP_DMA_MTP_H #include "stm32f10x.h" #include "stdio.h" // 串口工作参数宏定义 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUDRATE 115200 // USART GPIO 引脚宏定义 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 // 串口对应的DMA请求通道 #define USART_TX_DMA_CHANNEL DMA1_Channel4 #define USART_TX_FLAG_TC DMA1_FLAG_TC4 // 外设寄存器地址 #define USART_DR_ADDRESS (USART1_BASE+0x04) // 一次发送的数据量 #define SENDBUFF_SIZE 5000 void USART_Config(void); void USARTx_DMA_Config(void); #endif /*"BSP_DMA_MTP_H"*/ bsp_dma_mtp.c #include "bsp_dma_mtp.h" uint8_t SendBuff[SENDBUFF_SIZE]; void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 打开串口GPIO的时钟 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // 打开串口外设的时钟 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // 将USART Tx的GPIO配置为推挽复用模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // 将USART Rx的GPIO配置为浮空输入模式 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // 配置串口的工作参数 // 配置波特率 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; // 配置 针数据字长 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 配置停止位 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 配置校验位 USART_InitStructure.USART_Parity = USART_Parity_No ; // 配置硬件流控制 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 配置工作模式,收发一起 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 完成串口的初始化配置 USART_Init(DEBUG_USARTx, &USART_InitStructure); // 使能串口 USART_Cmd(DEBUG_USARTx, ENABLE); } ///重定向c库函数printf到串口,重定向后可使用printf函数 int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(DEBUG_USARTx, (uint8_t) ch); /* 等待发送完毕 */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); return (ch); } //USART->P void USARTx_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; // 开启DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 设置DMA源地址:串口数据寄存器地址*/ DMA_InitStructure.DMA_PeripheralBaseAddr = USART_DR_ADDRESS; // 内存地址(要传输的变量的指针) DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; // 方向:从内存到外设 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // 传输大小 DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; // 外设地址不增 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 内存地址自增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 外设数据单位 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 内存数据单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // DMA模式,一次或者循环模式 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; //DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 优先级:中 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; // 禁止内存到内存的传输 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 配置DMA通道 DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure); // 清除信道标志位 DMA_ClearFlag(USART_TX_FLAG_TC); // 使能DMA DMA_Cmd(USART_TX_DMA_CHANNEL,ENABLE); } main.c #include "stm32f10x.h" #include "bsp_led.h" #include "bsp_dma_mtp.h" extern uint8_t SendBuff[SENDBUFF_SIZE]; void Delay(uint32_t count) { for(;count!=0; count--); } int main() { uint16_t i = 0; //来到这个系统时钟被配置成72M LED_GPIO_Config(); USART_Config(); for(i = 0;i SendBuff = 'P'; } USARTx_DMA_Config(); USART_DMACmd(DEBUG_USARTx,USART_DMAReq_Tx,ENABLE); while(1) { LED_R(OFF); //GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); Delay(0xFFFFF); //GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); LED_R(ON); Delay(0xFFFFF); } } |
|
|
|
只有小组成员才能发言,加入小组>>
3308 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9049 浏览 16 评论
4083 浏览 18 评论
1167浏览 3评论
601浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
592浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2329浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1892浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:17 , Processed in 0.978261 second(s), Total 51, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号