Страницы

Ярлыки

ДШИ-200 (1) КСВУ-6 (1) ЛЧМ (1) МДР-23 (1) микроконтроллер (1) перенаправление (1) С (1) структуры (1) учебный курс (1) AC/DC (1) ADC (1) ADS1248 (1) Altium (1) Altuim (1) Amolifer (1) ARM (1) assembler (2) Asynchronous (1) at command (3) at#eaddr (1) at#epassw (1) at#esmtp (1) at#euser (1) at#gprs (1) at#selint=2 (1) at#sgact (1) at#tcpatcmdseq (1) ATX (1) AVR (2) bit (1) boost (1) boot (2) bootlloader (1) C (6) C# (7) C++ (1) CMSIS (1) command (1) CP2101 (1) CSD (1) Danfoss (6) DBGMCU (1) debug (1) debug.ini (1) delegate (1) Discovery (1) DMA (1) DRV8805 (1) DWT (1) e-mail (1) email (1) Exel (1) exFAT (1) FC-051 (1) gl868-dual (2) gl868-dual cmux (1) GPIO (2) GSM (1) I2C (1) IAR (1) ID (1) Invoke (1) Keil (3) LabVIEW (1) Linux (1) LMP7721 (1) LoRa (3) mdmread (1) memory (1) MODBUS (1) Operation Amplifer (1) pack (1) printf (2) printf() (1) RCC (1) retargetting (1) RFM95/96/87/98(W) (1) RS232 (4) RS485 (1) RSAPI.DLL (1) RSS (1) RTC (2) send (2) SerialPort (1) Silabs (1) spl (1) standard peripherals library (1) startup (1) stepper (2) STlink (1) STlink/V2 (2) STM32 (10) stm32 stm32f10x (1) STM32DBG.IN (1) STM32F (19) STM32F103 (4) struct (1) Structure (1) system (1) SystemInit (1) Task (1) telit (5) thread (4) TIM (1) Type Cast (1) UART (1) uni-trend (1) USART (6) USB (1) UT61B (1) viewer (1)

воскресенье, 13 июля 2014 г.

DMA to USART

Программирование передачи области памяти через UART с использованием DMA
#include "stm32f10x.h"
/*******************************************************************/
#define BAUDRATE 115200
#define DMA_BUFFER_SIZE 16

/*******************************************************************/
void initAll(void)
{
GPIO_InitTypeDef port;
USART_InitTypeDef usart;
DMA_InitTypeDef dma;
uint8_t dataBuffer[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

/*******************************************************************/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//if ((RCC->AHBENR & RCC_AHBENR_DMA1EN) != RCC_AHBENR_DMA1EN) RCC->AHBENR |= RCC_AHBENR_DMA1EN;
//при использовании для настройки CMSIS

DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
dma.DMA_MemoryBaseAddr = (uint32_t)&dataBuffer[0];
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = DMA_BUFFER_SIZE;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_Init(DMA1_Channel4, &dma);

GPIO_StructInit(&port);
port.GPIO_Mode = GPIO_Mode_AF_PP;
port.GPIO_Pin = GPIO_Pin_9;
port.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &port);

port.GPIO_Mode = GPIO_Mode_AF_PP;
port.GPIO_Pin = GPIO_Pin_10;
port.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &port);

USART_StructInit(&usart);
usart.USART_BaudRate = BAUDRATE;
USART_Init(USART1, &usart);
}
//==========================================================================
int main()
{
    __enable_irq();
    initAll();
    USART_Cmd(USART1, ENABLE);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(DMA1_Channel4, ENABLE);
    while(1)
    {
  __NOP();

DMA_Cmd(DMA1_Channel4, DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel4,16);
DMA_Cmd(DMA1_Channel4, ENABLE);
    }
}

Настройка DMA при использовании CMSIS

DMA1_Channel4->CMAR = (uint32_t) &text[0];                         //адрес буфера передатчика
DMA1_Channel4->CPAR = (uint32_t) &USART1->DR;             //адрес регистра данных передатчика
DMA1_Channel4->CNDTR = sizeof(text);                                    //для передатчика
DMA1_Channel4->CCR = DMA_CCR4_DIR | DMA_CCR4_MINC;      //чтение из памяти, инкремент указателя в памяти
DMA1_Channel4->CCR |= DMA_CCR4_TEIE;                          //канал 4
USART1->CR3 |= USART_CR3_DMAT;                                    //разрешить передачу USART1 через DMA

Чтобы включить DMA набираем:

DMA1_Channel4->CCR |= DMA_CCR1_EN;

Для перезапуска DMA, придётся несколько усложнить функцию:
DMA1_Channel4->CCR &= (uint16_t)(~DMA_CCR1_EN);              //Выключаем DMA.
DMA1_Channel4->CNDTR = sizeof(text);                                           //Устанавливаем размер передаваемого буфера заново.
DMA1_Channel4->CCR |= DMA_CCR1_EN;                                    //Включаем DMA

После этих строк DMA, будет работать и в конце выдаст прерывание вида:

void DMA1_Channel4_IRQHandler(void)
{
    DMA1->IFCR |= DMA_ISR_TCIF4;                                             //очистить флаг окончания обмена.
}

Флаг надо сбросить, иначе прерывания будут генерироваться бесконечно.

Другой вариант с SPL

DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)text;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = sizeof(text);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);

Комментариев нет:

Отправить комментарий

ваше мнение...