我在 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 的指导和参考手册