|
写了一个SPI通信的程序,主机发送数字0-9给从机,从机收到后再将一数字发送给主机,在proteus里仿真试过了,主机接收到从机的数据总是少一位,不知为毛,请高手指点。
主机程序:
#include <iom16v.h>
unsigned char led[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
char data=0;
void delay_s(unsigned char n) //---->us延时函数10us 误差0.46us
{
unsigned char i,j;
while(n--)
{
for(i=256;i>0;i--)
for(j=256;j>0;j--); //1时钟周期
}
}
//时钟周期62.5ns
void SPI_MasterInit(void)
{
PORTB=PORTB|0xf8;
/* 设置MOSI 和SCK 为输出,其他为输入 */
DDRB = (1<<DDB5)|(1<<DDB4)|(~(1<<DDB6))|(1<<DDB7)|(~(1<<DDB3));
/* 使能SPI 主机模式,设置时钟速率为fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(0<<DORD)|(0<<SPR1)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
char temp;
PORTB &= (~(1<<PB4)); //nss选通
/* 启动数据传输 */
SPDR = cData;
/* 等待传输结束 */
while((SPSR & (1<<SPIF)) == 0);
temp = SPSR;
temp = SPDR;
PORTB |= (1<<PB4); //nss关闭
}
char SPI_MasterReceive(void)
{
char temp;
/* 等待接收结束 */
while(!(PINB & 0x08));
SPDR = 0xFF;
PORTB &= (~(1<<PB4)); //nss选通
while(!(SPSR & (1<<SPIF)));
PORTB |= (1<<PB4); //nss关闭
/* 返回数据 */
temp = SPSR;
temp = SPDR;
return temp;
}
void datashift(void)
{
data++;
if(data>=10) data = 0;
}
void main(void)
{
char i=0;
SPI_MasterInit();
DDRD = 0x01;
PORTD = 0x01;
DDRC = 0xFF;
while(1)
{
SPI_MasterTransmit(data);
delay_s(10);
PORTC = led[data];
delay_s(50);
i=SPI_MasterReceive();
PORTC = led;
delay_s(50);
datashift();
}
}
从机程序:
#include <iom16v.h>
#include <macros.h>
unsigned char led[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
void delay_s(unsigned char n) //---->us延时函数10us 误差0.46us
{
unsigned char i;
while(n--)
{
for(i=256;i>0;i--)
for(i=256;i>0;i--); //1时钟周期
}
}
//时钟周期62.5ns
void SPI_SlaveInit(void)
{
PORTB=PORTB|0b11110000;
/* 设置MISO 为输出,其他为输入 */
DDRB = (1<<DDB6)|(~(1<<DDB4))|(~(1<<DDB5))|(~(1<<DDB7))|(1<<DDB3);
/* 使能 SPI */
SPCR = (1<<SPE)|(0<<SPR1)|(1<<SPR0)|(0<<DORD);
SPSR = 0x00; //(1<<SPIF)|(1<<WCOL);
}
char SPI_SlaveReceive(void)
{
char temp;
/* 等待接收结束 */
while((SPSR & (1<<SPIF)) == 0);
temp = SPSR;
temp = SPDR;
/* 返回数据 */
return temp;
}
void SPI_SlaveTransmit(char cData)
{
char temp;
/* 启动数据传输 */
SPDR = cData;
PORTB |= 0x08;
/* 等待传输结束 */
while((SPSR & (1<<SPIF)) == 0);
PORTB &= 0xF7;
temp = SPSR;
temp = SPDR;
}
void main(void)
{
char i;
SPI_SlaveInit();
DDRC = 0xFF;
DDRD = 0x01;
PORTD = 0x01;
while(1)
{ i = SPI_SlaveReceive();
PORTC = led;
SPI_SlaveTransmit(0x03);
SPDR = 0;
if(i>=10) i=0;
}
}
proteus仿真电路:
(从机返回的是0x03,但显示的是1)
proteus仿真波形:
(可以看到MISO输出的波形滞后一位) |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|