这几天被SPI搞得头都大了,我用的是单主单从的模式。我的做法是主机把数据发到从机,从机用液晶显示出来,同时从机的数据会移回主机,主机用串口来查看数据。但结果是,主机发到从机的数据能正确显示出来,从机发回主机的数据总有错位(其中有几个字节正确的)。简单地说就是,主机不能真确接受数据。
请问做过STC硬件SPI的有没有遇到这个问题?
下面是我的部分程序,也帮我看看有没有问题。
void Initial_SPI()
{
#ifdef MASTER
SPCTL = 0xFC; //0FCH, 忽略 SS 脚, 设为主机
//SSIG=1: 忽SS 脚
//SPEN=1:允许 SPI 工作
//DORD=1:先传低位 LSB
//MSTR=1:设为主机
//CPOL=1:SPI 空闲时 SPICLK = 1,前跳变沿是下降沿,后跳变沿是上升沿。
//CPHA=1:数据由 SPICLK 前跳变沿驱动到 SPI 口线,SPI 模块在后跳变沿采样数据。
//SPR1,SPR0 = 00:主模式时 SPI 时钟源选择为 fosc/4
#else
SPCTL = 0xEC; //0ECH, 忽略 SS 脚, 设为从机
//SSIG=1: 忽略SS 脚
//SPEN=1:允许 SPI 工作
//DORD=1:先传低位 LSB
//MSTR=0:设为从机
//CPOL=1:SPI 空闲时 SPICLK = 1,前跳变沿是下降沿,后跳变沿是上升沿。
//CPHA=1:数据由 SPICLK 前跳变沿驱动到 SPI 口线,SPI 模块在后跳变沿采样数据。
//SPR1,SPR0 = 00:主模式时 SPI 时钟源选择为 fosc/4
#endif
SPSTAT = CLSPI; //清0 标志位 SPIF(SPSTAT.7), WCOL(SPSTAT.6)
//向该两个标志位写"1" 会将它们清0
IE2 |= 0x02; // 允许 SPI 中断控制位
}
//这是主机收发一体的函数
uint8 SPI_RW_Byte(uint8 _data)
{
uint8 value;
SPDAT = _data; //发送一个字节数据
while(!(SPSTAT & 0X80)); //等待发送完毕
SPSTAT = CLSPI; //清0 标志位 SPIF(SPSTAT.7), WCOL(SPSTAT.6)
value = SPDAT;
return value;
}
//这是从机SPI接受数据的中断服务程序
void SPI_INT_SEV() interrupt 9
{
SPI_value = SPDAT;
SPSTAT = CLSPI; //清0 标志位 SPIF(SPSTAT.7), WCOL(SPSTAT.6)
SPI_REC_FLAG=1;
} |