江科大學(xué)習(xí)筆記 _10.DMA



數(shù)據(jù)可以從存儲(chǔ)器到外設(shè),也可以從外設(shè)到存儲(chǔ)器
FLASH只讀,不可以SRAM到FLASH,或FLASH 到FLASH
從某個(gè)地址取內(nèi)容,再放到另一個(gè)地址
三個(gè)參數(shù):1.起始地址;2.數(shù)據(jù)寬度(字節(jié),半字,字);3.地址是否自增 ?
數(shù)據(jù)轉(zhuǎn)運(yùn)
如何將SRAM中的dataA數(shù)組轉(zhuǎn)移到dataB數(shù)組中?
?

設(shè)置三個(gè)參數(shù):1.起始地址;2.數(shù)據(jù)寬度(字節(jié),半字,字);3.地址是否自增
?
1.?起始地址:
外設(shè)地址:uint8_t ?dataA數(shù)組首地址 ?存儲(chǔ)器地址:uint8_t ?dataBase數(shù)組首地址;
?
2.?數(shù)據(jù)寬度(字節(jié),半字,字):字節(jié);
?
3.?地址是否自增 :自增
?
傳輸計(jì)數(shù)器:轉(zhuǎn)運(yùn)幾次? 根據(jù)數(shù)組里的數(shù)據(jù)個(gè)數(shù)來設(shè)置; sizeof(strlen(dataA)/sizeof(類型));
?
觸發(fā)選擇:軟件觸發(fā)
?
DMA_Cmd使能
?
?
DMA運(yùn)行的三大信號(hào):傳輸計(jì)數(shù)器大于0;有觸發(fā)信號(hào);DMA使能;
?
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB,uint32_t Size) ?
{
????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//1.開DMA時(shí)鐘 ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
????DMA_InitTypeDef DMA_InitStruct; ???? ? ?//2.配置DMA參數(shù) ???????????????????
????DMA_InitStruct.DMA_PeripheralBaseAddr = AddrA;//外設(shè)站點(diǎn)基地址
????DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//傳輸寬度
????DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//外設(shè)地址自增
????
????DMA_InitStruct.DMA_MemoryBaseAddr = AddrB;//存儲(chǔ)器站點(diǎn)基地址
????DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//傳輸寬度
????DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲(chǔ)器地址自增
????
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//傳輸方向,外設(shè)站點(diǎn)是源端還是目的地 ???
????DMA_InitStruct.DMA_BufferSize = Size;//傳輸計(jì)數(shù)器 傳輸數(shù)據(jù)的個(gè)數(shù)
????DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//轉(zhuǎn)運(yùn)完一次就停止 or 循環(huán)轉(zhuǎn)運(yùn)
????DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;//軟件觸發(fā)(1) or 硬件觸發(fā)(0)
????DMA_InitStruct.DMA_Priority =DMA_Priority_Medium;//通道軟件優(yōu)先級(jí)
????DMA_Init(DMA1_Channel1, &DMA_InitStruct);
?
?
}
?
?
?
ADC掃描加DMA
?

設(shè)置三個(gè)參數(shù):1.起始地址;2.數(shù)據(jù)寬度(字節(jié),半字,字);3.地址是否自增
?
起始地址:
外設(shè)地址:ADC_DR寄存器地址 存儲(chǔ)器地址:uint16_t ?ADValue地址;
?
數(shù)據(jù)寬度(字節(jié),半字,字):ADC_DR為uint16_t數(shù)組,寬半字;
?
地址是否自增 :外設(shè)地址不自增,存儲(chǔ)器地址自增
?
傳輸計(jì)數(shù)器:轉(zhuǎn)運(yùn)幾次? 通道有7個(gè),轉(zhuǎn)運(yùn)7次
?
觸發(fā)選擇:ADC硬件觸發(fā)
?
DMA_Cmd使能
?
?
?
uint16_t AD_Value[4];//DMA數(shù)據(jù)轉(zhuǎn)運(yùn)到這個(gè)數(shù)組里
?
void AD_Init(void)
{
????RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//開DMA時(shí)鐘 ?
????RCC_ADCCLKConfig(RCC_PCLK2_Div6);
????
????GPIO_InitTypeDef GPIO_InitStruct;
????GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入
????GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
????GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
????GPIO_Init(GPIOA, &GPIO_InitStruct);
????
????ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//開4個(gè)ADC通道
????ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
????ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
????ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);
????
????ADC_InitTypeDef ADC_InitStruct;
????ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; ??????????//是否是連續(xù)轉(zhuǎn)換模式
????ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ??????????//右對(duì)齊
????ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部觸發(fā)方式,不使用外部觸發(fā)
????ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; ???????????//單ADC
????ADC_InitStruct.ADC_NbrOfChannel = 4; ????????????//通道數(shù)目,僅在掃描模式下有用
????ADC_InitStruct.ADC_ScanConvMode = ENABLE; ??????????????//是否是連續(xù)掃描模式
????ADC_Init(ADC1, &ADC_InitStruct);
????
????//DMA配置開始?????????????????????????????????????????????????????????????????????????
????DMA_InitTypeDef DMA_InitStruct; ????????????????????????
????DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外設(shè)站點(diǎn)基地址 ADC數(shù)據(jù)寄存器
????DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//ADC數(shù)據(jù)寄存器寬度16位
????DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設(shè)地址不自增
????
????DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;//存儲(chǔ)器站點(diǎn)基地址
????DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//傳輸寬度
????DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲(chǔ)器地址自增
????
????DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//傳輸方向,外設(shè)站點(diǎn)是源端還是目的地 ???
????DMA_InitStruct.DMA_BufferSize = 4;//傳輸計(jì)數(shù)器 傳輸數(shù)據(jù)的個(gè)數(shù)
????DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//轉(zhuǎn)運(yùn)完一次就停止 or 循環(huán)轉(zhuǎn)運(yùn)
????DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//軟件觸發(fā)(1) or 硬件觸發(fā)(0)
????DMA_InitStruct.DMA_Priority =DMA_Priority_Medium;//通道軟件優(yōu)先級(jí)
????DMA_Init(DMA1_Channel1, &DMA_InitStruct);
????
????DMA_Cmd(DMA1_Channel1,ENABLE);//初始化后不開啟DMA
????//DMA配置結(jié)束
????ADC_DMACmd(ADC1,ENABLE);
????
????ADC_Cmd(ADC1, ENABLE);
????
????ADC_ResetCalibration(ADC1);//復(fù)位校準(zhǔn)
????while(ADC_GetResetCalibrationStatus(ADC1) == SET);//等待復(fù)位校準(zhǔn)完成
????ADC_StartCalibration(ADC1);//啟動(dòng)校準(zhǔn)
????while(ADC_GetCalibrationStatus(ADC1) == SET);//等待校準(zhǔn)完成
????
}
?
void AD_GetValue(void)
{
????DMA_Cmd(DMA1_Channel1,DISABLE);//改變傳輸計(jì)數(shù)器的值之前 需要失能DMA
????DMA_SetCurrDataCounter(DMA1_Channel1, 4);
????DMA_Cmd(DMA1_Channel1,ENABLE);
????
????ADC_SoftwareStartConvCmd(ADC1, ENABLE);
????
????while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待DMA傳輸完成 ???DMA1_FLAG_TC1完成標(biāo)志位
????DMA_ClearFlag(DMA1_FLAG_TC1);//清楚完成標(biāo)志位
}