STM32 基于DMA利用SPI驱动WS2812时数据量大时错误

2019-07-21 02:27发布

如题,参考网上的代码,
但是当DMA_SetCurrDataCounter(DMA1_Channel3, 1700),中数据超过1700时,发送出来的数据就有问题,不知道什么原因,具体代码如下


uint16_t PixelBuffer[3072] = {0};
uint16_t PixelPointer = 0;
extern uint16_t SystemTime_Cnt;
void LED_SPI_LowLevel_Init(void)
{
    uint16_t i = 0;

    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef   SPI_InitStructure;
    DMA_InitTypeDef   DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);

    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_BufferSize = 0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI1->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)PixelBuffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //DMA_MemoryInc_Enable
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure); /* DMA1 CH3 = MEM -> DR */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

                /*
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
                */

    SPI_I2S_DeInit(SPI1);

    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; /* 48MHz / 8 = 6MHz / 16bit*/
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);

    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);

    SPI_Cmd(SPI1, ENABLE);

    for (i = 0; i < 3072; i++)
                        {PixelBuffer[i] = 0xff00;}
    PixelPointer = 0;
}



void LED_Red(unsigned long light, uint32_t length)
{
    uint16_t i = 0;
    uint8_t m = 0;
    if(DMA_GetCurrDataCounter(DMA1_Channel3) == 0)
    {


    for (i = 0; i < 3072; i++)
                        {
                        PixelBuffer[i] = 0xff00;
                        }
        PixelPointer = 0;

        DMA_Cmd(DMA1_Channel3, DISABLE);
        DMA_ClearFlag(DMA1_FLAG_TC3);
        DMA_SetCurrDataCounter(DMA1_Channel3, 1700);//80  1940 ok
        DMA_Cmd(DMA1_Channel3, ENABLE);
//                                while(!DMA_GetFlagStatus(DMA1_FLAG_TC3)) ;         // wait until transfer complete
//                                DMA_Cmd(DMA1_Channel3, DISABLE);                         // disable DMA channel 6
//                                DMA_ClearFlag(DMA1_FLAG_TC3);                                 // clear DMA1 Channel 6 transfer complete flag
    }
}

uint8_t wait_DMA_send(HARDWARE_PARAMS_S *hardware_params)
{
                  uint8_t send_result =0;
                                        if(!DMA_GetFlagStatus(DMA1_FLAG_TC3))
                                {
                                        hardware_params -> light.left_data=DMA_GetCurrDataCounter(DMA1_Channel3);
                                        hardware_params -> light.dma_error = DMA_GetFlagStatus(DMA1_FLAG_TE3);
                                }
                                else
                                {
                                DMA_Cmd(DMA1_Channel3, DISABLE);                         // disable DMA channel 6
                                DMA_ClearFlag(DMA1_FLAG_TC3);                                 // clear DMA1 Channel 6 transfer complete flag
        send_result = 1;
                                hardware_params -> light.left_data = 0;       
                                }
                               
                return send_result;
       
       
}

void Red_Bling ( uint32_t led_num)
{
        static uint8_t bling_mod =0;
        static uint16_t color_change_time = 0;
        uint16_t color_change_time_past = 0;
         uint8_t send_result =0;
                        ///////////////////////2aê&#212;′ú&#194;&#235;//////////////////////////////////
        static uint8_t last_state = 0;
        if(last_state!=bling_mod)
                WLOG_INFO("bling_mod=%d ",bling_mod);
        last_state = bling_mod;
//hardware_params ->robot_vend_params.msg_coming =1;
//Msg_From_Host.robot_vend.cmd =1;       
        ////////////////////////////////////////////////////////
        switch (bling_mod)
   {
        case 0 :
                 LED_Red(0x00ff00, 80);

           bling_mod =1;
                break;
        case 1 :       
                             send_result =wait_DMA_send(&Hardware_Params);

               if(send_result)
                                 {
                                         bling_mod = 2;
                color_change_time =SystemTime_Cnt;
                                 }
        break;
        case 2 : //&#209;óê±10ms
                Delay_ms(800);
          bling_mod =3;
//                 if(SystemTime_Cnt>color_change_time)color_change_time_past = SystemTime_Cnt-color_change_time;
//                 else color_change_time_past = 60000-color_change_time + SystemTime_Cnt;
//           if(color_change_time_past>1000)bling_mod =3;
                break;
                case 3 :
                 LED_Red(0x000000, 80);
           color_change_time =SystemTime_Cnt;
           bling_mod =4;
                break;
        case 4 :       
                             send_result =wait_DMA_send(&Hardware_Params);

               if(send_result)
                                 {
                                         bling_mod = 5;
                color_change_time =SystemTime_Cnt;
                                 }
        break;               
               
                case 5:
//                 if(SystemTime_Cnt>color_change_time)color_change_time_past = SystemTime_Cnt-color_change_time;
//                 else color_change_time_past = 60000-color_change_time + SystemTime_Cnt;
//           if(color_change_time_past>1000)bling_mod =0;
                                Delay_ms(800);
          bling_mod =0;
                break;
        default:
                break;
   }

}


0条回答

一周热门 更多>