Ну вот опять пошла религия

...
Пропустить амперсанд можно как в команде
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
так и в команде
DMA2_Stream0->PAR = (uint32_t)&(ADC1->DR);
А неправильное значение Вы хоть сразу в регистр впишите, хоть ещё через десяток структур и пяток функций прогоните, ничего не изменится.
Поверьте мне, как программисту с почти 15-летним стажем. И не только на МК...
И ещё немного оффтопа:
Я видел на разных форумах немало "простыней" типа этой:
CODE
/* Peripheral clock enable */
RCC->AHB1ENR |= (1<<4); // GPIOE clock enable
RCC->AHB1ENR |= (1<<3); // GPIOD clock enable
RCC->AHB1ENR |= (1<<2); // GPIOC clock enable
RCC->AHB1ENR |= (1<<1); // GPIOB clock enable
RCC->AHB1ENR |= (1<<0); // GPIOA clock enable
RCC->APB1ENR |= (1<<18); // USART3 clock enable
RCC->APB1ENR |= (1<<15); // SPI3 clock enable
RCC->APB1ENR |= (1<<14); // SPI2 clock enable
RCC->APB2ENR |= (1<<12); // SPI1 clock enable
RCC->AHB1ENR |= (1<<21); // DMA1 clock enable
RCC->APB1ENR |= (1<<4); // TIM6 clock enable
RCC->APB1ENR |= (1<<5); // TIM7 clock enable
RCC->APB2ENR |= (1<<1); // TIM8 clock enable
RCC->AHB2ENR |= (1<<6); // RNG clock enable
RCC->APB1ENR |= (1<<29); // DAC interface clock enable
RCC->APB2ENR |= (1<<14); // SYSCFGEN clock enable
RCC->APB2ENR |= (1<<8); // ADC1 clock enable
RCC->APB1ENR |= (1<<21); // I2C1 clock enable
RCC->AHB1ENR |= (1<<18); // SRAM backup enable
RCC->APB1ENR |= (1<<28); // POWER enable
RCC->AHB2ENR |= (1<<7); // USB OTG_FS clock enable
/* Set I/O mode for GPIOA */
GPIOA->MODER = 0x6AAAAA54; // PORT A OUT PA14 - PA4 AF PA0 digital input for USER BUTTON
GPIOA->OSPEEDR = 0xABFFAAAA; // 50 MHz all and PA12 - PA8 100 MHz speed
GPIOA->PUPDR = 0x24000100; // pull-up PA13 PA4 pull-down PA14
GPIOA->AFR[1] |= (0xA<<16); // PA12 how to alternative function AF10 USB_OTG_FS_DP
GPIOA->AFR[1] |= (0xA<<12); // PA11 how to alternative function AF10 USB_OTG_FS_DM
GPIOA->AFR[1] |= (0xA<<8); // PA10 how to alternative function AF10 USB_OTG_FS_ID
GPIOA->AFR[1] |= (0xA<<4); // PA9 how to alternative function AF10 USB_OTG_FS_VBUS
GPIOA->AFR[1] |= (0xA<<0); // PA8 how to alternative function AF10 USB_OTG_FS_SOF
GPIOA->AFR[0] |= (0x5<<28); // PA7 how to alternative function AF5 SPI1_MOSI
GPIOA->AFR[0] |= (0x5<<24); // PA6 how to alternative function AF5 SPI1_MISO
GPIOA->AFR[0] |= (0x5<<20); // PA5 how to alternative function AF5 SPI1_SCK
GPIOA->AFR[0] |= (0x5<<16); // PA4 how to alternative function AF5 SPI1_NSS
/* PA0 configuration interrupt input set */
EXTI->IMR |= (1<<0); // MR0 interrupt request from line 0 is not masked
EXTI->RTSR |= (1<<0); // TR0 rising trigger enabled for input line
SYSCFG->EXTICR[0] &= ~(0xF<<0); // EXTI0 PA pins set
NVIC_SetPriority(EXTI0_IRQn, 0); // PA0 priority set 0
NVIC_EnableIRQ(EXTI0_IRQn); // EXTI0 interrupt enable
/* Set I/O mode for GPIOB */
GPIOB->MODER = 0x55696555; // port B OUT PB10 AF
GPIOB->OSPEEDR = 0xAAAAAAAA; // 50 MHz speed
GPIOB->OTYPER |= (1<<9); // PB9 open-drain
GPIOB->OTYPER |= (1<<6); // PB6 open-drain
GPIOB->PUPDR = 0x00000000; // no pull-up or pull-down
GPIOB->AFR[1] |= (0x5<<8); // PB10 how to alternative function AF5 I2S2_CK
GPIOB->AFR[1] |= (0x4<<4); // PB9 how to alternative function AF4 I2C1_SDA
GPIOB->AFR[0] |= (0x4<<24); // PB6 how to alternative function AF4 I2C1_SCL
/* Set I/O mode for GPIOC */
GPIOC->MODER = 0x5669AD94; // port C OUT PC12 PC10 PC9 PC7 PC6 and PC3 AF PC5 analog mode ADC1 IN15 PC0 digital input
GPIOC->OSPEEDR = 0xAAAAAAAA; // 50 MHz speed
GPIOC->PUPDR = 0x00000080; // pull-down PC3
GPIOC->AFR[1] |= (0x6<<16); // PC12 how to alternative function AF6 I2S3_SD
GPIOC->AFR[1] |= (0x6<<8); // PC10 how to alternative function AF6 I2S3_CK
GPIOC->AFR[0] |= (0x6<<28); // PC7 how to alternative function AF6 I2S3_MCK
GPIOC->AFR[1] &= ~(0xF<<0); // PC9 how to alternative function AF0 MCO_2
GPIOC->AFR[0] |= (0x3<<24); // PC6 how to alternative function AF3 TIMER_8
GPIOC->AFR[0] |= (0x5<<12); // PC3 how to alternative function AF5 I2S2_SD
/* Set I/O mode for GPIOD */
GPIOD->MODER = 0x555A5155; // port D OUT PD5 digital input PD8 PD9 AF
GPIOD->OSPEEDR = 0xAAAAAAAA; // speed 50 MHz
GPIOD->PUPDR = 0x00040000; // pull-up PD9 USART3_RX
GPIOD->AFR[1] |= (0x7<<4); // PD9 how to alternative function AF7 USART3_RX
GPIOD->AFR[1] |= (0x7<<0); // PD8 how to alternative function AF7 USART3_TX
GPIOD->BSRRL |= (1<<4); // PD4 set 1 for RESET OFF EXTERNAL AUDIO DAC
/* Set I/O mode for GPIOE */
GPIOE->MODER = 0x55555550; // port E OUT PE0 and PE1 digital input from ACCELEROMETER
GPIOE->OTYPER = 0x00000008; // PE3 open-drain output type
GPIOE->OSPEEDR = 0xAAAAAAAA; // speed 50 MHz
GPIOE->PUPDR = 0x00000000; // no pull-down or pull-up
GPIOE->BSRRL |= (1<<3); // PE3 set 1
/* PE1 configuration interrupt input set */
EXTI->IMR |= (1<<1); // MR1 interrupt request from line 1 is not masked
EXTI->RTSR |= (1<<1); // TR1 rising trigger enabled for input line 1
EXTI->FTSR |= (1<<1); // TR1 failing trigger enabled for input line 1
SYSCFG->EXTICR[0] |= (0x4<<4); // EXTI1 PE pins set
NVIC_SetPriority(EXTI1_IRQn, 1); // PE1 priority set 1
NVIC_EnableIRQ(EXTI1_IRQn); // EXTI1 interrupt enable
/* USART3 configuration set*/
USART3->BRR |= 0x00000030; // USART3 speed 2 Mb/c set dev 3
USART3->CR1 |= (1<<15); // Oversampling by 8 set
USART3->CR1 &= ~(1<<12); // Word length 8 bit set
USART3->CR1 &= ~(1<<10); // Parity control disable
USART3->CR1 &= ~(1<<8); // Parity interrupt disable
USART3->CR1 &= ~(1<<7); // Transmit data register empty interrupt disable
USART3->CR1 &= ~(1<<6); // Transmission complete interrupt disable
USART3->CR1 |= (1<<5); // Read data register interrupt enable
USART3->CR1 |= (1<<3); // TX set On
USART3->CR1 |= (1<<2); // RX set On
USART3->CR1 &= ~(1<<1); // Receiver set in active mode
USART3->CR2 &= ~(0x3<<12); // Set 1 stop bit
USART3->CR3 &= ~(1<<11); // 3 sample bit method set
USART3->CR3 &= ~(1<<7); // DMA transmitter disable
USART3->CR3 &= ~(1<<6); // DMA receiver disable
USART3->CR1 |= (1<<13); // USART3 On
NVIC_SetPriority(USART3_IRQn, 2); // USART3 priority set 2
NVIC_EnableIRQ(USART3_IRQn); // USART3 interrupt enable
/* Timer8 PWM PC6 configuration set */
TIM8->CR1 |= (1<<7); // Timer 8 TIM8 ARR register is buffered set
TIM8->PSC = 0xFDE7; // Timer 8 prescaler configuration set 65000 - 1
TIM8->ARR = 0x0171; // Timer 8 auto-reload value before 1 c
TIM8->CCR1 = 0x00B8; // Timer 8 capture compare register 500 mc set 1
TIM8->CCMR1 = 0x0068; // Timer 8 PWM output mode set
TIM8->CCER &= ~(1<<1); // Timer 8 OC1 active high output polarity
TIM8->CCER |= (1<<0); // Timer 8 OC1 signal On
TIM8->BDTR |= (1<<15); // Timer 8 MOE main output enable
TIM8->CR1 |= (1<<0); // Timer 8 On
/* ADC1 IN15 configuration set */
ADC1->CR1 |= (1<<26); // ADC1 overrun interrupt enabled
ADC1->CR1 &= ~(0x3<<24); // ADC1 resolution 12-bit 15 ADCCLK cycles
ADC1->CR1 |= (1<<23); // ADC1 analog watchdog enabled on regular channels
ADC1->CR1 &= ~(1<<22); // ADC1 analog watchdog disabled on injected channels
ADC1->CR1 &= ~(0x7<<13); // ADC1 discontinuous mode channel count 1 channel
ADC1->CR1 &= ~(1<<12); // ADC1 discontinuous mode on injected channels disabled
ADC1->CR1 &= ~(1<<11); // ADC1 discontinuous mode on regular channels disabled
ADC1->CR1 &= ~(1<<10); // ADC1 automatic injected group conversion disabled
ADC1->CR1 |= (1<<9); // ADC1 analog watchdog enabled on one channel
ADC1->CR1 &= ~(1<<8); // ADC1 scan mode disabled
ADC1->CR1 &= ~(1<<7); // ADC1 interrupt disable for injected channels
ADC1->CR1 |= (1<<6); // ADC1 analog watchdog interrupt enabled
ADC1->CR1 |= (1<<5); // ADC1 EOC interrupt enabled
ADC1->CR1 |= (0xF<<0); // ADC1 analog watchdog input channel 15
ADC1->CR2 &= ~(0x3<<28); // ADC1 external trigger detection disabled for regular channels
ADC1->CR2 &= ~(0xF<<24); // ADC1 external event select for regular group timer 1 CC1 event
ADC1->CR2 &= ~(0x3<<20); // ADC1 external trigger detection disabled for injected channels
ADC1->CR2 &= ~(0xF<<16); // ADC1 external event select for regular group timer 1 CC4 event
ADC1->CR2 &= ~(1<<11); // ADC1 data alignment right set
ADC1->CR2 |= (1<<10); // ADC1 EOC bit is set at the end of each regular conversion overrun detection is enabled
ADC1->CR2 &= ~(1<<9); // ADC1 no new DMA request is issued after the last transfer
ADC1->CR2 &= ~(1<<8); // ADC1 DMA mode disabled
ADC1->CR2 &= ~(1<<1); // ADC1 single conversion mode set
ADC1->SMPR1 = 0x00000000; // ADC1 channels 18 - 10 sampling time selection 3 cycles
ADC1->SMPR2 = 0x00000000; // ADC1 channels 9 - 0 sampling time selection 3 cycles
ADC1->HTR = 0x00000100; // ADC1 analog watchdog higher threshold 0x100
ADC1->LTR = 0x00000000; // ADC1 analog watchdog lower threshold 0x000
ADC1->SQR1 &= ~(0xF<<20); // ADC1 regular channel sequence length 1 conversion
ADC1->SQR3 |= (0xF<<0); // ADC1 1st conversion in regular sequence channel 15
ADC1->JSQR = 0x00000000; // ADC1 injected sequence register set
ADC->CCR &= ~(1<<23); // ADC1 temperature sensor and Vref INT channel disabled
ADC->CCR &= ~(1<<22); // ADC1 Vbat channel disabled
ADC->CCR |= (0x2<<16); // ADC1 prescaler PCLK2 divided by 6 speed equal 2 MHz
ADC->CCR &= ~(0x3<<14); // ADC1 DMA mode disabled
ADC->CCR &= ~(1<<13); // ADC1 DMA disable selection for multi-ADC mode
ADC->CCR &= ~(0xF<<8); // ADC1 delay between 2 sampling phases 5*TADCCLK
ADC->CCR &= ~(0x1F<<0); // ADC1 multi ADC mode selection 'independent mode'
ADC1->CR2 |= (1<<0); // ADC1 On
NVIC_SetPriority(ADC_IRQn, 7); // ADC1 IN15 priority set 7
NVIC_EnableIRQ(ADC_IRQn); // ADC1 IN15 interrupt enable
Лично мне этот стиль не нравится. Здесь хоть комментарии есть

