新手上路
- 积分
- 34
- 金钱
- 34
- 注册时间
- 2018-1-31
- 在线时间
- 7 小时
|
1金钱
问题:用SPI+DMA的方式,单向给外设发送数据,将SPI以及DMA配置初始化完成,编写的发送子函数调用一次,功能正常!多次调用达不到理想的效果(基本就是第一次调用有效,后续调用功能无效) 可能是这里面的标志位啥的没有清除引起的,初始使用这个,对这些搞不太清除,重点是红色那几行代码该怎么优化,还请懂的朋友指点指点,谢谢!
/* 主函数 */
while(1)
{
LED_SPI_DMA_2811_Send(0,255,0,LEDNum); //这一条功能正常
delay_ms (1000);
LED_SPI_DMA_2811_Send(255,0,0,LEDNum); //这一条没有效果
delay_ms (1000);
}
SPI+DMA发送子函数:
void LED_SPI_DMA_2811_Send(u8 r,u8 g,u8 b,u16 LedNum)//点亮LedNum个灯
{
//**********************************************SPI要发送的数据处理过程************SendBuff[l][k]为SPI-DMA数据内存区**********
u16 i;//灯数量
u8 j=0,k=0,l;//rgb参数
u8 RGBConver[3][8]={ZEROCODE};
for (i = 0x80; i >= 0x01; i >>= 1)
{
RGBConver[0][j]=(g & i) ? ONECODE : ZEROCODE;//G码转换
RGBConver[1][j]=(r & i) ? ONECODE : ZEROCODE;//R码转换
RGBConver[2][j]=(b & i) ? ONECODE : ZEROCODE;//B码转换
j++;
}
for( l=0;l<LedNum;l++)
{
for(k=0;k<8;k++)
{
SendBuff[l][k]=RGBConver[0][k];//G码
}
for(k=8;k<16;k++)
{
SendBuff[l][k]=RGBConver[1][k-8];//R码
}
for(k=16;k<24;k++)
{
SendBuff[l][k]=RGBConver[2][k-16];//B码
}
}
//**********************************************SPI要发送的数据处理过程完成************SendBuff[l][k]为SPI-DMA数据内存区**********
DMA_Cmd(DMA1_Stream4, DISABLE); //关闭DMA传输
while (DMA_GetCmdStatus(DMA1_Stream4) != DISABLE){} //确保DMA可以被设置
DMA_SetCurrDataCounter(DMA1_Stream4,LedNum*24); //数据传输量
DMA_Cmd(DMA1_Stream4, ENABLE); //开启DMA传输
}
其他DMA SPI初始化代码见后!
/* 配置 DMA Stream */
void MyDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{
DMA_InitTypeDef DMA_InitStructure;
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
}else
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
}
DMA_DeInit(DMA_Streamx);
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
DMA_InitStructure.DMA_Channel = chx; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
}
//SPI2配置
void MySPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
//DMA初始化
//SPI初始化
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 , ENABLE );//使能SPI2时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);//使能GPIOB时钟
//初始化SPI输出口
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_15|GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF ;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP ;
//GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz ;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//SPI引脚复用
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);//PB15-SPI2_MOSI
//GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);//PB15-SPI2_MISO
//GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2);//PB15-SPI2_SCK
//SPI初始化
SPI_InitStruct.SPI_Direction =SPI_Direction_1Line_Tx;//SPI数据传输方向-单向发送
SPI_InitStruct.SPI_Mode =SPI_Mode_Master;//主站
SPI_InitStruct.SPI_DataSize =SPI_DataSize_8b;
SPI_InitStruct.SPI_CPOL =SPI_CPOL_Low;//时钟空闲时为低电平
SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;//第一个边沿开始
SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;//软件片选
SPI_InitStruct.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_2;//8分频
SPI_InitStruct.SPI_FirstBit =SPI_FirstBit_MSB;//高位在前
SPI_InitStruct.SPI_CRCPolynomial = 7; //????CRC值计算的多项式
SPI_Init(SPI2, &SPI_InitStruct);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_Cmd(SPI2, ENABLE);
}
|
-
最佳答案
查看完整内容[请看2#楼]
找到主要原因了,是子函数Dma完成标志未清除!不过这里面严谨的代码过程还不是很清楚,虽然程序能够按要求运行,不知会不会出现意想不到的问题,还请大神指点下规范严谨的spi dma代码该如何完善,谢谢
|