微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 读写93C66A问题

读写93C66A问题

时间:10-02 整理:3721RD 点击:
C51单片机读写93C66A不正常,程序如下,那位大侠用过的指点一下.
//-----------------------------------------------------
//Enable Write  写使能
//-----------------------------------------------------
void EnWr(void)
{
           uint8  i;
           uint16 comm;
        //启动总线
           ioEeCs=0;
        nop;
        nop;
        ioClk=0;
        nop;
        nop;
        ioEeCs=1;
        nop;
        nop;
        //发送指令
           comm = 0x9800;
           for(i=0;i<12;i++)
           {
      ioClk=0;
          nop;
          nop;
      comm<<=1;
      ioSdo=CY;
          nop;
          nop;
      ioClk=1;
          nop;
          nop;
           }
           //停止总线
           ioEeCs=0;
}
//-----------------------------------------------------
//Disable Write  写保护
//-----------------------------------------------------
void DisWr(void)
{
           uint8   i;
           uint16  comm;
        //启动总线
           ioEeCs=0;
        nop;
        nop;
        ioClk=0;
        nop;
        nop;
        ioEeCs=1;
        nop;
        nop;
        //发送指令
        comm = 0x8000;
           for(i=0; i<12; i++)
           {
      ioClk=0;
          nop;
          nop;
      comm<<=1;
      ioSdo=CY;
          nop;
          nop;
      ioClk=1;
          nop;
          nop;
        }
           ioEeCs=0;
}
//-----------------------------------------------------
//写数据
//-----------------------------------------------------
void WriteEe1Bey(uint8 Addr,uint8 InData)
{
        uint8 i;
           uint16  comm;
           uint16  Delays;
           //启动总线
        ioEeCs=0;
        nop;
        nop;
        ioClk=0;
        nop;
        nop;
        ioEeCs=1;
        nop;
        nop;
        //发送指令
        comm = 0x0A00 + (uint16)(Addr);
           comm <<= 4;
           for(i = 0; i < 12; i++)
           {
              ioClk = 0;
                nop;
                nop;
              comm <<= 1;
              ioSdo = CY;
                nop;
                nop;
              ioClk = 1;
                nop;
                nop;
           }
           //发送数据
           for(i = 0;i < 8; i++)
           {
              ioClk=0;
                nop;
                nop;
              InData <<= 1;
              ioSdo=CY;
                nop;
                nop;
              ioClk=1;
                nop;
                nop;
           }
           ioEeCs=0;
        nop;
        nop;
        ioEeCs=1;
        nop;
        nop;
        Delays = 0;
           while(!ioSdi)
           {
             Delays++;
             if(Delays>30000)
                {
                        break;
                }
           }
           ioEeCs=0;
}
void WriteEe(uint8 Addr,uint16 InData)
{
           uint8 dataH;
           uint8 dataL;
           dataL = InData & 0xFF;
           InData = InData >> 8;
           dataH = InData & 0xFF;
           Addr = Addr & 0x3f;
           Addr = Addr * 2;
        EnWr();
           WriteEe1Bey(Addr, dataH);
           Addr ++;
           WriteEe1Bey(Addr, dataL);
           DisWr();
}
//-----------------------------------------------------
//读数据
//-----------------------------------------------------
uint16 ReadEe(uint8 Addr)
{
        uint8  i;
           uint16 comm;
           uint16 EeValue;
           Addr = Addr & 0x3f;
           Addr = Addr * 2;
        //启动总线
           ioEeCs=0;
        nop;
        nop;
        ioClk=0;
        nop;
        nop;
        ioEeCs=1;
        nop;
        nop;
        //发送指令
        comm = 0x0C00 + (uint16)(Addr);
           comm <<= 4;
           for(i=0;i<12;i++)
           {
              ioClk=0;
                nop;
                nop;
              comm<<=1;
              ioSdo=CY;
                nop;
                nop;
              ioClk=1;
                nop;
                nop;
           }
           EeValue=0;
           for(i=0;i<16;i++)
           {
              ioClk=0;
                EeValue<<=1;
                ioClk=1;
                nop;
                nop;
              if(ioSdi == 1)
                {
                        EeValue|=1;
                }
           }
           ioEeCs=0;
           return EeValue;
}

