STM32 - DMA 编程实践2 M2P

news/2024/12/29 2:06:20/

1. 实验设计:

Memory to Peripheral , Memory to 外设, 把内部SRAM的数据传输到串口外设,同时LED灯闪烁,演示DMA传数据不需要占用CPU

2. 编程要点

1)初始化USART;

2)初始化DMA,注意也需要初始化DMA外设的时钟;

3)编写主函数(开启串口发送DMA请求);

3 源码

完成相关宏定义

// 串口工作参数宏定义
#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_DR_ADDRESS        (USART1_BASE+0x04)
// 一次发送的数据量
#define  SENDBUFF_SIZE            5000void USART_Config(void);
void USARTx_DMA_Config(void);

配置USART, DMA 模式

uint8_t SendBuff[SENDBUFF_SIZE];/*** @brief  USART GPIO 配置,工作参数配置* @param  无* @retval 无*/
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);	    
}/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{/* 发送一个字节数据到USART */USART_SendData(pUSARTx,ch);/* 等待发送数据寄存器为空 */while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{uint8_t i;for(i=0; i<num; i++){/* 发送一个字节数据到USART */Usart_SendByte(pUSARTx,array[i]);	}/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while(*(str + k)!='\0');/* 等待发送完成 */while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET){}
}/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{uint8_t temp_h, temp_l;/* 取出高八位 */temp_h = (ch&0XFF00)>>8;/* 取出低八位 */temp_l = ch&0XFF;/* 发送高八位 */USART_SendData(pUSARTx,temp_h);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);/* 发送低八位 */USART_SendData(pUSARTx,temp_l);	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}///重定向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);
}///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{/* 等待串口输入数据 */while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(DEBUG_USARTx);
}/*** @brief  USARTx TX DMA 配置,内存到外设(USART1->DR)* @param  无* @retval 无*/
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);		// 使能DMADMA_Cmd (USART_TX_DMA_CHANNEL,ENABLE);
}

main 函数中调用相关代码,演示DMA搬数据的同时,CPU还能干其他事

extern uint8_t SendBuff[SENDBUFF_SIZE];void Delay(__IO uint32_t nCount)	 //简单的延时函数
{for(; nCount != 0; nCount--);
}int main(void)
{uint16_t i;/* 初始化USART */USART_Config(); /* 配置使用DMA模式 */USARTx_DMA_Config();/* 配置RGB彩色灯 */LED_GPIO_Config();//printf("\r\n USART1 DMA TX 测试 \r\n");/*填充将要发送的数据*/for(i=0;i<SENDBUFF_SIZE;i++){SendBuff[i]	 = 'P';}/*为演示DMA持续运行而CPU还能处理其它事情,持续使用DMA发送数据,量非常大,*长时间运行可能会导致电脑端串口调试助手会卡死,鼠标乱飞的情况,*或把DMA配置中的循环模式改为单次模式*/		/* USART1 向 DMA发出TX请求 */USART_DMACmd(DEBUG_USARTx, USART_DMAReq_Tx, ENABLE);/* 此时CPU是空闲的,可以干其他的事情 */  //例如同时控制LEDwhile(1){LED1_TOGGLEDelay(0xFFFFF);}
}

实测有效


http://www.ppmy.cn/news/647037.html

相关文章

ibm服务器找不到网卡,IBM X3650 M2服务器网卡(BCM5709)在RHEL5.4下有时断网问题

作者:sealinger发布时间:December 21, 2010分类: 2010年7月遇到 IBM X3650 M2服务器网卡在RHEL 5.4 X64系统下有时断网和drop包的异常,记录下来希望帮助到有同样问题的人。 已确认问题: “RHEL 5.3/5.4 自带的Broadcom NetXtreme II BCM5709 网卡驱动有BUG,涉及到 ACPI 电…

Renesa 瑞萨 RA4M2 移植文件系统FAT32

工程创建 Resc进行可视化配置工程 选定芯片型号 配置SDIO底层驱动&#xff08;SD card&#xff09; 跳到对应GPIO&#xff0c;进行复用 将Operation Mode配置 SD_MMC 4Bit&#xff0c;系统会自动配置 会到stacks 根据上面提示&#xff0c;解决错误。 解决第一个error S…

香蕉派开源硬件开发板 Banana Pi BPI M2Pro Amlogic S905X3 主板

Banana Pi BPI-M2 Pro是Banana Pi公司于2021年推出的下一代单板机。它采用Amlogic S905X3四核Cortex-A55 (2.0 XXGHz)处理器。板载2GB LPDDR4内存和16GB EMMC存储&#xff0c;支持2个USB 3.0接口&#xff0c;1个千兆网口。板载RT8821CU wifi&BT。1 HDMI输出 905X3是晶晨半导…

M2DGR数据集在一些SLAM框架上的配置与运行:ORB-SLAM系列、VINS-Mono、LOAM系列、FAST-LIO系列、hdl_graph_slam

文章目录 一、M2DGR数据集二、ORB-SLAM22.1 配置参数2.2 单目 三、ORB-SLAM33.1 配置参数3.2 运行单目IMU 四、VINS-Mono4.1 配置参数4.2 运行单目IMU 五、DM-VIO5.1 安装5.2 配置运行 六、A-LOAM七、LeGO-LOAM八、LIO-SAM8.1 配置参数8.2 运行 九、LVI-SAM9.1 配置参数9.2 运行…

安全芯片OPTIGA Trust M2 ID2连接阿里云

英飞凌的安全芯片产品OPTIGA Trust M2 ID2,是款通过了CC EAL6+,可用于工业自动化、消费、智能家居、医疗等IoT场景的安全产品。 主控怎么通过I2C来连接Trust X的呢? 上电后,大约10ms后,I2C接口的启动: 热启动的话,主要是拉一下RST信号线,其中下降沿和上升沿需要满足…

DMA学习笔记 M2M M2P 代码实现

编程要点 1-初始化DMA初始化结构体。 2-熟读参考手册DMA章节&#xff08;非常重要&#xff09; M To M 编程要点  1-在FLASH中定义好要传输的数据&#xff0c;在SRAM中定 义好用来接收FLASH数据的变量。  2-初始化DMA&#xff0c;主要是配置DMA初始化结构体。  3-编写比…

【HTML+CSS兼容性】 li中插入img元素之间存在空隙BUG问题+解决方案 前端零基础必须知道的事情!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

RA4M2开发(4)----读取HS3003数据,并在OLED上显示,串口打印

概述 HS3003是一种数字式温湿度传感器&#xff0c;可以测量环境中的温度和湿度。读取HS3003的数据需要连接传感器到一个数据采集系统&#xff0c;一般是微处理器或者单片机。以下是一个简单的读取HS3003数据的概述&#xff1a; 连接电路&#xff1a;将HS3003传感器连接到微处…