Срок: Запись на цифровой вывод во время работы АЦП
У меня возникла проблема с записью на цифровой вывод Arduino Due во время работы АЦП.
У меня есть следующий код:
#undef HID_ENABLED
// Arduino Due ADC->DMA->USB 1MSPS
// от стимера
// из http://forum.arduino.cc/index.php?topic=137635.msg1136315#msg1136315
// Вход: Аналоговый в A0
// Вывод: Необработанный поток uint16_t в диапазоне 0-4095 на собственном USB Serial/ACM
// в Linux, чтобы остановить обработку данных ОС:
// stty -F /dev/ttyACM0 raw -iexten -echo -echo -echok -echoctl -echoke -onlcr
// источник: https://gist.github.com/pklaus/5921022
// применен патч 1 из: http://forum.arduino.cc/index.php?topic=137635.msg2526475#msg2526475
// применен патч 2 из: https://gist.github.com/pklaus/5921022 комментарий от 2 апреля 2017 г. от borisbarbour
volatile int bufn,obufn;
uint16_t buf[4][256]; // 4 буфера по 256 показаний
void ADC_Handler(){ // переместить указатели DMA в следующий буфер
int f=ADC->ADC_ISR;
if (f&(1<<27)){
bufn=(bufn+1)&3;
// запуск патча 2
//ADC->ADC_RNPR=(uint32_t)buf[bufn];
ADC->ADC_RNPR=(uint32_t)buf[(bufn+1)&3];
// патч 2 конец
ADC->ADC_RNCR=256;
}
}
void setup() {
SerialUSB.begin(0);
while(!SerialUSB);
pmc_enable_periph_clk(ID_ADC);
adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
ADC->ADC_MR |=0x80; // свободный ход
ADC->ADC_CHER=0x80;
NVIC_EnableIRQ(ADC_IRQn);
ADC->ADC_IDR=~(1<<27);
ADC->ADC_IER=1<<27;
ADC->ADC_RPR=(uint32_t)buf[0]; // буфер DMA
ADC->ADC_RCR=256;
ADC->ADC_RNPR=(uint32_t)buf[1]; // следующий буфер DMA
ADC->ADC_RNCR=256;
// патч 1.2 старт
//bufn=obufn=1;
bufn=1;
obufn=0;
// патч 1.2 конец
ADC->ADC_PTCR=1;
ADC->ADC_CR=2;
// это не работает:
pinMode(52, OUTPUT); //
digitalWrite(52, HIGH); //
}
void loop(){
// патч 1.1 старт
while((obufn + 1)%4==bufn);// ждем заполнения буфера
// патч 1.1 конец
SerialUSB.write((uint8_t *)buf[obufn],512); // отправляем - 512 байт = 256 uint16_t
obufn=(obufn+1)&3;
}
Контакт 52 показывает 0 В.
С помощью этой функции я могу поднять цифровое выходное напряжение до 1,58 В:
void digitalWriteDirect(int pin, boolean val){
if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}
Есть идеи?
@aJazz, 👍0
1 ответ
Лучший ответ:
▲ 0
Я нашел проблему: Arduino ждал соединения SerialUSB
.
Последовательное соединение не было установлено, потому что я запустил Arduino без запуска соответствующего скрипта Python. Этот скрипт открыл бы последовательное соединение.
При запуске скрипта Python Arduino Due работает так, как и ожидалось.
,
@aJazz
Смотрите также:
- Постоянный выход тактовой частоты Arduino
- Расширение аналоговых входов для Arduino
- ESP8266: system_adc_read_fast() всегда возвращает 1024
- Высокоскоростной внешний АЦП
- Измерение напряжения литий-ионного элемента, используемого для питания Arduino через повышающий модуль
- Шумный analogRead
- Расширенная настройка АЦП на Due (SAM3X8E) для повышения точности
- Arduino/ESP8266 нет данных SPI, поступающих от MCP3008