STM32 SRAM a pines GPIO DMA

6

Deseo transferir una gran variedad de datos a 8 pines de salida que están todos en el mismo puerto. P.ej. una matriz de 500 elementos de 8 bits donde cada bit de cada elemento representa el estado del pin. Por lo tanto, se necesitarían 500 transferencias independientes al puerto.

He estado revisando los ejemplos que tiene ST, pero ninguno de ellos parece hacer esto. Parece que hay muchos ejemplos de 'DMA a PWM' que se transfieren a un pin que tiene un temporizador conectado, pero esto no me sirve, ya que quiero transferir a un puerto completo. ¿Cómo haría esto? ¿Hay ejemplos similares a esto que podría modificar a mi necesidad?

Gracias

    
pregunta gorge

1 respuesta

5

Breve descripción:

El temporizador activa DMA con la velocidad deseada, DMA escribe datos en el registro de salida GPIO.

Descripción larga:

  1. Prepare el estado de salida del puerto GPIO seleccionado al estado predeterminado bajo / alto
  2. Configure el puerto GPIO seleccionado PX para que salga push-pull / drenaje abierto
  3. Configure cualquier temporizador para el período deseado de actualización del puerto GPIO
  4. Configurar DMA seleccionado y vincularlo a TIM seleccionado
  5. Configure las devoluciones de llamada para las IRQ de DMA: HT, TC, ERR
  6. Habilite DMA para escribir su búfer de datos, la longitud del búfer a PX- > ODR seleccionado
  7. Habilite TIM para generar eventos DMA
  8. Ejecutar TIM
  9. Maneje el estado DMA en las devoluciones de llamada y controle el TIM según lo necesite

Código en blanco:

  

Todo el código escrito aquí y no probado, puede contener contenido simple   errores como el uso de variables en lugar de punteros en macros HAL o   funciones llamadas.

GPIO_InitTypeDef GPIO_InitStruct;
TIM_HandleTypeDef htim1;
DMA_HandleTypeDef hdma_tim1_uev;

/* 1 (Port GPIOA) */
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_All, GPIO_PIN_RESET);

/* 2 (Port GPIOA) */
GPIO_InitStruct.Pin = GPIO_PIN_All;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* 3 (Timer TIM1) */
__HAL_RCC_TIM1_CLK_ENABLE();
htim1.Instance = TIM1;
htim1.Init.Prescaler = DESIRED_PRESCALER;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = DESIRED_PERIOD;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim1)

/* 4 (DMA1 Channel2) */
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_tim1_uev.Instance = DMA1_Channel2;
hdma_tim1_uev.Init.Direction = DMA_MEMORY_TO_PERIF;
hdma_tim1_uev.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim1_uev.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim1_uev.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; // 16 bits
hdma_tim1_uev.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_tim1_uev.Init.Mode = DMA_NORMAL;
hdma_tim1_uev.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_tim1_uev);
__HAL_DMA1_REMAP(HAL_DMA1_CH2_TIM1_UP);
__HAL_LINKDMA(&htim1,hdma[TIM_DMA_ID_UPDATE],hdma_tim1_uev);
HAL_NVIC_SetPriority(DMA1_Ch2_3_DMA2_Ch1_2_IRQn, 0, 0); // enable DMA IRQ
HAL_NVIC_EnableIRQ(DMA1_Ch2_3_DMA2_Ch1_2_IRQn);

/* 5 (Callbacks for DMA IRQs) */
htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = data_tramsmitted_handler;
htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = transmit_error_handler;

/* 6 (Enable DMA) */
HAL_DMA_Start_IT(htim1.hdma[TIM_DMA_ID_UPDATE],(uint32_t)&my_data_buf, 
    (uint32_t)&GPIOA->ODR, my_data_buf_length);

/* 7 (Enable TIM for DMA events) */
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);

/* 8 (Run TIM) */
__HAL_TIM_ENABLE(&htim1);

/* 9 (DMA IRQ callbacks) */
void data_tramsmitted_handler(DMA_HandleTypeDef *hdma)
{
    /* Stop timer */
    __HAL_TIM_DISABLE(&htim1);
    /* Reconfigure DMA */
    HAL_DMA_Start_IT(htim1.hdma[TIM_DMA_ID_UPDATE],(uint32_t)&my_data_buf, 
        (uint32_t)&GPIOA, my_data_buf_length);
    /* Start timer for new data transmit */
    __HAL_TIM_ENABLE(&htim1);
}

void transmit_error_handler(DMA_HandleTypeDef *hdma)
{
    /* Stop timer */
    __HAL_TIM_DISABLE(&htim1);
    /* Some error handle ? */
}
    
respondido por el imbearr

Lea otras preguntas en las etiquetas