. А некоторым "спецам" вообще писать их облом. В итоге, чтобы понять как что делается, надо полдня посидеть глядя одним глазом в эту простыню, а другим в RefMan. А если надо перенести код с проца на проц - вообще мрак .... Приходилось.
Такой способ я поддержу в одном единственном случае - только если я буду на 100% уверен, что в стандартных библиотеках в каком-то месте имеет место ошибка или нестабильность.
Справедливости ради отмечу, что RTC на этом проце у меня не заработал со стандартной библиотекой, а с манипуляциями регистрами заработал. Но подобные разовые случаи не повод повсеместно и навсегда отказываться от библиотек.
Это ж не AVR, где таймер в большинстве случаев программируется через 2-3 простеньких регистра и т.п. ...
Извините, если обидел. Не выдержал...
По делу.
Прикладываю полный вариант библиотеки ADC_DMA_Timer. Методов для задания частоты таймера (дискретизации) нету, всё наглухо вшито в инициализацию, но это разделить не проблема.
Кому надо, берите.
Компилятор - IAR.
Пример использования:
Код
#include "Adc.h"
...............
// Данные АЦП
extern uint16_t adcBuffer[4096];
// Флаг готовности данных
extern bool isDataReady;
.......................
uint32_t adcVal;
.......................
if (isDataReady)
{
isDataReady = false;
adcVal = 0;
for ( i = 0; i < 4096; i ++ )
adcVal += adcBuffer [ i ];
adcVal /= 4096;
sprintf ( sBuffer, "ADCVal = %05lu", adcVal );
DrawString ( sBuffer, 10, 70, 0xFFE0, 0x0000, 1 );
} // if
...........................
PS. Если у кого будут замечания, буду рад услышать.
АЦП пока цифрует только один канал, вообще в планах сделать одновременный опрос разных каналов 2-х АЦП (а-ля 2-х канальный осциллограф), есть наброски примитивного кода для этого, оно вроде работает, но до конца я не дотестировал.
Сделаю, выложу.
Прикрепленные файлы
Adc.zip ( 2.18 килобайт )
Кол-во скачиваний: 33
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда