不能下载附件的请看这里:论坛限制流量,临时解决方法
返回列表 回复 发帖

请帮我看看PIC与X5045的程序问题在哪?

这个程序师从51上移植过来的SPI的协议时测试通过的,但是调了很久就是没有把它弄出来,期间改变晶振大小,调整端口输出位,硬件也检查了很多次,器件是在51板上测试过的,确实找不到问题在哪里,希望请高人相助!
  1. //模拟SPI总线方式与X5045的EEPROM的读写
  2. //主程序中通过byte_write(6,6)将数据写入地址6中,通过ee_date[0]= byte_read(6);读出数据
  3. //由display();输出ee_date[0]中的数据到LED上
  4. //单片机采用PIC16F877A,测试X5045数据读写失败(LED一直显示0000),注此程序在51系列单片机测试通过的。
  5. #include<pic.h>
  6. __CONFIG(0x1832);        
  7. //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡

  8. /* #define   c_s      RC2
  9. #define   clk      RC3
  10. #define   d_i      RC5
  11. #define   d0       RC4 */
  12. #define   ee_addr  0x5
  13. #define   nop() asm("nop")
  14. const char ee_data_write[]={0x56,0x78};
  15. unsigned char ee_date[4];
  16. const char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

  17. void      init();
  18. void      display();
  19. void      delay();
  20. #define uchar unsigned char
  21. #define uint unsigned int
  22. //x5045和51的连接方法
  23. #define CS   RC2  
  24. #define SO   RC4
  25. #define SI   RC5
  26. #define SCK  RC3
  27. //定义寄存器指令
  28. #define WREN 0x06 // 写入使能指令(WREN)
  29. #define WRDI 0x04 // 写入禁止指令(WRDI)
  30. #define WRSR 0x01 // 写入状态寄存器指令(WRSR)
  31. #define RDSR 0x05 // 读取状态寄存器指令(RDSR)
  32. #define WRITE 0x02 // 写入存储器指令(WRITE)
  33. #define READ 0x03 // 读取存储器指令(READ)
  34. #define nop() asm("nop")
  35.                        
  36. #define STATUS_REG 0x00 // 要写入到状态寄存器的值
  37. #define MAX_POLL 0x99 // 最在查询次数m number of

  38. void outbyt(unsigned char write_data)
  39. {
  40.      unsigned char i;  
  41.        for(i = 0; i < 8; i++)
  42.      {
  43.        SCK = 0;
  44.      SI = (bit)(write_data & 0x80); //传送一个位到SI
  45.      write_data <<= 1;
  46.      nop();
  47.      nop();
  48.      nop();
  49.      nop();
  50.      nop();
  51.      nop();
  52.      SCK = 1;
  53.      nop();
  54.      nop();
  55.      nop();
  56.      nop();
  57.      nop();
  58.      nop();
  59.       }
  60.      SI = 0;
  61. }
  62. unsigned char inbyt()
  63. {
  64.       unsigned char i;
  65.       unsigned char read_data=0;

  66. for(i = 0; i < 8; i++)
  67.       {
  68.         SCK = 0;
  69.         read_data <<= 1;
  70.         nop();
  71.         nop();
  72.         nop();
  73.         nop();
  74.         nop();
  75.         nop();
  76.         SCK = 1;
  77.          read_data |= (unsigned char)SO;
  78.         nop();
  79.         nop();
  80.         nop();
  81.         nop();
  82.         nop();
  83.         nop();
  84.       }
  85.      return read_data;
  86. }
  87. void wren_cmd()
  88. {

  89.       CS = 0;           
  90.       outbyt(WREN); // 传送写入使能指令
  91.       CS = 1;
  92. }            

  93. void wrdi_cmd()
  94. {
  95.      CS = 0;           
  96.      outbyt(WRDI); // 传送写入禁止指令
  97.     CS = 1;
  98. }

  99. unsigned char rdsr_cmd()
  100. {
  101.       unsigned char status;  
  102.         CS = 0;   
  103.        outbyt(RDSR); // 传送状态寄存器读取指令
  104.       status = inbyt(); // 读取状态寄存
  105.      CS = 1;
  106.        return status;
  107. }
  108. void wip_poll()
  109. {
  110.    unsigned char i; // 设置最大的查询次数

  111. //// 如果WIP位为'1'并且未达到最大查询次数, 则继续查询
  112. //// 如果WIP位为'0', 则写入周期完成, 返回
  113.    for(i = 0; i < MAX_POLL; i++)
  114.    {
  115.       if(rdsr_cmd() & 0x01) // 读取状态寄存器
  116.       {
  117.         continue;
  118.       }
  119.       return;
  120.     }
  121. }

  122. void wrsr_cmd()
  123. {
  124.      CS = 0;
  125.      outbyt(WRSR); // 传送状态寄存器写入指令
  126.       outbyt(STATUS_REG); // 传送要写入的数据
  127.      CS = 1;
  128.    wip_poll(); // 检测写入进度
  129. }

  130. void byte_write(unsigned int addr,unsigned char dat)
  131. {
  132.        wren_cmd();
  133.    CS = 0;
  134.       if(addr & 0x100)
  135.           outbyt(WRITE | 0x08); //传送写入指令和地址最高位"1"
  136.       else
  137.           outbyt(WRITE); // 传送写入指令和地址最高位"0"
  138.      outbyt(addr); // 传送地址低字节      
  139.        outbyt(dat); // 传送数据字节  

  140. CS = 1;
  141.      wip_poll(); // 检测写入进度
  142. }
  143. unsigned char byte_read(unsigned int addr)
  144. {
  145.      unsigned char read_data;  
  146.         CS = 0;   
  147.         if(addr & 0x100)
  148.             outbyt(READ | 0x08);// 传送读取指令和地址最高位"1"
  149.         else     
  150.            outbyt(READ); // 传送读取指令和地址最高位"0"
  151.       

  152. outbyt(addr); // 传送地址低字节

  153. read_data = inbyt(); // 读取字节
  154.       CS = 1;
  155.        return read_data;
  156. }
  157. void rst_wdog()
  158. {
  159.    CS = 0;
  160.    _nop_();_nop_();
  161.     CS = 1;
  162. }
  163. void  main()
  164.   {
  165.      init();
  166.      while(1)
  167.        {
  168.            byte_write(6,6);
  169.            delay();
  170.           // byte_write(9,9);
  171.            delay();
  172.            ee_date[0]= byte_read(6);
  173.          //  ee_date[1]= byte_read(9);
  174.            display();
  175.        }
  176.    }

  177. void init()
  178.    {
  179.      OPTION=0;
  180.      ADCON1=0X07;
  181.      TRISA=0X30;
  182.      TRISB=0X03;
  183.      TRISC=0X10;
  184.      TRISD=0X00;
  185. //     PORTD=0XFF;
  186.      SSPSTAT=0X80;
  187.      SSPCON=0X31;
  188.      INTCON=0X00;
  189.      PIR1=0X00;
  190.      CS=0;
  191.    }
  192. void display()
  193.    {
  194.      int i;
  195.      i=ee_date[0]&0xf0;
  196.      i=i>>4;
  197.      PORTD=table;
  198.      PORTA=0x37;
  199.      delay();
  200.      i=ee_date[0]&0x0f;
  201.      PORTD=table;
  202.      PORTA=0x3b;
  203.      delay();
  204.      
  205.      i=ee_date[1]&0xf0;
  206.      i=i>>4;
  207.      PORTD=table;
  208.      PORTA=0x3d;
  209.      delay();
  210.      i=ee_date[1]&0x0f;
  211.      PORTD=table;
  212.      PORTA=0x3e;
  213.      delay();
  214.    }

  215. void  delay()
  216.    {
  217.      int i;
  218.      for(i=100;i>0;i--);
  219.    }
复制代码
社区口号:开发路上不能单打独斗,帮助需要帮助的人,是对帮助过你的人最大的感谢!
我选择了原代码可怎么没有那种效果呢?
社区口号:开发路上不能单打独斗,帮助需要帮助的人,是对帮助过你的人最大的感谢!
这么样的程序很难仔细看问题。建议这么找:

此程序源于51,是否在51肯定正确,移植是否有问题;
模拟SPI,其实很容易处理,只要符合时序就可以,开始用低速运行,或者单步执行都可以;
调试程序切记大段,最好一部分一部分逐步调试
首先非常感谢“莫名其妙”,这个程序以前在51上是测试过的,而且在使用中也没有什么问题,就是在移植到PIC上才出现问题的,在移植的过程中,主要进行了一下步骤:
    1.更改了端口定义。
    2.添加了PIC的CONFIG寄存器设置。
    3.对PIC的端口I/O组态进行了配置。
    4.由于怀疑他们两种处理器的速率不同造成的PIC与X5045通信错误,所以在位操作的函数中加入了NOP指令,可是还是不能正常通信。
返回列表