这几天在用74HC595驱动8位数码管,之间用CC2541做过驱动都很正常PCB就按照以前的画了,这次单片机使用了MSP430G2553
8位数码管使用2片74HC595驱动,第一片用来显示字符,第二片用来控制哪位显示
调试时发现显示乱码,单字字符显示发现会有篡位的情况,而且显示的效果还和不同的SPI速率和中间的手动延时有关
用示波器测了一下SCLK有DIO引脚,波形正常,数据也正常,因为是2通道示波器就只测了这两个通道的波形
后来反复调试,感觉好像找到规律了,每次结果又都和预想的不太一样
后来又用示波器测量SCLK和RCLK的波形,波形是这样的
很明显黄色的RCLK在蓝色的SCLK还在发送数据时就已经设置成高电平(显示更新)
数据还没有发完就更新显示自然就会显示篡位,在发送函数执行后延时一定时间再给RCLK高电平显示正常
显示的问题找到了,剩下就是为什么RCLK在SPI数据还没有发送完成就抬起来了呢?
SPI代码我参考官方提供的msp430g2xx3_uscia0_spi_09.c修改
发送函数spi_write_read_byte在发送前判断UCB0TXIFG是否为1,发送后没有判断
我猜可能是这个问题
- uint8_t spi_write_read_byte(uint8_t d)
- {
- while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
- UCB0TXBUF = d; // Send next value
- return UCB0TXBUF;
- }
后来我将代码改成下边这样,发送后再判断是否发送完成
- uint8_t spi_write_read_byte(uint8_t d)
- {
- while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
- UCB0TXBUF = d; // Send next value
- while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
- return UCB0TXBUF;
- }
用示波器测量时发现波形没有任何变化RCLK还是在SCLK时钟没有跑完就抬了起来
原来官方代码的数据发送是在中断函数里实现的,我没有开启中断所以IFG2对应的位不会被更新,判断也就没有实际意义
将代码改成下边这种,通过检查UCB0STAT的UCBUSY判断数据是否发送完成
再测试一切正常
- uint8_t spi_write_byte(uint8_t d)
- {
- while ((UCB0STAT & UCBUSY)); // USCI transmitting or receiving
- UCB0TXBUF = d; // Send next value
- while ((UCB0STAT & UCBUSY)); // USCI transmitting or receiving
- return UCB0TXBUF;
- }
问题已经解决,另外一个小问题是RCLK上升的速度不够快
如果将时钟频率调的很高,RCLK延时变短就会出现下边情况
SCLK的上升速度很快,RCLK像是在给电容充放电
现在还不清楚是MSP430的SPI和GPIO的驱动能力有区别
还是74HC595不同引脚输入电容大小不一样造成的,有空再研究
想起以前使用MSP430G2553这个单片机调试射频模块的情况
当时使用MSP430G2553的GPIO模拟SPI和射频模块通信正常
使用硬件SPI就出错,用示波器比较模拟和硬件的SCLK和MOSI的数据
软件模拟SPI,和硬件SPI发送的数据已经完全一样了,硬件还是不能使用
现在想想那时候硬件SPI发送不成功也许就是因为CS引脚抬起太早导致数据发送中断造成的
时间太长忘了当时没有没测量CS引脚
以前用带逻辑分析仪功能的4通道的示波器没觉得4通道有啥用,后来买示波器时就买了2通道,经过这几次高度发现2通道用起来其实挺别手的
水平不够还容易掉坑里
本帖最后由 littleshrimp 于 2017-4-16 10:09 编辑