|
今天使用SPI接口调试TLC5618,上午按设想配置了SPI但调试没有成功,由于是首次使用STM32的SPI,TLC5618也是首次,不知器件是否焊接正常,下午先改用GPIO模拟SPI成功了。又将程序改为STM32硬件的SPI,发现两个问题有些奇怪。
先上TLC5618的资料
这是TLC5618的通信时序图
这是TLC5618的指令格式
问题1:
根据时序图,可选择SCK静态是为低,在脉冲的第二个沿进行数据捕捉,代码如下
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//第二个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号由SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//预分频值为2
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//用于CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStructure);//初始化配置
SPI_Cmd(SPI2,ENABLE);//使能或者失能SPI外设
GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据
while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
说明:GPIO等配置已设置正确,PA12为控制TLC5618的CS片选,使用SPI2发送数据,结果不成功。
将SPI2的配置改为
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//第一个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号由SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//预分频值为2
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//用于CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStructure);//初始化配置
SPI_Cmd(SPI2,ENABLE);//使能或者失能SPI外设GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
偶尔还是不行,后来又在代码中插入延时,后面的配置倒是成功了,但我觉得根据时序图这两种配置都应该可行的,但前一种就是不可以。
问题2:SPI_I2S_FLAG_RXNE标志的问题,在SPI_I2S_FLAG_RXNE有效后,直接CS=1,是无法控制TLC5618的,必须在测试SPI_I2S_FLAG_RXNE循环结束后,在假一段延时才不会出错
GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据
while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
for (a = 0; a < 5; a++);//插入延时
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
这样才成功了。
我的疑问是在GPIO模拟SPI时CS=1是不需要延时的,而while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);之后不进行延时就不行,难道是SPI_I2S_FLAG_RXNE标示到来时,SPI的传输还未结束? |
|