搜索
bottom↓
回复: 1

关于SPI双机互为主从的通信

[复制链接]

出0入0汤圆

发表于 2012-7-31 12:06:15 | 显示全部楼层 |阅读模式
SPI单主单从试了很多次,数据总是乱飞,现在决定用互为主从通信,依然碰到错误,错误如下。
每次开机后,主机发送数据给从机,从机返回这个数据到主机,但是主机收到的数据是0x00,开机后第一次通信总是这样,之后就正常了,第二次给从机发送数据就能返回正常的数据了。根据测试,从机收到的数据是正常的,但是将数据返回给主机,数据就不正常了,程序如下:
  1. #include "reg51.h"
  2. #define FOSC 22118400L
  3. #define BAUD (256 - FOSC / 32 / 115200)
  4. typedef unsigned char BYTE;
  5. typedef unsigned int WORD;
  6. typedef unsigned long DWORD;
  7. sfr AUXR = 0x8e; //Auxiliary register
  8. sfr SPSTAT = 0xcd; //SPI status register
  9. #define SPIF 0x80 //SPSTAT.7
  10. #define WCOL 0x40 //SPSTAT.6
  11. sfr SPCTL = 0xce; //SPI control register
  12. #define SSIG 0x80 //SPCTL.7
  13. #define SPEN 0x40 //SPCTL.6
  14. #define DORD 0x20 //SPCTL.5
  15. #define MSTR 0x10 //SPCTL.4
  16. #define CPOL 0x08 //SPCTL.3
  17. #define CPHA 0x04 //SPCTL.2
  18. #define SPDHH 0x00 //CPU_CLK/4
  19. #define SPDH 0x01 //CPU_CLK/16
  20. #define SPDL 0x02 //CPU_CLK/64
  21. #define SPDLL 0x03 //CPU_CLK/128
  22. sfr SPDAT = 0xcf; //SPI data register
  23. sbit SPISS = P1^3; //SPI slave select, connect to other MCU's SS(P1.4) pin
  24. sfr IE2 = 0xAF; //interrupt enable rgister 2
  25. #define ESPI 0x02 //IE2.1
  26. void InitUart();
  27. void InitSPI();
  28. void SendUart(BYTE dat); //send data to PC
  29. BYTE RecvUart(); //receive data from PC
  30. bit MSSEL; //1: master 0:slave
  31. ///////////////////////////////////////////////////////////
  32. void main()
  33. {
  34. InitUart(); //initial UART
  35. InitSPI(); //initial SPI
  36. IE2 |= ESPI;
  37. EA = 1;
  38. while (1)
  39. {
  40. if (RI)
  41. {
  42. SPCTL = SPEN | MSTR; //set as master
  43. MSSEL = 1;
  44. ACC = RecvUart();
  45. SPISS = 0; //pull low slave SS
  46. SPDAT = ACC; //trigger SPI send
  47. }
  48. }
  49. }
  50. ///////////////////////////////////////////////////////////
  51. void spi_isr() interrupt 9 using 1 //SPI interrupt routine 9 (004BH)
  52. {
  53. SPSTAT = SPIF | WCOL; //clear SPI status
  54. if (MSSEL)
  55. {
  56. SPCTL = SPEN; //reset as slave
  57. MSSEL = 0;
  58. SPISS = 1; //push high slave SS
  59. SendUart(SPDAT); //return received SPI data
  60. }
  61. else
  62. { //for salve (receive SPI data from master and
  63. SPDAT = SPDAT; // send previous SPI data to master)
  64. }
  65. }
  66. ///////////////////////////////////////////////////////////
  67. void InitUart()
  68. {
  69. SCON = 0x5a; //set UART mode as 8-bit variable baudrate
  70. TMOD = 0x20; //timer1 as 8-bit auto reload mode
  71. AUXR = 0x40; //timer1 work at 1T mode
  72. TH1 = TL1 = BAUD; //11 5200 bps
  73. TR1 = 1;
  74. }
  75. ///////////////////////////////////////////////////////////
  76. void InitSPI()
  77. {
  78. SPDAT = 0; //initial SPI data
  79. SPSTAT = SPIF | WCOL; //clear SPI status
  80. SPCTL = SPEN; //slave mode
  81. }
  82. ///////////////////////////////////////////////////////////
  83. void SendUart(BYTE dat)
  84. {
  85. while (!TI); //wait pre-data sent
  86. TI = 0; //clear TI flag
  87. SBUF = dat; //send current data
  88. }
  89. ///////////////////////////////////////////////////////////
  90. BYTE RecvUart()
  91. {
  92. while (!RI); //wait receive complete
  93. RI = 0; //clear RI flag
  94. return SBUF; //return receive data
  95. }
复制代码

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-8-26 17:28

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

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