利用ATmega168的硬件SPI驱动74HC595来扩展串行接口。把MOSI和SCK设置为输出,然后设置好寄存器。,具体如下:
static void vSpi595Init(void)
{
DDRB|=(1<<PB3)|(1<<PB5); //设置io口状态,spi的mosi和sck输出
DDRD|=(1<<PD5); //设置595锁存引脚的方向
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI主机模式传送速度。
}
然后调用如下的发送函数
static void vSPIMasterTransmit(unsigned char ucData)
{
SS_L(); //拉低存储寄存器时钟
SPDR = ucData; // 启动数据传输
while(!(SPSR & (1<<SPIF))); // 等待传输结束
SS_H(); //拉高存储寄存器时钟
}
却发现死活不产生SPIF的中断。更换芯片,调整时钟和SPI数率都不管用。
后来去ouravr网站去搜,发现好多人碰到同样的问题,并且恰恰有个人给出了解决方法。就是需要把SS管脚设置为输出才行。
修改后的初始化函数为
static void vSpi595Init(void)
{
DDRB|=(1<<PB3)|(1<<PB5))|(1<<PB2); //设置io口状态,spi的mosi和sck SS输出
DDRD|=(1<<PD5); //设置595锁存引脚的方向
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI主机模式传送速度。
}
就是说当作为主机的时候,SS必须设置为输出,而芯片复位后该SS引脚默认为输入,所以必须程序中主动设置一下。再Datasheet里面好像也没有明确指出这一点。
用户377235 2015-10-1 12:35
用户395069 2007-9-1 00:10
用户53464 2007-9-1 00:02
我们老师都不管我们了,老师就是给我们提供器件,整个暑假也没指导我们多少,你们还有队服~~好羡慕~~~