STM32 DMA 串口透传
DMA 网上的解释一大堆,简单总结一下:
DMA处理过程全部是由硬件来实现的,速度很快!
DMA在专门的DMA控制下,实现高速外设与主存储期之间自动成批量的数据交换。
通常有两种交换方式:1独占总线方式 2周期挪用方式
DMA传送过程
DMA预处理
DMA数据传送
DMA结束处理将总线控制权交换给CPU
DMA内部寄存器
地址寄存器:存放DMA传输是储存单元地址
字节寄存器:存放DMA传输字节数
控制寄存器:存放CPU设定的DMA传输方式
状态寄存器:存放DMAC当前的状态
DMA外设地址:基地址+偏移地址
两种方法设定地址:
#defineUSART1_DR_Base 0x40013804
#defineUSART1_DR_Base (&(USART1->DR)) 觉得还是第二种方法比较直接
DMA两种中断触发方式:
DMA_IT_TC1传输完成中断:每次更新发生在计数>=设定值
DMA_IT_HT1传输过半中断:每次更新发生在计数>(设定值/2)
DMA_IT_GL1全局中断:(实验了几次和过半中断传输情况一致)
编程的时候根据DMA请求映像来判断通道号,然后找到目的地址和原地址基本上就算完事儿了。当然得分清是传输是外设和内存,内存和外设,内存和内存三种情况,会有 (DMA_InitTypeDef 结构体).DMA_M2M 进行设置。
下面是DMA串口收发简单例子,并没有用到FIFO精确收发,有时间再好好写写~
DMA_Configuration()是DMA5通道 串口1接收通道配置函数
DMA_Configuration2()是DMA4通道 串口1发送通道配置函数
对于发送 可以每当发送的时候 都执行DMA_Configuration2(),进行发送操作
对于接收 理应采用FIFO,对于接收数组进行处理,这里只是简单的接收,没有进一步处理
/* Includes ------------------------------------------------------------------*/#include "stm32f10x.h"#include "stm32f10x_tim.h" #include "stm32f10x_rcc.h"#include "stm32f10x_map.h" #include "stm32f10x_it.h" #include "misc.h" #include "bsp_timer.h"#include "stm32f10x_usart.h"#include "stm32f10x_dma.h"#include "stdio.h"#define SENDBUFF_SIZE 10vu8 SendBuff[SENDBUFF_SIZE]={0};vu8 TxBuffer[] = "hello xiao lei !!! ";vu8 NbrOfDataToTransfer = sizeof(TxBuffer)-1;GPIO_InitTypeDef GPIO_InitStructure;#define LED1_ON GPIO_SetBits(GPIOB, GPIO_Pin_5); #define LED1_OFF GPIO_ResetBits(GPIOB, GPIO_Pin_5); #define LED2_ON GPIO_SetBits(GPIOD, GPIO_Pin_6); #define LED2_OFF GPIO_ResetBits(GPIOD, GPIO_Pin_6); #define LED3_ON GPIO_SetBits(GPIOD, GPIO_Pin_3); #define LED3_OFF GPIO_ResetBits(GPIOD, GPIO_Pin_3); void RCC_Configuration(void);void LED_Config(void);void Delay(__IO uint32_t nCount);int fputc(int ch, FILE *f){USART_SendData(USART1, (u8) ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}return ch;}/* 名 称:void LED_Config(void)* 功 能:LED 控制初始化函数* 入口参数:无* 出口参数:无* 说 明:* 调用方法:无 / void LED_Config(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1 V6 //将V6,V7,V8 配置为通用推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线翻转速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3 V7 V8GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //LCD背光控制GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_ResetBits(GPIOD, GPIO_Pin_13); //LCD背光关闭 }void USART1_Configration(){USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStr
STM32DMA串口透 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)