DMA+ADC+TC требуется помощь знающих людей
- Войдите на сайт для отправки комментариев
Здравия желаю. Зарядил ацп на измерения пользовательской последовательности 15 каналов от таймера с периодом "Т". Хотелкой вызывать прерывания по готовности данных наткнулся в интернете на код АЦП с DMA, чуток поправил на свой лад.
Из даташита понял что:
1.Для одного периферийного модуля отводится несколько регистров - указателей (RPR, RNPR) и несколько регистров-счетчиков (RCR, RNCR).
2. Количество пересылок устанавливается внутренним 16-ти битным регистром счетчика пересылок.
3. Нарастающий фронт на DRDY запускает запрос на передачу данных
4.Счетчики автоматически декрементируются после каждой пересылки данных, а указатель памяти инкрементируется.
5.Программирование вторых регистров счетчиков/указателей позволяет организовать непрерывность буферов.
Т.е. получается готовность данных на одном из измерительных каналов запускает передачу данных, забивает элемент массива,декрементирует счетчик, инкрементирует адрес. Достижение счетчиком 0 (массив забит) выставляет флаг ENDRX и вызывает прерывание ацп с непонятным переходом ко второму регистру указателя приема. Непонятен переход от одного регистра к другому......
окончательно убила вот такая фраза из даташита "Но как только счетчик пересылок достигает нуля, значения 2-рых счетчиков/указателей загружаются в регистры счетчиков/указателей"
Поправте если я где то наврал и поясните по переходам от одних регистров к другим, код прилагаю.
#include <Streaming.h> int const NUM_CHANNELS=12; uint16_t global_ADCounts_Array[NUM_CHANNELS]; // holds the raw data from the analog to digital void setup_AtoD(){ // Arduino Due ADC->DMA // first modified by contravalent from code on the internet by "Stimmer" // fills the array global_ADCounts_Array in the background, with data from the ADC z pmc_enable_periph_clk(ID_ADC); //power management controller told to turn on adc ADC->ADC_CR |=1; //reset the adc ADC->ADC_MR= 0x90380f03; //this setting is used by arduino. ADC->ADC_CHER=0x3cff; // use channels A0 to A11 // ADC->ADC_SEQR1=0x01234567; // use A0 to A7 in order into array ADC->ADC_SEQR2=0x00dcba00; //use A8 to A11 following in order into array NVIC_EnableIRQ(ADC_IRQn); // interrupt controller set to enable adc. ADC->ADC_IER=(1<<27); // interrupt enable register, enables only ENDRX // following are the DMA controller registers for this peripheral // "receive buffer address" ADC->ADC_RPR=(uint32_t) global_ADCounts_Array; // УКАЗАЛИ АДРЕС ДЛЯ ДАННЫХ // "receive count" ADC->ADC_RCR=NUM_CHANNELS; // УКАЗАЛИ КОЛИЧЕСТВО ПЕРЕСЫЛОК // "next-buffer address" ADC->ADC_RNPR=(uint32_t)global_ADCounts_Array; // ??? // and "next count" ADC->ADC_RNCR=NUM_CHANNELS; // ??? // "transmit control register" ADC->ADC_PTCR=1; // Регистр управления передачи, разрешает запросы приемных пересылок, если не установлен флаг RXTDIS. // now that all things are set up, it is safe to start the ADC..... // сетапаем таймер REG_PMC_PCER0|=1<<27; REG_TC0_CMR0|=0xCC000; REG_TC0_RC0= 21000; REG_TC0_CCR0=5; } void ADC_Handler() { // for the ATOD: re-initialize DMA pointers and count int f=ADC->ADC_ISR; // read the interrupt status register if (f & (1<<27)){ /// check the bit "endrx" in the status register /// set up the "next pointer register" ADC->ADC_RNPR=(uint32_t) global_ADCounts_Array; // ??? // set up the "next count" ADC->ADC_RNCR=NUM_CHANNELS; // ??? REG_PIOB_ODSR^=1<<27; } } void setup(){ Serial.begin(115200); REG_PIOB_PER |= PIO_PER_P27; //ВКЛ 13 PIN REG_PIOB_OER |= PIO_PER_P27; //УСТАНОВИТЬ 13 PIN КАК ВЫХОД setup_AtoD(); } void loop() { unsigned int temp[NUM_CHANNELS]; for (int i = 0; i < NUM_CHANNELS; i++){ temp[i] = global_ADCounts_Array[i]&=0xFFF; //keep only data on buffer Serial << "temp " << i << " = " << temp[i] << endl; } Serial << endl; delay(500); }
Отдышитесь хоть немного.
Контроллер какой?
А чё там с этой фразой не так, регистры делятся на две группы - текущие (куда прям счас расписывается) и следующие ( как там заполнится, так все данные и адреса перепищутся и станут текущими). Двойная буферизация обзывается. Код по моему кривой, на раз, не видно чтоб следующие регистры записывались.
Реально волшебник....
arduino due) В начале кода в комментариях указано. Настолько проникся процессом что забыл в заголовок кинуть)
Как организуется этот переход? Автоматом или инициализировать нужно? Это мое первое знакомство с микроконтроллерами, по stm пытался аналогию найти как то не густо, с ADC и TC по проще получилось все (http://www.mwmw.ca/ - аналогичный МК). Интересен принцип конфигурации и работы DMA.
У Вас по сути вопроса что - то имеется ?
Как организуется этот переход? Автоматом или инициализировать нужно? Это мое первое знакомство с микроконтроллерами, по stm пытался аналогию найти как то не густо, с ADC и TC по проще получилось все (http://www.mwmw.ca/ - аналогичный МК). Интересен принцип конфигурации и работы DMA.
После долгого отсутствия вернулся к освоению DUE) Нашел довольно позновательную ссылку по обсуждаемой теме: http://forum.arduino.cc/index.php?topic=271381.0 . Пригодится в качестве помощи для начинающих.