STM32 串列埠DMA(一)
今天調USART,資料在晶片內部用DMA傳到串列埠快取,發現DMA真的很好,很快,而且不消耗系統資源。只是在傳輸完的時候中斷的標誌置位。下面解釋一下程式。
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//DMA設定:
//設定DMA源:記憶體地址&串列埠資料暫存器地址
//方向:記憶體-->外設
//每次傳輸位:8bit
//傳輸大小DMA_BufferSize=SENDBUFF_SIZE
//地址自增模式:外設地址不增,記憶體地址自增1
//DMA模式:一次傳輸,非迴圈
//優先順序:中
DMA_DeInit(DMA1_Channel4); //功能描述: 將DMA的通道x 暫存器重設為預設值. 輸入引數: DMA Channelx :x 可以是1 2…,或者 7 來選擇DMA通道x
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; //該引數用以定義DMA外設基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; //該引數用以定義DMA記憶體基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //DMA_DIR 規定了外設是作為資料傳輸的目的地還是來源。
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; //DMA_BufferSize用以定義指定 DMA通道的DMA快取的大小,單位為資料單位。根據傳輸方向,資料單位等於結構中引數DMA_PeripheralDataSize 或者引數 DMA_MemoryDataSize 的值。
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //DMA_PeripheralInc用來設定外設地址暫存器遞增與否。
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_MemoryInc 用來設定記憶體地址暫存器遞增與否。
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //DMA_PeripheralDataSize 設定了外設資料寬度。Byte 8位。HalfWord 16位。Word 32位。
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //DMA_MemoryDataSize 設定了外設資料寬度。
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode設定了CAN的工作模式,Circular 工作在迴圈快取模式,Normal 工作在正常快取模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA_Priority 設定DMA通道x 的軟體優先順序。VeryHigh,High,Medium ,Low
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA_M2M使能DMA通道的記憶體到記憶體傳輸。
DMA_Init(DMA1_Channel4, &DMA_InitStructure); //
}
再弄幾個重要的語句。
//這裡是開始DMA傳輸前的一些準備工作,將USART1模組設定成DMA方式工作
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
//開始一次DMA傳輸!
DMA_Cmd(DMA1_Channel4, ENABLE);
在串列埠配置的時候需要開啟串列埠接收中斷
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
相應的NVIC
/設定NVIC優先順序分組為Group2:0-3搶佔式優先順序,0-3的響應式優先順序
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//串列埠接收中斷開啟
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//啟動DMA時鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);