Я только что получил свой стартовый комплект PIC32 и поиграл с демонстрационными версиями. Я никогда не использовал более совершенные uC, чем 8-битные PIC.
Одной из новых вещей в PIC32 для меня является DMA. Стартовый комплект поставляется с демонстрацией, в которой используются цепные передачи DMA для управления ШИМ и затемнения двух светодиодов.
Пробовал экспериментировать с добавлением третьего вывода в цепочку, но не вышло. Я считаю, что это потому, что я не знаю, как связать три канала прямого доступа к памяти.
В основном я пытаюсь получить цепочку: DMACh0 -> DMACh1 -> DMAch2 -> DMACh0 -> ...
Вот одна из модифицированных версий (некоторые стандартные комментарии и конфиг вырезаны, чтобы уменьшить размер):
const unsigned short pwm_duty_cycles[] = {...};
#define ARRAY_SIZE (sizeof(pwm_duty_cycles))
#define DMA0 (0)
#define DMA1 (1)
#define DMA2 (2) // Added this line
unsigned char srcSize = ARRAY_SIZE;
unsigned char cellSize = 2;
unsigned int dstSize = 2;
unsigned short* volatile pDma_0_Dst = (void*) &OC1RS;
unsigned short* volatile pDma_1_Dst = (void*) &OC2RS;
unsigned short* volatile pDma_2_Dst = (void*) &OC3RS; // Also added this
const unsigned short* pDmaSrc = pwm_duty_cycles;
#define SYS_FREQ (80000000)
#define PWM_PERIOD (25000)
// pwm_dma application code
int main(void)
{
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
DmaChnOpen(DMA0, 0, DMA_OPEN_CHAIN_LOW);
DmaChnOpen(DMA1, 0, DMA_OPEN_CHAIN_HI);
DmaChnOpen(DMA2, 0, DMA_OPEN_CHAIN_HI); // Added this line, I'm not sure how to set up the
// chaining. What should be LOW and what should be HIGH
DmaChnSetEventControl(DMA0, DMA_EV_START_IRQ(_TIMER_4_IRQ));
DmaChnSetEventControl(DMA1, DMA_EV_START_IRQ(_TIMER_4_IRQ));
DmaChnSetEventControl(DMA1, DMA_EV_START_IRQ(_TIMER_4_IRQ)); // Added
DmaChnSetTxfer(DMA0, pDmaSrc, pDma_0_Dst, srcSize, dstSize, cellSize);
DmaChnSetTxfer(DMA1, pDmaSrc, pDma_1_Dst, srcSize, dstSize, cellSize);
DmaChnSetTxfer(DMA2, pDmaSrc, pDma_2_Dst, srcSize, dstSize, cellSize); // Added
OpenOC1(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0);
OpenOC2(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0);
OpenOC3(OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0,0); // Added
OpenTimer3(T3_ON | T3_PS_1_64, PWM_PERIOD);
OpenTimer4(T4_ON | T4_PS_1_256, 100000);
DmaChnEnable(DMA0);
while(1);
}
Я думаю, проблема в настройке DMA_OPEN_CHAIN_LOW и DMA_OPEN_CHAIN_HI. Я предполагаю, что эти HI и LOW означают приоритеты канала. Они только позволяют мне указать следующий канал с более высоким или более низким приоритетом. Как я могу перепрыгнуть через канал (ch2 -> ch0)?
Я использую Mplab C32 v2.02. Это вызывает воспоминания, пытаясь изменить примеры, чтобы получить еще одно мигание светодиода :)
Причина объясняется в справочном руководстве по контроллеру DMA PIC32MX (стр. 31-35):
Канал (ведомый канал) может быть связан с соседним каналом (главным каналом).
Это означает, что вы не можете связать вместе 3 канала DMA.
Но чтобы ответить на ваш вопрос о том, как работает эта цепочка, посмотрите на стр. 31-16 в руководстве:
CHCHNS: бит выбора канала цепочки (5)
1 = Привязка к каналу с более низким естественным приоритетом (канал 1 будет включен после завершения передачи канала 2)
0 = Привязка к каналу с более высоким естественным приоритетом (канал 1 будет включен после завершения передачи канала 0)
Канал 0 имеет самый высокий приоритет, а канал 3 — самый низкий (у Pic32MX360F512L 4 канала). Таким образом, установка первого канала DMA в цепочку в более низком порядке означает, что он запускается каналом 1 (в вашем примере).
Тони Стюарт EE75
вареза