DMA应用实例详解
DMA應用實例詳解
閑來無事,學習了下DMA的相關知識和使用。平時看到的DMA都是簡單的存儲器到寄存器或者寄存器到存儲器這樣單類的傳輸。學習完DMA后,我想寫個比較綜合點的DMA學習實例,不僅能增加自己對DMA的深入應用,也同時發表于此給網友提供參考。之所以說多知識,實例涉及到存儲器到寄存器和寄存器到存儲器,以及DMA中斷使用等相關知識。
實例內容:單片機采集AD值通過DMA傳輸給RAM存儲器(就是定義的變量),同時又將存儲器數據傳輸給串口輸出,實現AD采集與串口輸出的轉換。
下面賦上一些主要的代碼進行分析:
1.主函數部分
int main(void) { delay_init(); //延時初始化RCCInit();//時鐘初始化USARTInit(USART2 ,115200);//串口初始化ADCInit(ADC1 , 1); //AD初始化PA1Get_ADCValue(ADC1 ,ADC_Channel_1 ,1);//對ADC通道配置//ADC1-->存儲器(adcValue)(注傳入地址位要32位)DMAx_ADCx_Init(DMA1_Channel1 ,DMA_DIR_PeripheralSRC,(u32)(&adcValue), u32)&(ADC1->DR),1);//存儲器(adcValue)-->UASART1DMAx_USARTx_Init(DMA1_Channel7 ,DMA_DIR_PeripheralDST,(u32)usart_BUFF, (u32)&(USART2->DR),bufferSize);NVIC_Config();//注意,實測過,DMA中斷配置必須放在DMA配置后面才能用DMAx_Enable(DMA1_Channel1 , 1);ADC_DMACmd(ADC1, ENABLE);DMAx_Enable(DMA1_Channel7 , bufferSize);//先啟動,使滿標志不為0USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);printf("下面是DMA測試,AD值為:\r\n");while(1){delay_ms(100);DMAx_Enable(DMA1_Channel1 , 1);} }
2.DMA1_CH1中斷函數
void DMA1_Channel1_IRQHandler() {if(DMA_GetITStatus(DMA1_IT_TC1) == SET)//獲取DMA1_CH1的傳輸完成標志位{DMA_ClearITPendingBit(DMA1_IT_TC1);//清除滿標志(注意清除后,不能去等待判滿)//16位整型轉化為字符串型(每個字符8位,1字節)(轉換中加了個空格,方便顯示)sprintf(usart_BUFF,"%d ",adcValue);while(!DMA_GetFlagStatus( DMA1_FLAG_TC7));//等待傳輸完成(注意 等待判滿前,不能清除標志)DMA_ClearFlag(DMA1_FLAG_TC7); //完成后清除DMAx_Enable(DMA1_Channel7 , bufferSize);//開始串口的DMA傳輸 } }3.ADC初始化
void ADCInit(ADC_TypeDef* ADCx , u8 Channel_num) {//=============對ADC1的配置并校準====================//ADC_InitTypeDef ADC_Inittrue;ADC_DeInit(ADCx);//復位ADC1ADC_Inittrue.ADC_ContinuousConvMode = ENABLE;//連續轉換ADC_Inittrue.ADC_DataAlign = ADC_DataAlign_Right;//右對齊。(ADC為12位精度,其數字信號存于16位的寄存器)ADC_Inittrue.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//觸發方式,無外部觸發=軟件觸發ADC_Inittrue.ADC_Mode = ADC_Mode_Independent;//獨立模式ADC_Inittrue.ADC_NbrOfChannel = Channel_num;//順序進行規則轉換的 ADC 通道的數目(1--16)ADC_Inittrue.ADC_ScanConvMode = DISABLE;//無掃描模式,即工作在單通道下ADC_Init(ADCx, &ADC_Inittrue);//初始化配置模塊ADC1 ADC_Cmd(ADCx, ENABLE);//使能ADC1ADC_ResetCalibration(ADCx); //復位校準while(ADC_GetResetCalibrationStatus(ADCx));ADC_StartCalibration(ADCx);//開啟adc校準while(ADC_GetCalibrationStatus(ADCx)); }4.ADC通道配置,并獲取相應模塊下通道的ADC值(這里只用到通道配置就夠了)
u16 Get_ADCValue(ADC_TypeDef* ADCx ,u8 ADC_Channel_x ,u8 rank) { //========對ADC的規則通道的配置(選通道x)=========//ADC_RegularChannelConfig(ADCx,ADC_Channel_x, rank , ADC_SampleTime_28Cycles5);//ADC1的通道4,排在第1個被轉換,并且采集時間為28.5個ADC1時鐘周期ADC_SoftwareStartConvCmd(ADCx ,ENABLE);//開啟軟件轉換//========對ADC轉換部分=========//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束return ADC_GetConversionValue(ADCx)&0x00000fff;//換回ADC1轉換后的值 }
5.DMA_ADC初始化
//名稱:DMA ADC初始化
//傳入參數:通道 傳輸方向 存儲器基地址? 外設基地址 數據量
//注:傳入地址位數32位
//說明:默認非循環,存儲器地址不自加,外設不自加,數據寬度都為16位
void DMAx_ADCx_Init(DMA_Channel_TypeDef* DMAx_Channelx ,u32 DMA_DIR_Peripheralxxx , u32 MemoryBaseAddr, u32 PeripheralBaseAddr,u16 DMA_BufferSize) {DMA_InitTypeDef DMA_InitStruct;if(DMA1_Channel1 <= DMAx_Channelx && DMA1_Channel7 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA位于AHB時鐘上}if(DMA2_Channel1 <= DMAx_Channelx && DMA2_Channel5 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//DMA位于AHB時鐘上}DMA_DeInit(DMAx_Channelx);//DMA_InitStruct.DMA_BufferSize = DMA_BufferSize;//DMA傳輸的數據量DMA_InitStruct.DMA_DIR = DMA_DIR_Peripheralxxx;//傳輸方向:外設為目標地址(存儲器到外設)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //存儲器到存儲器傳輸失能DMA_InitStruct.DMA_MemoryBaseAddr = MemoryBaseAddr;//存儲器基地址(可為sram或flash,程序變量一般位于sram)DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存儲器傳輸數據寬度16(可選8,16,32位)DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;//存儲器地址不遞增DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;// 不循環傳輸模式(循環:地址遞增滿后,又重載從基地址開始傳輸)(不循環:遞增滿后不重載且暫停)DMA_InitStruct.DMA_PeripheralBaseAddr = PeripheralBaseAddr;//外設寄存器的基地址(多是數據寄存器)DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外設寄存器傳輸數據寬度16(8,16,32位)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不進行遞增DMA_InitStruct.DMA_Priority = DMA_Priority_High;//傳輸優先級:高(四種:最高,高,中,低)DMA_Init(DMAx_Channelx, &DMA_InitStruct); }
6.DMA_USART初始化
注意此初始化和ADC 的DMA初始化是不一樣的,具體不一樣處見函數說明, 和調用的實參。
//名稱:DMA USART初始化
//傳入參數:通道 傳輸方向 存儲器基地址? 外設基地址 數據量
//注;傳入地址位數32位
//說明:默認非循環,存儲器地址自加,外設不自加,數據寬度都為8位
void DMAx_USARTx_Init(DMA_Channel_TypeDef* DMAx_Channelx ,u32 DMA_DIR_Peripheralxxx , u32 MemoryBaseAddr, u32 PeripheralBaseAddr,u16 DMA_BufferSize) {DMA_InitTypeDef DMA_InitStruct;if(DMA1_Channel1 <= DMAx_Channelx && DMA1_Channel7 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA位于AHB時鐘上}if(DMA2_Channel1 <= DMAx_Channelx && DMA2_Channel5 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//DMA位于AHB時鐘上}DMA_DeInit(DMAx_Channelx);DMA_InitStruct.DMA_BufferSize = DMA_BufferSize;//DMA傳輸的數據量DMA_InitStruct.DMA_DIR = DMA_DIR_Peripheralxxx;//傳輸方向:外設為目標地址(存儲器到外設)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //存儲器到存儲器傳輸失能DMA_InitStruct.DMA_MemoryBaseAddr = MemoryBaseAddr;//存儲器基地址(可為sram或flash,程序變量一般位于sram)DMA_InitStruct.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte;存儲器傳輸數據寬度8位(8,16,32位)DMA_InitStruct.DMA_MemoryInc =DMA_MemoryInc_Enable;//存儲器地址隨傳輸而遞增(加多少與數據寬度有關,可見芯片參考手冊,這里是地址自加1)DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//不循環傳輸模式(循環:地址遞增滿后,又重載從基地址開始傳輸)(不循環:遞增滿后不重載且暫停)DMA_InitStruct.DMA_PeripheralBaseAddr = PeripheralBaseAddr;//外設寄存器的基地址(多是數據寄存器)DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// DMA_PeripheralDataSize_HalfWord;//外設寄存器傳輸數據寬度8位(8,16,32位)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不進行遞增DMA_InitStruct.DMA_Priority = DMA_Priority_High;//傳輸優先級:高(四種:最高,高,中,低)DMA_Init(DMAx_Channelx, &DMA_InitStruct); }
7.DMA啟動傳輸(用于每次傳輸開啟)
//DMA啟動傳輸
//傳入參數:通道? 數據量
void DMAx_Enable(DMA_Channel_TypeDef* DMAx_Channelx ,u16 DMA_BufferSize) {DMA_Cmd(DMAx_Channelx, DISABLE);//失能DMA_SetCurrDataCounter( DMAx_Channelx , DMA_BufferSize); //重新設置傳輸數據長度DMA_Cmd(DMAx_Channelx, ENABLE);//使能}
8.中斷配置函數
void NVIC_Config() {NVICInit(NVIC_PriorityGroup_2, DMA1_Channel1_IRQn , 0, 1); //組別2 搶占0 從占1DMA_ClearFlag(DMA1_FLAG_TC1);//清滿標志DMA_ClearITPendingBit(DMA1_IT_TC1); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);//開啟全部傳輸完成中斷 }9.RCC時鐘配置
void RCCInit() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1 , ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC時鐘周期 6分頻 }
下面是上位機顯示傳輸的數據:
對于串口,一次只能輸出8位(一字節數),即使傳進去16位數,也被截取前半段 ADC采集為10為精度,數據存儲寬度要大于8位 所以:DMA的ADC傳輸需要16位,而USART傳輸只能8位傳輸 該例程的ADC為連續轉換模式,若是單次需要每次對通道重新配置一次 *DMA為循環模式只需要使能一次,否則非循環下需要重新使能 來啟動傳輸 每個DMA通道對應不同外設見手冊 DMA中斷配置必須放在DMA參數配置后面才能用 注意:等待判滿前,不能清除標志;注意:清除后,不能去等待判滿,否則死循環。
閑來無事,學習了下DMA的相關知識和使用。平時看到的DMA都是簡單的存儲器到寄存器或者寄存器到存儲器這樣單類的傳輸。學習完DMA后,我想寫個比較綜合點的DMA學習實例,不僅能增加自己對DMA的深入應用,也同時發表于此給網友提供參考。之所以說多知識,實例涉及到存儲器到寄存器和寄存器到存儲器,以及DMA中斷使用等相關知識。
實例內容:單片機采集AD值通過DMA傳輸給RAM存儲器(就是定義的變量),同時又將存儲器數據傳輸給串口輸出,實現AD采集與串口輸出的轉換。
下面賦上一些主要的代碼進行分析:
1.主函數部分
int main(void) { delay_init(); //延時初始化RCCInit();//時鐘初始化USARTInit(USART2 ,115200);//串口初始化ADCInit(ADC1 , 1); //AD初始化PA1Get_ADCValue(ADC1 ,ADC_Channel_1 ,1);//對ADC通道配置//ADC1-->存儲器(adcValue)(注傳入地址位要32位)DMAx_ADCx_Init(DMA1_Channel1 ,DMA_DIR_PeripheralSRC,(u32)(&adcValue), u32)&(ADC1->DR),1);//存儲器(adcValue)-->UASART1DMAx_USARTx_Init(DMA1_Channel7 ,DMA_DIR_PeripheralDST,(u32)usart_BUFF, (u32)&(USART2->DR),bufferSize);NVIC_Config();//注意,實測過,DMA中斷配置必須放在DMA配置后面才能用DMAx_Enable(DMA1_Channel1 , 1);ADC_DMACmd(ADC1, ENABLE);DMAx_Enable(DMA1_Channel7 , bufferSize);//先啟動,使滿標志不為0USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);printf("下面是DMA測試,AD值為:\r\n");while(1){delay_ms(100);DMAx_Enable(DMA1_Channel1 , 1);} }
2.DMA1_CH1中斷函數
void DMA1_Channel1_IRQHandler() {if(DMA_GetITStatus(DMA1_IT_TC1) == SET)//獲取DMA1_CH1的傳輸完成標志位{DMA_ClearITPendingBit(DMA1_IT_TC1);//清除滿標志(注意清除后,不能去等待判滿)//16位整型轉化為字符串型(每個字符8位,1字節)(轉換中加了個空格,方便顯示)sprintf(usart_BUFF,"%d ",adcValue);while(!DMA_GetFlagStatus( DMA1_FLAG_TC7));//等待傳輸完成(注意 等待判滿前,不能清除標志)DMA_ClearFlag(DMA1_FLAG_TC7); //完成后清除DMAx_Enable(DMA1_Channel7 , bufferSize);//開始串口的DMA傳輸 } }3.ADC初始化
void ADCInit(ADC_TypeDef* ADCx , u8 Channel_num) {//=============對ADC1的配置并校準====================//ADC_InitTypeDef ADC_Inittrue;ADC_DeInit(ADCx);//復位ADC1ADC_Inittrue.ADC_ContinuousConvMode = ENABLE;//連續轉換ADC_Inittrue.ADC_DataAlign = ADC_DataAlign_Right;//右對齊。(ADC為12位精度,其數字信號存于16位的寄存器)ADC_Inittrue.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//觸發方式,無外部觸發=軟件觸發ADC_Inittrue.ADC_Mode = ADC_Mode_Independent;//獨立模式ADC_Inittrue.ADC_NbrOfChannel = Channel_num;//順序進行規則轉換的 ADC 通道的數目(1--16)ADC_Inittrue.ADC_ScanConvMode = DISABLE;//無掃描模式,即工作在單通道下ADC_Init(ADCx, &ADC_Inittrue);//初始化配置模塊ADC1 ADC_Cmd(ADCx, ENABLE);//使能ADC1ADC_ResetCalibration(ADCx); //復位校準while(ADC_GetResetCalibrationStatus(ADCx));ADC_StartCalibration(ADCx);//開啟adc校準while(ADC_GetCalibrationStatus(ADCx)); }4.ADC通道配置,并獲取相應模塊下通道的ADC值(這里只用到通道配置就夠了)
u16 Get_ADCValue(ADC_TypeDef* ADCx ,u8 ADC_Channel_x ,u8 rank) { //========對ADC的規則通道的配置(選通道x)=========//ADC_RegularChannelConfig(ADCx,ADC_Channel_x, rank , ADC_SampleTime_28Cycles5);//ADC1的通道4,排在第1個被轉換,并且采集時間為28.5個ADC1時鐘周期ADC_SoftwareStartConvCmd(ADCx ,ENABLE);//開啟軟件轉換//========對ADC轉換部分=========//while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束return ADC_GetConversionValue(ADCx)&0x00000fff;//換回ADC1轉換后的值 }
5.DMA_ADC初始化
//名稱:DMA ADC初始化
//傳入參數:通道 傳輸方向 存儲器基地址? 外設基地址 數據量
//注:傳入地址位數32位
//說明:默認非循環,存儲器地址不自加,外設不自加,數據寬度都為16位
void DMAx_ADCx_Init(DMA_Channel_TypeDef* DMAx_Channelx ,u32 DMA_DIR_Peripheralxxx , u32 MemoryBaseAddr, u32 PeripheralBaseAddr,u16 DMA_BufferSize) {DMA_InitTypeDef DMA_InitStruct;if(DMA1_Channel1 <= DMAx_Channelx && DMA1_Channel7 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA位于AHB時鐘上}if(DMA2_Channel1 <= DMAx_Channelx && DMA2_Channel5 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//DMA位于AHB時鐘上}DMA_DeInit(DMAx_Channelx);//DMA_InitStruct.DMA_BufferSize = DMA_BufferSize;//DMA傳輸的數據量DMA_InitStruct.DMA_DIR = DMA_DIR_Peripheralxxx;//傳輸方向:外設為目標地址(存儲器到外設)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //存儲器到存儲器傳輸失能DMA_InitStruct.DMA_MemoryBaseAddr = MemoryBaseAddr;//存儲器基地址(可為sram或flash,程序變量一般位于sram)DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存儲器傳輸數據寬度16(可選8,16,32位)DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;//存儲器地址不遞增DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;// 不循環傳輸模式(循環:地址遞增滿后,又重載從基地址開始傳輸)(不循環:遞增滿后不重載且暫停)DMA_InitStruct.DMA_PeripheralBaseAddr = PeripheralBaseAddr;//外設寄存器的基地址(多是數據寄存器)DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外設寄存器傳輸數據寬度16(8,16,32位)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不進行遞增DMA_InitStruct.DMA_Priority = DMA_Priority_High;//傳輸優先級:高(四種:最高,高,中,低)DMA_Init(DMAx_Channelx, &DMA_InitStruct); }
6.DMA_USART初始化
注意此初始化和ADC 的DMA初始化是不一樣的,具體不一樣處見函數說明, 和調用的實參。
//名稱:DMA USART初始化
//傳入參數:通道 傳輸方向 存儲器基地址? 外設基地址 數據量
//注;傳入地址位數32位
//說明:默認非循環,存儲器地址自加,外設不自加,數據寬度都為8位
void DMAx_USARTx_Init(DMA_Channel_TypeDef* DMAx_Channelx ,u32 DMA_DIR_Peripheralxxx , u32 MemoryBaseAddr, u32 PeripheralBaseAddr,u16 DMA_BufferSize) {DMA_InitTypeDef DMA_InitStruct;if(DMA1_Channel1 <= DMAx_Channelx && DMA1_Channel7 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA位于AHB時鐘上}if(DMA2_Channel1 <= DMAx_Channelx && DMA2_Channel5 >= DMAx_Channelx){RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//DMA位于AHB時鐘上}DMA_DeInit(DMAx_Channelx);DMA_InitStruct.DMA_BufferSize = DMA_BufferSize;//DMA傳輸的數據量DMA_InitStruct.DMA_DIR = DMA_DIR_Peripheralxxx;//傳輸方向:外設為目標地址(存儲器到外設)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //存儲器到存儲器傳輸失能DMA_InitStruct.DMA_MemoryBaseAddr = MemoryBaseAddr;//存儲器基地址(可為sram或flash,程序變量一般位于sram)DMA_InitStruct.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte;存儲器傳輸數據寬度8位(8,16,32位)DMA_InitStruct.DMA_MemoryInc =DMA_MemoryInc_Enable;//存儲器地址隨傳輸而遞增(加多少與數據寬度有關,可見芯片參考手冊,這里是地址自加1)DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//不循環傳輸模式(循環:地址遞增滿后,又重載從基地址開始傳輸)(不循環:遞增滿后不重載且暫停)DMA_InitStruct.DMA_PeripheralBaseAddr = PeripheralBaseAddr;//外設寄存器的基地址(多是數據寄存器)DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// DMA_PeripheralDataSize_HalfWord;//外設寄存器傳輸數據寬度8位(8,16,32位)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址不進行遞增DMA_InitStruct.DMA_Priority = DMA_Priority_High;//傳輸優先級:高(四種:最高,高,中,低)DMA_Init(DMAx_Channelx, &DMA_InitStruct); }
7.DMA啟動傳輸(用于每次傳輸開啟)
//DMA啟動傳輸
//傳入參數:通道? 數據量
void DMAx_Enable(DMA_Channel_TypeDef* DMAx_Channelx ,u16 DMA_BufferSize) {DMA_Cmd(DMAx_Channelx, DISABLE);//失能DMA_SetCurrDataCounter( DMAx_Channelx , DMA_BufferSize); //重新設置傳輸數據長度DMA_Cmd(DMAx_Channelx, ENABLE);//使能}
8.中斷配置函數
void NVIC_Config() {NVICInit(NVIC_PriorityGroup_2, DMA1_Channel1_IRQn , 0, 1); //組別2 搶占0 從占1DMA_ClearFlag(DMA1_FLAG_TC1);//清滿標志DMA_ClearITPendingBit(DMA1_IT_TC1); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);//開啟全部傳輸完成中斷 }9.RCC時鐘配置
void RCCInit() {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1 , ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC時鐘周期 6分頻 }
下面是上位機顯示傳輸的數據:
對于串口,一次只能輸出8位(一字節數),即使傳進去16位數,也被截取前半段 ADC采集為10為精度,數據存儲寬度要大于8位 所以:DMA的ADC傳輸需要16位,而USART傳輸只能8位傳輸 該例程的ADC為連續轉換模式,若是單次需要每次對通道重新配置一次 *DMA為循環模式只需要使能一次,否則非循環下需要重新使能 來啟動傳輸 每個DMA通道對應不同外設見手冊 DMA中斷配置必須放在DMA參數配置后面才能用 注意:等待判滿前,不能清除標志;注意:清除后,不能去等待判滿,否則死循環。
總結
- 上一篇: 开发相关手册、STM32各种库文件、相关
- 下一篇: 嵌入式开发板上常用术语