Idler (01.05.2017 01:21 - 01:23, просмотров: 371) ответил Ксения на Спасибо за труды! У меня получилось вот что (кое-где отступила от рекомендаций):
Сразу включать DMA_CH_ENABLE_bm нельзя! Это должно быть последним действием после всех настроек. Для некоторых регистров в DS прямо указано, что запись в них работает только при выключенном ДМА (в смысле, именно этом бите). На сколько я понимаю, этим битом данные из регистров переписываются непосредственно во всякие триггера/счетчики/коммутаторы аппаратной части ДМА. Нужно ли сначала при настройке прописывать этот регистр без DMA_CH_ENABLE_bm, а в конце с ним, или достаточно только в конце, я не знаю. Во всех виданных мной примерах - 2 раза.
2. Можно, конечно, "=".
3. Если уж хочется прерывание, то его надо описать именно как прерывание. Чтобы компиллятор не просто сделал подпрограмму, но и вход в нее внес в таблицу прерываний, причем, куда надо, выход сделал через RETI, и вставил сохранение/восстановление регистра состояния.
4. Если мы используем 1 канал, то семпл мы получим за (Resol/2+1+Gain), т.е., при 12 битах и отключенном усилении за 7 тактов АЦП, что при 1МГц даст 7 мкс = 224 такта процессора. При 8 битах - 160 тактов. Если нужно усиление - все еще хуже. Fadc можно и 2МГц сделать, только ни при 1, ни, тем более, при 2 мы 12бит не получим.
Если ХМега из новых (с USB), то в ней очень хорошо сделана и реально работает конвееризация каналов АЦП. То есть включаем все 4 канала с одного и того же входа, настраиваем ДМА забирать все 4 канала бурстом по концу 3 канала, и имеем скорость до 2 мегасемплов при 8 битах или до 0.5 но полные 12 бит. Там, правда, есть свои хитрости при настройке АЦП, но сделать можно.
В старых ХМегах АЦП был гораздо хуже и тупее.
5. Собственно, в регистре DMA_INTFLAGS должен стоять DMA_CH0TRNIF_bm. И, естественно, перед новым запуском ДМА его нужно сбросить записью туда '1'.
6. Пока ДМА работает, можно прочитать TRFCNT, он декрементируется после каждого принятого из АЦП байта. Или DESTADDRn - он, соответственно, инкрементируется после каждого байта, положенного в память. После остановки они сами перезапишутся тем, что в них писали.
То есть, читаем DMA_CH0TRNIF_bm в DMA_INTFLAGS, если он =0, читаем TRFCNT или DESTADDR, и еще раз проверяем DMA_CH0TRNIF. Если он все еще =0, то прочитанные из счетчика данные - валидные, и мы знаем, где находимся. А если уже =1, то тем более знаем, и счетчик нам нахрен не нужен...