0

我在 Arduino Portenta H7 上使用 H747。我正在尝试一起实现 ADC 和 DMA。ADC 应以连续模式运行并扫描 2 个通道。

void ADC_Init (void){
/******Enable ADC Voltage regulator******/
ADC1->CR&= ~(1<<29); //DEEPPWD set to zero to set adc not deep power down
ADC1->CR|= ADC_CR_ADVREGEN; //Turn on voltage regulator ADC |=(1<<28)
digitalWrite(LEDR,LOW);
//while (!(ADC1->ISR & (1<<12)));  //LDORDY: ADC LDO output voltage ready bit

/******Enable ADC CLOCK******/
RCC->AHB1ENR|=(1<<5);//ADC peripheral clock enable
//RCC->D3CCIPR&= ~(7<<16)// ADCSEL[1:0]: SAR ADC kernel clock source selection default
ADC1->CR|=(3<<8);


/******Set the prescalar******/
ADC12_COMMON->CCR &= ~(15<<18);// PRESC[3:0]: ADC prescaler 0000: input ADC clock not divided
ADC12_COMMON->CCR &= ~(3<<16);// CKMODE[3:0]: ADC clock mode


/******Set Scan Mode Data Management and resolution******/
ADC1->CFGR|=(6<<2);  //RES[2:0]: Data resolution 110=12bits
ADC1->CFGR|=(3<<0);  //DMNGT[1:0]: Data Management configuration 11: DMA Circular Mode selected

//ADC regular sequence register 1
ADC1->SQR1|=(1<<0);  // L[3:0]: Regular channel sequence length 1=2 conversions
ADC1->SQR1&= ~(0<<6);// SQ1[4:0]: 1st conversion in regular sequence channel number =0
ADC1->SQR1&= ~(1<<12);// SQ1[4:0]: 2st conversion in regular sequence channel number =1


/******Set the Continuous Conversion, ******/
ADC1->CFGR|=(1<<13);  //CONT: Single / continuous conversion mode for regular conversions

/******Set the Sampling Time for the channels in ADC_SMPRx******/
ADC1->SMPR1&= ~(7<<0);//SMP0[2:0]: Channel 0 sampling time selection 000: 1.5 ADC clock cycles
ADC1->SMPR1&= ~(7<<3);//SMP1[2:0]: Channel 1 sampling time selection 000: 1.5 ADC clock cycles
ADC1->PCSEL|= (1<<0);//PCSEL[19:0] :Channel 0 (VINP[i]) pre selection 
ADC1->PCSEL|= (1<<1);//PCSEL[19:0] :Channel 1 (VINP[i]) pre selection 

/******Set singleEnded Input******/
ADC1->DIFSEL&= ~(1<<0); //DIFSEL[19:0]: Differential mode for channels 19 to 0
ADC1->DIFSEL&= ~(1<<1); //DIFSEL[19:0]: Differential mode for channels 19 to 0


/******Enable ADC******/
ADC1->ISR|=(1<<0); // Reset ADC ready flag
ADC1->CR|= ADC_CR_ADEN; //Enable ADC
while (!(ADC1->ISR & (1<<0)));  //Wait for ready flag
ADC1->ISR|=(1<<0);}

DMA 应该捕获来自 adc 的输出并将它们移动到内存中

void DMA_Init (void){
    RCC->AHB1ENR |= (1<<0);
    DMA1_Stream0->CR &= ~(0x1 << 0);
    while (DMA1_Stream0->CR & 0x1);
 
    DMA1_Stream0->CR |= (0x3 << 16);
    DMA1_Stream0->CR &= ~(3<<6);  //Bits 7:6 DIR[1:0]: data transfer direction
    DMA1_Stream0->CR |= (1<<8);  //CIRC: circular mode
    DMA1_Stream0->CR |= (1<<10);  // MINC = 1;
    DMA1_Stream0->CR |= (1<<11)|(1<<13);  // MSIZE[1:0]: memory data size PSIZE[1:0]: peripheral data size
    DMA1_Stream0->CR &= ~(7<<25);  // Channel 0 selected
    DMAMUX1_Channel0->CCR |=(9<<0);
    DMA1_Stream0->CR |= (0x1 << 4);
    DMA1_Stream0->CR |= (0x1 << 3);
    NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
void DMA_Config (uint32_t srcAdd, uint32_t destAdd, uint16_t s){
     
  DMA1_Stream0->NDTR = s;   // Set the size of the transfer
  DMA1_Stream0->PAR = srcAdd;  // Source address is peripheral address
  DMA1_Stream0->M0AR = destAdd;  // Destination Address is memory address
  // Enable the DMA Stream
  DMA1_Stream0->CR |= (1<<0);  // EN =1
}

运行代码时,它卡在 ADCStart() 的 ADC1->CR|= ADC_CR_ADON;

void setup() {
  SystemClock_Config();
  ADC_Init();
  DMA_Init();
  DMA_Config ((uint32_t ) &ADC1->DR, (uint32_t) RxData, 3);
  ADC_start();
  digitalWrite(LEDB,LOW);
  Serial.begin(9600); //for debuging
}
void ADC_start (void){
    while ((ADC1->CR & (1<<1)));
    ADC1->CR|= ADC_CR_ADON;
}

我的程序错了吗?

  • 配置ADC
  • 配置 dma
  • 启动ADC

我还是 stm32 的新手,所以我使用https://controllerstech.com/dma-with-adc-using-registers-in-stm32/作为 stm32h7 的指导和参考手册

4

0 回答 0