atmega328p spi通信只能接收到第一位数据
本帖最后由 xiezx 于 2014-7-29 19:12 编辑测试flash memory at26f004
println() 是串口通信函数
程序如下
unsigned char data;
void spi_initialisation(void)
{
//设置SCK MOSI SS输出 1
DDRB &= ~(0x3c);
DDRB |= 0x2C;
SPCR = 0x50;
println("init finished");
}
void spi_transmit(char data)
{
SPDR = data;
while(!(SPSR & (1 << SPIF)));
}
unsigned char spi_receive(void)
{
while(!(SPSR & (1 << SPIF)));
return SPDR;
}
void flash_read()
{
println("start read");
PORTB &= ~(1 << PORTB2);
spi_transmit(0x03);
println("opcode");
spi_transmit(0x00);
spi_transmit(0x00);
spi_transmit(0x00);
println("address");
/*for(unsigned char i = 0;i < 8;i++)
{
data = spi_receive();
println("data");
}*/
data = spi_receive();
println("data");
data = spi_receive();
println("data");
data = spi_receive();
println("data");
data = spi_receive();
println("data");
PORTB |= 1 << PORTB2;
}
void _flash_text()
{
spi_initialisation();
PORTB |= 1 << PORTB2;
_delay_ms(1000);
flash_read();
for(unsigned char i = 0;i < 8;i++)
{
print_byte_hex(data);
}
}
由串口通信的结果知道
init finished
start read
opcode
address
data
只能进行完第一次接收
不知道是因为什么
麻烦大伙帮帮想想
下面是一些资料
好吧现在问题解决了
只是在等待中断标志置位之前 加了一句
SPDR = 0X00;
像这样
unsigned char spi_receive(void)
{
SPDR=0x00;
while(!(SPSR & (1 << SPIF)));
return SPDR;
}
就行了
可是为什么呢
这样给SPDR赋值不是会当作数据发送出去吗
有没有人能解释一下 难道是没清标志?
SPIF可能一直有效 SPI 没有可能有单独分开的传送或接收程式,因为是同时发生的。传送时你一定也同时接收,关键是你是否对接收来所得的资料住作出处理。
但你必需读取收来的资料,否则SPIF标志一直有效。 楼主的 SPI 『接收』程式并没有对 SPDR 写入任意数值,AVR 为主的 SPI,跟本不会产生 SCK,何来接收资料? 其实是写了内容的呀
void flash_read()
{
println("start read");
PORTB &= ~(1 << PORTB2);
spi_transmit(0x03);//<<<<<---------------------------------传送opcode 表示read array
println("opcode");
//<<<<<<<<<<<<<<<<<-----------------------------------------传送3byte的地址字节
spi_transmit(0x00);
spi_transmit(0x00);
spi_transmit(0x00);
println("address");
/*for(unsigned char i = 0;i < 8;i++)
{
data = spi_receive();
println("data");
}*/
data = spi_receive();
println("data");
data = spi_receive();
println("data");
data = spi_receive();
println("data");
data = spi_receive();
println("data");
PORTB |= 1 << PORTB2;
} 嗯 楼上说必须读取SPDR的值也读取过了呀
unsigned char spi_receive(void)
{
while(!(SPSR & (1 << SPIF)));
return SPDR;//<=======这里╮(╯▽╰)╭
}
这样算读取过了吗
avr的Data sheet里就是这样写的 alias 发表于 2014-7-29 16:09
楼主的 SPI 『接收』程式并没有对 SPDR 写入任意数值,AVR 为主的 SPI,跟本不会产生 SCK,何来接收资料? ...
而且应该不存在写的同时有数据传进来的情况
lcw_swust 发表于 2014-7-29 14:56
难道是没清标志?
SPIF可能一直有效
应该不是吧
我也试了一下
好像清没清标志位对结果没什么改变的样子 xiezx 发表于 2014-7-29 17:55
应该不是吧
我也试了一下
这样改一下:
char spi_transmit(char data)
{
SPDR = data;
while(!(SPSR & (1 << SPIF)));
data=SPDR;
return data;
}
将spi_receive函数去掉,用spi_transmit(0xFF)代替 嗯 好像这样是可以的
之前也用接收等待前加一句
SPDR = 0X00;
解决了这个问题
非常感谢啊
但是好像又有了新的问题
确实后面的数据能接到了
但是好像和我写进去的数据不一样
换句话说是不是接收到的并不是数据
通信还是没成功啊
页:
[1]