keil4 编写的93C66的51程序,可在89C51,89C52,89C58,89C516上直接移植。:
http://download.csdn.net/detail/wxjcan/4088803

93C66我也没用过,发个驱动程序你参考下;

  1. /*93c66 操作子程序 */
  2. /* 注意:这里使用的93c66 为8 位结构的EEROM*/
  3. void delay1(unsigned int num)
  4. {
  5. while(num!=0){num=num-1;}
  6. }
  7. /***********************************************************************/
  8. /*名称: START_93c66() */
  9. /*说明: 用于93c66 的启动,防止由于CS_93c66 的改动而引起数据时序混乱 */
  10. /***********************************************************************/
  11. void START_93c66()
  12. {
  13. DO_93c66=1; /*防止DO 由于是低电平而无法输入*/
  14. CS_93c66=1;
  15. /*开启93c66*/
  16. CS_93c66=0;
  17. DI_93c66=0;
  18. SK_93c66=0;
  19. CS_93c66=1;
  20. delay1(1000);
  21. }
  22. /***************************************************************************/
  23. /*名称:END_93c66() */
  24. /*说明:用于93c66 的结束,防止由于CS_93c66 的改动而引起数据线为0 而无法输入*/
  25. /***************************************************************************/
  26. void END_93c66()
  27. {
  28. CS_93c66=0;
  29. DI_93c66=1;
  30. SK_93c66=1;
  31. }
  32. /***********************************************************************/
  33. /*名称:SEND_DATA_93c66() */
  34. /*说明:在93c66 启动下,送入指定位数的数据 */
  35. /*输入: op_data 要输入的数据 */
  36. /* num 输入的位数 */
  37. /**********************************************************************/
  38. void SEND_DATA_93c66(unsigned int op_data,unsigned char num)
  39. {
  40. unsigned char temp1;
  41. op_data=op_data<<(16-num); /*左移去掉无用位*/
  42. for(temp1=0;temp1<num;temp1++)
  43. {
  44. if( (op_data&0X8000)==00 )
  45. {DI_93c66=0;}
  46. else
  47. {DI_93c66=1;}
  48. SK_93c66=1;//SK_93c66=1;SK_93c66=1;SK_93c66=1;
  49. SK_93c66=0;
  50. op_data=op_data<<1;
  51. }
  52. }
  53. /***********************************************************************/
  54. /*名称: EWEN_93c66() */
  55. /*说明: 93c66 的编程启动.操作码(100 11XXXXXXX) */
  56. /***********************************************************************/
  57. void EWEN_93c66()
  58. {
  59. START_93c66();
  60. SEND_DATA_93c66(0X0013,0X05); /*送入3 位操作码+11*/
  61. SEND_DATA_93c66(0X0000,Addr_bit-2); /*送入9 位地址*/
  62. END_93c66();
  63. }
  64. /***********************************************************************/
  65. /*名称: EWDS_93c66() */
  66. /*说明: 93c66 的编程关闭.操作码(100 00XXXXXXX) */
  67. /**********************************************************************/
  68. void EWDS_93c66()
  69. {
  70. START_93c66();
  71. SEND_DATA_93c66(0X0004,0X03);
  72. SEND_DATA_93c66(0X0000,Addr_bit);
  73. END_93c66();
  74. }
  75. /***********************************************************************/ /*名称:READ() */
  76. /*说明:93c66 的字读取程序 */
  77. /*输入:要读取的字节地址(9 位) */
  78. /*输出:读取的字数值 */
  79. /**********************************************************************/
  80. unsigned char READ(unsigned int address)
  81. {
  82. unsigned char temp1;
  83. unsigned char temp2;
  84. START_93c66();
  85. SEND_DATA_93c66(0X0006,0X03);
  86. SEND_DATA_93c66(address,Addr_bit);
  87. temp2=0; /*存放返回数据的缓冲先清零*/
  88. for(temp1=0;temp1<8;temp1++) /*循环读出8 个数据*/
  89. {
  90. temp2=temp2<<1;
  91. SK_93c66=1;SK_93c66=0;
  92. if(DO_93c66==1)
  93. {temp2=temp2|0X01;}
  94. }
  95. END_93c66();
  96. return temp2;
  97. }
  98. /**********************************************************************/
  99. /*名称:WRITE() */
  100. /*说明:93c66 的字写入程序 */
  101. /*输入: address 要写入的字节地址(9 位) */
  102. /* op_data 要写入的数据(8 位) */
  103. /*输出: 读取的字数值 */
  104. /**********************************************************************/
  105. unsigned char WRITE(unsigned int address,unsigned int op_data)
  106. {
  107. unsigned char temp1;
  108. unsigned int temp2;
  109. EWEN_93c66();
  110. START_93c66();
  111. SEND_DATA_93c66(0X0005,0X03);
  112. SEND_DATA_93c66(address,Addr_bit);
  113. SEND_DATA_93c66(op_data,0X08);
  114. CS_93c66=0;
  115. CS_93c66=1;
  116. temp1=1;
  117. temp2=50000; /*设置一个最大延时等待数值.注意在不同的晶振下延时是不同的*/
  118. while(!DO_93c66)
  119. {
  120. temp2=temp2-1;
  121. if(temp2==0)
  122. {
  123. temp1=0;//temp1=0则写入失败
  124. CD_3=0;
  125. P0=0X08;
  126. delay1(60000);
  127. P0=0;
  128. CD_3=1;
  129. //break; /*最大等待延时后说明擦除失败*/
  130. }
  131. }
  132. END_93c66();
  133. EWDS_93c66();
  134. return temp1;
  135. }
  136. /***********************************************************************/
  137. /*名称:ERASE() */
  138. /*说明:93c66 的字擦除程序 */
  139. /*输入: address 要擦除的字地址(9 位) */
  140. /**********************************************************************/
  141. unsigned char ERASE(unsigned char address)
  142. {data unsigned char temp1;
  143. data unsigned int temp2;
  144. EWEN_93c66();
  145. START_93c66();
  146. SEND_DATA_93c66(0X07,0X03);
  147. SEND_DATA_93c66(address,0X06);
  148. CS_93c66=0;
  149. CS_93c66=1;
  150. temp1=1;
  151. temp2=50000;
  152. while(!DO_93c66)
  153. {temp2=temp2-1;
  154. if(temp2==0)
  155. {temp1=0;
  156. break;
  157. }
  158. }
  159. END_93c66();
  160. EWDS_93c66(); //返回表示擦除状态的特征
  161. return temp1;
  162. }

  163. /**********************************************************************/
  164. /*名称:ERAL() */
  165. /*说明:93c66 的全部擦除程序 */
  166. /**********************************************************************/
  167. unsigned char ERAL()
  168. {data unsigned char temp1;
  169. data unsigned int temp2;
  170. EWEN_93c66();
  171. START_93c66();
  172. SEND_DATA_93c66(0X04,0X03);
  173. SEND_DATA_93c66(0X20,0X06);
  174. CS_93c66=0;
  175. CS_93c66=1;
  176. temp1=1;
  177. temp2=50000;
  178. while(!DO_93c66)
  179. {temp2=temp2-1;
  180. if(temp2==0)
  181. {temp1=0;
  182. break;
  183. }
  184. }
  185. END_93c66();
  186. EWDS_93c66(); //返回表示擦除状态的特征
  187. return temp1;
  188. }
  189. /***********************************************************************/
  190. /*名称:WRAL() */
  191. /*说明:93c66 的写全部程序 */
  192. /*输入: op_data 要写入的数据(16 位) */
  193. /*输出: 读取的字数值 */
  194. /***********************************************************************/
  195. unsigned char WRAL(unsigned int op_data)
  196. {data unsigned char temp1;
  197. data unsigned int temp2;
  198. EWEN_93c66();
  199. START_93c66();
  200. SEND_DATA_93c66(0X04,0X03);
  201. SEND_DATA_93c66(0X10,0X06);
  202. SEND_DATA_93c66(op_data,0X10);
  203. CS_93c66=0;
  204. CS_93c66=1;
  205. temp1=1;
  206. temp2=50000; //设置一个最大延时等待数值.注意在不同的晶振下延时是不同的
  207. while(!DO_93c66)
  208. {temp2=temp2-1;
  209. if(temp2==0)
  210. {temp1=0;
  211. break;
  212. }
  213. }
  214. END_93c66();
  215. EWDS_93c66();
  216. return op_data;
  217. }

复制代码

感谢你,我参考了你的程序。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top