|
楼主 |
发表于 2015-4-11 17:41:50
|
显示全部楼层
經過一些摸索後,以下是目前改出來的程式碼。[s:123]
使用ADC1, ADC2對PA5, PA7進行取樣。
MCU是429。
Clock為180MHz,ADC Clock為APB2的一半,45MHz。
就給ADC小小的超頻,跑在45MHz。
3 cycles 取樣,12 cycles轉換 ==> 45M / 15 ==> 3MSPS
因為同時對PA5, PA7取樣,所以設定方式為
ADC1 ==> PA5, PA7
ADC2 ==> PA7, PA5
用3MSPS取樣的結果來看,8KHz方波,看來效果不錯。
目前用示波器確認過訊號是8KHz。
怎麼知道取樣率是3MSPS?
因為一個週期有375樣本點,所以一秒鐘8K個週期,總共有8K * 375 ==> 3MSPS
看來Noise有點大,需要想點辦法做一些濾波處理了。
可以看以下的pdf檔案
waveform.pdf
(46 KB, 下载次数: 105)
以下是程式碼:
void DMA2_Stream0_IRQHandler(void);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void ADC_Configuration(void);
void DMA_Configuration(void);
void NVIC_Configuration(void);
void ADC_Buffer_Init(void);
void ADC_Buffer_Copy(void);
void ADC_Buffer_Dump(void);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f4xx_adc.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "misc.h"
#include "adc_dma.h"
#define ADC_BUFFER_LEN 4096
#define ADC_CDR_ADDRESS 0x40012308
volatile unsigned int dma_counts = 0;
volatile unsigned int dma_status = 0;
#define ADC_LEN (ADC_BUFFER_LEN << 1)
#define CH1_LEN (ADC_BUFFER_LEN)
#define CH2_LEN (ADC_BUFFER_LEN)
volatile unsigned short adc_buffer[ADC_LEN];
volatile unsigned short ch1_buffer[CH1_LEN];
volatile unsigned short ch2_buffer[CH2_LEN];
void ADC_Buffer_Init() {
dma_counts = 0;
dma_status = 0;
memset(adc_buffer, 0xFF, sizeof(unsigned short) * ADC_LEN);
memset(ch1_buffer, 0xFF, sizeof(unsigned short) * CH1_LEN);
memset(ch2_buffer, 0xFF, sizeof(unsigned short) * CH2_LEN);
}
void RCC_Configuration(void) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
}
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void DMA_Configuration(void) {
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned int)&adc_buffer;
DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)ADC_CDR_ADDRESS;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = ADC_LEN;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
// Enable DMA Stream Half / Transfer Complete interrupt
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
// DMA2_Stream0 enable
DMA_Cmd(DMA2_Stream0, ENABLE);
}
void ADC_Configuration(void) {
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
// ADC Common Initialization
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; // ADC 1 then 2
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_18Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // Ignored
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
// ADC1 regular channel 5, 7 configuration
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_3Cycles); // PA5 (3 or 15 cycles, less than 18-2)
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_3Cycles); // PA7 (3 or 15 cycles, less than 18-2)
// ADC2 regular channel 7, 5 configuration
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 1, ADC_SampleTime_3Cycles); // PA7 (3 or 15 cycles, less than 18-2)
ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 2, ADC_SampleTime_3Cycles); // PA5 (3 or 15 cycles, less than 18-2)
// Enable DMA request after last transfer (Multi-ADC mode)
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
// Enable ADC1 DMA
ADC_DMACmd(ADC1, ENABLE);
// Enable ADC1
ADC_Cmd(ADC1, ENABLE);
// Enable ADC2
ADC_Cmd(ADC2, ENABLE);
}
void NVIC_Configuration(void) {
NVIC_InitTypeDef NVIC_InitStructure;
// Enable the DMA Stream IRQ Channel
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DMA2_Stream0_IRQHandler(void) {
if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0)) {
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
GPIOG->ODR ^= GPIO_Pin_14;
}
if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) {
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
GPIOG->ODR ^= GPIO_Pin_13;
dma_counts++;
if(dma_status == 1) {
ADC_Buffer_Copy();
dma_status = 0;
}
}
}
void ADC_Buffer_Copy(void) {
int i = 0;
int j = 0;
for(i = 0, j = 0; j < CH1_LEN; i += 4, j += 2) {
ch1_buffer[j + 0] = adc_buffer[i + 0];
ch2_buffer[j + 0] = adc_buffer[i + 1];
ch2_buffer[j + 1] = adc_buffer[i + 2];
ch1_buffer[j + 1] = adc_buffer[i + 3];
}
}
void ADC_Buffer_Dump(void) {
int i = 0;
printf("rn ch1 ch2 start........rn");
for(i = 0; i < CH1_LEN; i++) printf("[%3d] %4d %4drn", i, ch1_buffer, ch2_buffer);
printf("rn ch1 ch2 end........rn");
} |
|