搜索
bottom↓
回复: 9

atmega328p spi通信只能接收到第一位数据

[复制链接]

出0入0汤圆

发表于 2014-7-29 14:33:17 | 显示全部楼层 |阅读模式
本帖最后由 xiezx 于 2014-7-29 19:12 编辑

测试flash memory at26f004
println() 是串口通信函数

程序如下
  1. unsigned char data[8];


  2. void spi_initialisation(void)
  3. {
  4.         //设置SCK MOSI SS输出 1
  5.         DDRB &= ~(0x3c);
  6.         DDRB |= 0x2C;
  7.        
  8.         SPCR = 0x50;
  9. println("init finished");
  10. }

  11. void spi_transmit(char data)
  12. {
  13.         SPDR = data;
  14.         while(!(SPSR & (1 << SPIF)));
  15. }

  16. unsigned char spi_receive(void)
  17. {
  18.         while(!(SPSR & (1 << SPIF)));
  19.         return SPDR;
  20. }

  21. void flash_read()
  22. {
  23. println("start read");
  24.         PORTB &= ~(1 << PORTB2);
  25.         spi_transmit(0x03);
  26. println("opcode");
  27.         spi_transmit(0x00);
  28.         spi_transmit(0x00);
  29.         spi_transmit(0x00);
  30. println("address");
  31.         /*for(unsigned char i = 0;i < 8;i++)
  32.         {
  33.                 data[i] = spi_receive();
  34. println("data");
  35.         }*/
  36.         data[0] = spi_receive();
  37. println("data");
  38.         data[1] = spi_receive();
  39. println("data");
  40.         data[2] = spi_receive();
  41. println("data");
  42.         data[3] = spi_receive();
  43. println("data");
  44.         PORTB |= 1 << PORTB2;
  45. }


  46. void _flash_text()
  47. {
  48.         spi_initialisation();
  49.         PORTB |= 1 << PORTB2;
  50.         _delay_ms(1000);
  51.        
  52.        
  53.         flash_read();
  54.        
  55.         for(unsigned char i = 0;i < 8;i++)
  56.         {
  57.                 print_byte_hex(data[i]);
  58.         }
  59.        
  60. }
复制代码


由串口通信的结果知道
  1. init finished
  2. start read
  3. opcode
  4. address
  5. data
复制代码

只能进行完第一次接收
不知道是因为什么
麻烦大伙帮帮想想


下面是一些资料










好吧现在问题解决了
只是在等待中断标志置位之前 加了一句
SPDR = 0X00;
像这样
  1. unsigned char spi_receive(void)
  2. {
  3.         SPDR=0x00;
  4.         while(!(SPSR & (1 << SPIF)));
  5.         return SPDR;
  6. }
复制代码

就行了
可是为什么呢
这样给SPDR赋值不是会当作数据发送出去吗
有没有人能解释一下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2014-7-29 14:56:12 | 显示全部楼层
难道是没清标志?
SPIF可能一直有效

出0入0汤圆

发表于 2014-7-29 15:58:24 | 显示全部楼层
SPI 没有可能有单独分开的传送或接收程式,因为是同时发生的。传送时你一定也同时接收,关键是你是否对接收来所得的资料住作出处理。

但你必需读取收来的资料,否则SPIF标志一直有效。

出0入0汤圆

发表于 2014-7-29 16:09:39 | 显示全部楼层
楼主的 SPI 『接收』程式并没有对 SPDR 写入任意数值,AVR 为主的 SPI,跟本不会产生 SCK,何来接收资料?

出0入0汤圆

 楼主| 发表于 2014-7-29 17:12:40 | 显示全部楼层
其实是写了内容的呀
  1. void flash_read()
  2. {
  3. println("start read");
  4.         PORTB &= ~(1 << PORTB2);
  5.         spi_transmit(0x03);//<<<<<---------------------------------传送opcode 表示read array
  6. println("opcode");
  7. //<<<<<<<<<<<<<<<<<-----------------------------------------传送3byte的地址字节
  8.         spi_transmit(0x00);
  9.         spi_transmit(0x00);
  10.        
  11.         spi_transmit(0x00);
  12.        
  13. println("address");
  14.         /*for(unsigned char i = 0;i < 8;i++)
  15.         {
  16.                 data[i] = spi_receive();
  17. println("data");
  18.         }*/
  19.         data[0] = spi_receive();
  20. println("data");
  21.         data[1] = spi_receive();
  22. println("data");
  23.         data[2] = spi_receive();
  24. println("data");
  25.         data[3] = spi_receive();
  26. println("data");
  27.         PORTB |= 1 << PORTB2;
  28. }
复制代码

出0入0汤圆

 楼主| 发表于 2014-7-29 17:17:35 | 显示全部楼层
嗯 楼上说必须读取SPDR的值也读取过了呀
  1. unsigned char spi_receive(void)
  2. {
  3.         while(!(SPSR & (1 << SPIF)));
  4.         return SPDR;//<=======这里╮(╯▽╰)╭
  5. }
复制代码

这样算读取过了吗
avr的Data sheet里就是这样写的

出0入0汤圆

 楼主| 发表于 2014-7-29 17:53:15 | 显示全部楼层
alias 发表于 2014-7-29 16:09
楼主的 SPI 『接收』程式并没有对 SPDR 写入任意数值,AVR 为主的 SPI,跟本不会产生 SCK,何来接收资料? ...

而且应该不存在写的同时有数据传进来的情况

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-7-29 17:55:40 | 显示全部楼层
lcw_swust 发表于 2014-7-29 14:56
难道是没清标志?
SPIF可能一直有效

应该不是吧

我也试了一下
好像清没清标志位对结果没什么改变的样子

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-7-29 21:34:23 | 显示全部楼层
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)代替

出0入0汤圆

 楼主| 发表于 2014-7-30 11:40:26 | 显示全部楼层
嗯 好像这样是可以的
之前也用接收等待前加一句
SPDR = 0X00;
解决了这个问题
非常感谢啊

但是好像又有了新的问题
确实后面的数据能接到了
但是好像和我写进去的数据不一样
换句话说是不是接收到的并不是数据
通信还是没成功啊
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 10:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表