代码放的不对,我重新放:void LED_SPI_LowLevel_Init(void)
{
uint16_t i = 0;
uint32_t temp =0;
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_BufferSize = 0; //开辟3个连续的DMA存储单元
// DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR); //外设地址(u32)SPI2_DR_Address;
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x4000380C;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)PixelBuffer; //内存地址,就是你想要把采样值存在那个变量的地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //方向
DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //DMA优先级为低
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //设置外设数据长度为半字,即16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //设置DMA存储数据长度为半字,即16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_Init(DMA1_Channel5 , &DMA_InitStructure); /* DMA1 CH3 = MEM -> DR */
DMA_SetCurrDataCounter(DMA1_Channel5, 0);
temp=GPIOB->CRH;
temp&=0x0fffffff;
temp|=0xb0000000;
GPIOB->CRH=temp;
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PB15 RGB
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
/*
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOA, &GPIO_InitStructure);
*/
SPI_I2S_DeInit(SPI2);
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
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; //* 72MHz / 8 =9MHz / 16bit*/ SPI2在低速时钟,SPI1在高速时钟
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_Cmd(SPI2, ENABLE);
for (i = 0; i < 2190; i++)
{PixelBuffer[i] = 0xf0;}
PixelPointer = 0;
}
void LED_SPI_WriteByte(uint16_t Data)
{
/* Wait until the transmit buffer is empty */
/*
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
{
}
*/
PixelBuffer[PixelPointer] = Data;
PixelPointer++;
// if(PixelPointer>2190)
// {
// PixelPointer = 0;
// }
/* Send the byte */
/* SPI_I2S_SendData16(SPI1, Data); */
}
void LED_SPI_SendBits(uint8_t bits)
{
uint8_t zero = 0xc0; //1100 0000 0xc0
uint8_t one = 0xfc; //1111 1100 0xFc
uint8_t i = 0x00;
for (i = 0x80; i >= 0x01; i >>= 1)
{
LED_SPI_WriteByte((bits & i) ? one : zero);
}
}
void LED_SPI_SendPixel(uint32_t color)
{
/*
r7,r6,r5,r4,r3,r2,r1,r0,g7,g6,g5,g4,g3,g2,g1,g0,b7,b6,b5,b4,b3,b2,b1,b0
\_____________________________________________________________________/
| _________________...
| / __________________...
| / / ___________________...
| / / /
RGB,RGB,RGB,RGB,...,STOP
*/
/*
BUG Fix : Actual is GRB,datasheet is something wrong.
*/
uint8_t Red, Green, Blue; // 三原色
// 绿 红 蓝 三原色分解
Red = color>>8;
Green = color>>16;
Blue = color;
LED_SPI_SendBits(Green);
LED_SPI_SendBits(Red);
LED_SPI_SendBits(Blue);
}
uint8_t SK6812_light(unsigned long light, uint32_t length,HARDWARE_PARAMS_S *hardware_params)
{
uint16_t i = 0;
uint8_t send_result = 0;
// static uint16_t last_send_DMA = 0;
// uint16_t last_send_DMA_past = 0;
switch (hardware_params ->light.light_mod)
{
case 0 :
if(SystemTime_Cnt>=hardware_params ->light.last_send_DMA)
hardware_params ->light.last_send_DMA_past = SystemTime_Cnt-hardware_params ->light.last_send_DMA;
else
hardware_params ->light.last_send_DMA_past = 60000-hardware_params ->light.last_send_DMA + SystemTime_Cnt;
left_data=DMA_GetCurrDataCounter(DMA1_Channel5);
if(left_data == 0)
{
for (i = 0; i < length; i++)
{
LED_SPI_SendPixel(light);//数据存到数组内存中
}
PixelPointer = 0;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_BufferSize = 24*length;
// DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->DR);
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x4000380C;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)PixelBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_MemoryInc_Enable DMA_MemoryInc_Disable
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_Medium; //DMA ?? x ??????
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // ????????
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA_ClearFlag(DMA1_FLAG_TC5);
DMA_SetCurrDataCounter(DMA1_Channel5, (24*length));//80 1940 ok
DMA_Cmd(DMA1_Channel5, ENABLE);
hardware_params ->light.last_send_DMA = SystemTime_Cnt;
hardware_params ->light.light_mod = 1;
}
else if(hardware_params ->light.last_send_DMA_past>3000)
{
hardware_params ->light.light_mod = 2;
WLOG_INFO("left_data=%d\n",left_data);
}
break;
case 1:
if(SystemTime_Cnt>=hardware_params ->light.last_send_DMA)hardware_params ->light.last_send_DMA_past = SystemTime_Cnt-hardware_params ->light.last_send_DMA;
else hardware_params ->light.last_send_DMA_past = 60000-hardware_params ->light.last_send_DMA + SystemTime_Cnt;
send_result = wait_DMA_send();
if(send_result)
{
left_data=DMA_GetCurrDataCounter(DMA1_Channel5);
hardware_params ->light.light_mod = 0;
}
else
{
if(hardware_params ->light.last_send_DMA_past>500)
{
hardware_params ->light.light_mod = 2;
left_data=DMA_GetCurrDataCounter(DMA1_Channel5);
WLOG_INFO("left_data1=%d\n",left_data);
}
}
break;
case 2:
LED_SPI_LowLevel_Init();
send_result = 1;
hardware_params ->light.last_send_DMA = SystemTime_Cnt;
hardware_params ->light.light_mod = 0;
// WLOG_INFO("last_send_DMA_past=%d\n",hardware_params ->light.last_send_DMA_past);
break;
default:
break;
}
return send_result;
}
/*
uint8_t SK6812_light(unsigned long light, uint32_t length)
{
uint16_t i = 0;
static uint8_t light_mod = 0;
uint8_t send_result = 0;
switch (light_mod)
{
case 0 :
left_data=DMA_GetCurrDataCounter(DMA1_Channel3);
if(left_data == 0)
{
for (i = 0; i < length; i++)
{
LED_SPI_SendPixel(light);
}
PixelPointer = 0;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel3);
DMA_InitStructure.DMA_BufferSize = 24*length;
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_Medium;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //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_Init(DMA1_Channel3, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel3, DISABLE);
DMA_ClearFlag(DMA1_FLAG_TC3);
DMA_SetCurrDataCounter(DMA1_Channel3, (24*length));//80 1940 ok
DMA_Cmd(DMA1_Channel3, ENABLE);
light_mod = 1;
}
break;
case 1:
send_result = wait_DMA_send();
if(send_result)light_mod = 0;
break;
default:
break;
}
return send_result;
}*/
uint8_t wait_DMA_send(void)
{
uint8_t send_result =0;
if(DMA_GetFlagStatus(DMA1_FLAG_TC5)==0)
{
left_data=DMA_GetCurrDataCounter(DMA1_Channel5);
dma_error = DMA_GetFlagStatus(DMA1_FLAG_TE5);
send_result = 0;
// WLOG_INFO("left_data1=%d\n",left_data);
// LED_SPI_LowLevel_Init();
}
if(DMA_GetFlagStatus(DMA1_FLAG_TC5)==1)
{
left_data=DMA_GetCurrDataCounter(DMA1_Channel5);
if(left_data)
{
WLOG_INFO("left_data1=%d\n",left_data);
}
DMA_Cmd(DMA1_Channel5, DISABLE); // disable DMA channel 6
DMA_ClearFlag(DMA1_FLAG_TC5); // clear DMA1 Channel 6 transfer complete flag
DMA_SetCurrDataCounter(DMA1_Channel5, 0);
send_result = 1;
left_data = 0;
}
return send_result;
}
|