СОВРЕМЕННАЯ ЭЛЕКТРОНИКА №4/2015
ЭЛЕМЕНТЫ И КОМПОНЕНТЫ 42 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 4 2015 Данную процедуру можно разделить на три части: ● настройка режима связи с перифе- рийным устройством; ● настройка режима связи с памятью; ● настройка канала в целом. Настройка режима связи с перифе- рийным устройством подобна настрой- ке режима связи с памятью. Необходи- мо задать размерность данных и акти- вировать инкремент указателя. Размерность данных может состав- лять 8, 16 или 32 бита. В рассматрива- емом примере данные будут переме- щаться из буфера памяти в регистр дан- ных USART1_TX. Для этого необходимо будет поместить в один и тот же регистр данных USART1_TX первый байт из буфера, затем второй и так далее до конца буфера. Значит, инкремента- ция указателя на память необходима, а инкрементация указателя на перифе- рийное устройство не требуется. Настройки канала в целом включа- ют в себя: ● задание режима цикличности в виде однократного или циклического обмена; ● задание направления чтения из памя- ти или периферии; ● задание уровня приоритета канала; ● разрешение при необходимости пре- рываний. Данные настройки выполняются с помощью битов регистра управления канала CCR, описанных ранее. Запись данных в управляющий регистр мож- но выполнять побитно или в один при- ём 32-разрядным словом. Для нагляд- ности рассмотрим пример побитного занесения данных. Вначале выполним предварительную очистку управляющего регистра: DMA1_Channel4->CCR=0; // Очистка регистра конфигурации четвертого канала Далее зададим размер элемента дан- ных размером 8 бит путём обнуления соответствующего поля: DMA1_Channel4->CCR &= ~DMA_CCR4_ MSIZE; // 8 бит Для задания другого размера можно использовать следующие операции: DMA1_Channel4->CCR |= DMA_CCR4_ MSIZE_0; // 16 бит DMA1_Channel4->CCR |= DMA_CCR4_ MSIZE_1; // 32 бита Аналогично задаём размер элемента данных для периферии: DMA1_Channel4->CCR &= ~DMA_CCR4_ PSIZE; // 8 бит Для передачи всего массива данных из буфера активируем режим инкре- мента указателя в памяти: DMA1_Channel4->CCR |= DMA_CCR4_ PINC; // Инкремент указателя Запретим инкремент указателя для периферии: DMA1_Channel4->CCR &= ~DMA_CCR4_ PINC; В обычном режиме DMA останав- ливается после выполнения одного цикла обмена. Чтобы инициировать следующий цикл обмена, необходи- мо выполнить следующие действия: отключить канал DMA, перезагрузить регистр CNDTR, вновь включить канал DMA. Но можно изначально задать режим циклического обмена. Тогда по окончании передачи DMA автома- тически начнёт новый цикл. Для это- го необходимо выполнить следующие операции: DMA1_Channel4->CCR |= DMA_CCR4_ CIRC; // Включить циклический режим DMA1_Channel4->CCR |= DMA_CCR4_ DIR; // Задать направление пере- дачи данных из памяти DMA1_Channel4->CCR |= DMA_CCR4_ EN; // Разрешить работу канала Кроме этого необходимо разрешить работу периферии через DMA, восполь- зовавшись описанием периферийного устройства, которое нужно подключить к DMA. В нашем случае для подключе- ния USART1 используем следующий код: USART1->CR3 |= USART_CR3_DMAT; // Разрешить передачу USART1 че- рез DMA Узнать об окончании процедуры обмена через DMA помогут следую- щие флаги в регистре ISR: TEIF – ошиб- ка обмена в канале, HTIF – передана половина буфера, TСIF – передан весь буфер и GIF – общий флаг прерыва- ния в канале, который устанавливает- ся, если установлен любой из флагов TEIF, HTIF или TCIF. Для проверки соответствующего фла- га канала 4 необходимо выполнить сле- дующие процедуры: if (DMA1->ISR & DMA_ISR_TEIF4) {} // Проверить флаг TEIF ошибки обмена if (DMA1->ISR & DMA_ISR_HTIF4) {} // Проверить флаг HTIF пере- дачи половины буфера if (DMA1->ISR & DMA_ISR_TCIF4) {} // Проверить флаг TCIF окон- чания обмена Для обнуления установленного фла- га канала 4 существует регистр IFCR. Очистка соответствующего флага выполняется так: DMA1->IFCR |= DMA_ISR_TEIF4; // Очистить флаг ошибки обмена TEIF DMA1->IFCR |= DMA_ISR_HTIF4; // Очистить флаг передачи половины буфера HTIF DMA1->IFCR |= DMA_ISR_TCIF4; // Очистить флаг окончания обмена TCIF Листинг 2 unsigned char BuffTxd[32]; // Инициализация буфера передатчика void main() { // Загрузка буфера BuffTxd[0] = ‘Д’; BuffTxd[1] = ‘о’; BuffTxd[2] = ‘б’; BuffTxd[3] = ‘р’; BuffTxd[4] = ‘ы’; BuffTxd[5] = ‘й’; BuffTxd[6] = ‘ ’; BuffTxd[7] = ‘д’; BuffTxd[8] = ‘е’; BuffTxd[9] = ‘н’; BuffTxd[10] = ‘ь’; BuffTxd[11] = ‘!’; USART1_TX_DMA1_Init(); // Иници- ализация режима DMA1 для USART1 StartDMAChannel4(12); // Пуск передачи while(GetStateDMAChannel4()==0) {}; // Ждать окончания передачи StartDMAChannel4(12); // Повтор- ный пуск передачи while(GetStateDMAChannel4()==0) {}; // Ждать окончания передачи } © СТА-ПРЕСС
RkJQdWJsaXNoZXIy MTQ4NjUy