首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

【晒FRAM铁电存储器样片】+四川省TI杯省赛集训FRAM应用

【晒FRAM铁电存储器样片】+四川省TI杯省赛集训FRAM应用

哈哈哈,首先非常感谢富士通半导体的样片,让我有幸体验到FRAM的好处。本人只是一个电子小菜鸟,今年有幸参加四川省TI省赛,在学校集训器件得到了mb85rc64样片,于是顺便就是用到当时的集训题目上了。“双相信号发生器”。话不多说,直接上原理图。
原理图.png


接线.png


MCU使用的MSP430F1611,毕竟这是TI的比赛,哈哈哈。这片FRAM的接线方式与普通的存储器一样,便于替换,但是性能大大提高。
  至于mb85rc64的读写和其余的EEPROM一样,就不再多说了。附上程序源码。
下面是.c文件。
  1. #include <msp430x16x.h>
  2. #include "i2c.h"

  3. #define SCL_OUT_H P6OUT |= BIT6 //SCL = 1
  4. #define SCL_OUT_L P6OUT &=~ BIT6 //SCL = 0
  5. #define SCL_DIR_OUT P6DIR |= BIT6

  6. #define SDA_OUT_H P6OUT |= BIT7 //SDA = 1
  7. #define SDA_OUT_L P6OUT &=~ BIT7 //SDA = 0
  8. #define SDA_DIR_IN P6DIR &=~ BIT7; //I/O口为输入
  9. #define SDA_DIR_OUT P6DIR |= BIT7 //I/0口为输出
  10. #define SDA_IN ((P6IN >> 7) & 0x01) //Read SDA

  11. unsigned char ack;




  12. /*******************************************************************
  13. 起动总线函数
  14. 函数原型: void Start_I2c();
  15. 功能: 启动I2C总线,即发送I2C起始条件.

  16. ********************************************************************/
  17. void Start_I2c(void)
  18. {
  19. SCL_DIR_OUT; //SCK I/O口设为输出
  20. SDA_DIR_OUT; //SDA I/O口设为输出

  21. SDA_OUT_H; //发送起始条件的数据信号
  22. DelayNus(2);
  23. SCL_OUT_H ;
  24. DelayNus(6); //起始条件建立时间大于4.7us,延时
  25. SDA_OUT_L; //发送起始信号
  26. DelayNus(6); //起始条件建立时间大于4.7us,延时
  27. SCL_OUT_L; //钳住I2C总线,准备发送或接收数据
  28. }


  29. /*******************************************************************
  30. 结束总线函数
  31. 函数原型: void Stop_I2c();
  32. 功能: 结束I2C总线,即发送I2C结束条件.

  33. ********************************************************************/
  34. void Stop_I2c(void)
  35. {
  36. SCL_DIR_OUT;//SCK I/O口设为输出
  37. SDA_DIR_OUT;//SDA I/O口设为输出

  38. SDA_OUT_L;
  39. DelayNus(2);
  40. SCL_OUT_H;
  41. DelayNus(6);//起始条件建立时间大于4.7us,延时
  42. SDA_OUT_H;
  43. DelayNus(6);
  44. }



  45. void SendByte(unsigned char c)
  46. {
  47. unsigned char i;

  48. SCL_DIR_OUT;//I/O口设为输出
  49. SDA_DIR_OUT;//I/O口设为输出

  50. for(i=0;i<8;i++)
  51. {
  52. if((c<<i) & 0x80) SDA_OUT_H; //判断发送位
  53. else SDA_OUT_L;

  54. DelayNus(2);
  55. SCL_OUT_H;
  56. DelayNus(6);
  57. SCL_OUT_L;
  58. DelayNus(6);

  59. }
  60. //slave应答
  61. SDA_OUT_H;//SDA必须释放
  62. DelayNus(2);
  63. SCL_OUT_H;
  64. DelayNus(6);
  65. SDA_DIR_IN;//I/O口设为输入
  66. if (SDA_IN == 0X01) ack=0;
  67. else ack=1;//应答
  68. SCL_OUT_L;

  69. SCL_DIR_OUT;//I/O口设为输出
  70. SDA_DIR_OUT;//I/O口设为输出



  71. }

  72. unsigned char RcvByte(void)
  73. {
  74. unsigned char i;
  75. unsigned char c=0;

  76. SDA_OUT_H;//

  77. SCL_DIR_OUT;//I/O口设为输出
  78. SDA_DIR_IN;//I/O口设为输入
  79. for(i=0;i<8;i++)
  80. {
  81. SCL_OUT_L; //置时钟线为低,准备接收数据位
  82. DelayNus(6);//时钟低电平周期大于4.7μs
  83. SCL_OUT_H;
  84. DelayNus(2);
  85. c<<=1;
  86. if(SDA_IN)
  87. {
  88. c+=1; //读数据位,将接收的数据存c
  89. }
  90. }
  91. SCL_OUT_L;
  92. SCL_DIR_OUT;//I/O口设为输出
  93. SDA_DIR_IN;//I/O口设为输出
  94. return c;
  95. }

  96. void Ack_I2c(unsigned char a)
  97. {

  98. SCL_DIR_OUT;//I/O口设为输出
  99. SDA_DIR_OUT;//I/O口设为输出

  100. if(a==0) SDA_OUT_L; /*在此发出应答或非应答信号 */
  101. else SDA_OUT_H;

  102. DelayNus(6);
  103. SCL_OUT_H;
  104. DelayNus(6); /*时钟低电平周期大于4μs*/
  105. SCL_OUT_L; /*清时钟线,钳住I2C总线以便继续接收*/

  106. }



  107. unsigned char ISendByte(unsigned char sla,unsigned char c)
  108. {
  109. Start_I2c(); /*启动总线*/
  110. SendByte(sla); /*发送器件地址*/
  111. if(ack==0)return(0);
  112. SendByte(c); /*发送数据*/
  113. if(ack==0)return(0);
  114. Stop_I2c(); /*结束总线*/
  115. return(1);
  116. }

  117. unsigned char ISendStr(unsigned char sla,unsigned char suba,
  118. unsigned char *s,unsigned char no)
  119. {
  120. unsigned char i;

  121. Start_I2c(); /*启动总线*/
  122. SendByte(sla); /*发送器件地址*/
  123. if(ack==0)return(0);
  124. SendByte(suba); /*发送器件子地址*/
  125. if(ack==0)return(0);

  126. for(i=0;i<no;i++)
  127. {
  128. SendByte(*s); /*发送数据*/
  129. if(ack==0)return(0);
  130. s++;
  131. }
  132. Stop_I2c(); /*结束总线*/
  133. return(1);
  134. }

  135. unsigned char IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,
  136. unsigned char no)
  137. {
  138. unsigned char i;

  139. Start_I2c(); /*启动总线*/
  140. SendByte(sla); /*发送器件地址*/
  141. if(ack==0)return(0);
  142. SendByte(suba); /*发送器件子地址*/
  143. if(ack==0)return(0);

  144. Start_I2c();
  145. SendByte(sla+1);
  146. if(ack==0)return(0);

  147. for(i=0;i<no-1;i++)
  148. {
  149. *s=RcvByte(); /*发送数据*/
  150. Ack_I2c(0); /*发送就答位*/
  151. s++;
  152. }
  153. *s=RcvByte();
  154. Ack_I2c(1); /*发送非应位*/
  155. Stop_I2c(); /*结束总线*/
  156. return(1);
  157. }
复制代码
下面是头文件。
  1. #ifndef _I2C_H
  2. #define _I2C_H
  3. #define SDA_1 P4OUT|=BIT1 //SDA = 1
  4. #define SDA_0 P4OUT&=~BIT1 //SDA = 0
  5. #define SCL_1 P4OUT|=BIT0 //SCL = 1
  6. #define SCL_0 P4OUT&=~BIT0 //SCL = 0
  7. #define SCL_DIR_OUT P4DIR|=BIT0
  8. #define SDA_IN P4DIR&=~BIT1 //I/O口为输入
  9. #define SDA_OUT P4DIR|=BIT1 //I/0口为输出
  10. #define J_SDA_1_or_0 (P4IN&BIT1)==0x02

  11. unsigned long int flag=0x0000;
  12. //--------------------------------------------
  13. //--------以下为24C64读写子函数
  14. //DELAY 函数程序//功能:延时子程序
  15. //==========================================
  16. static void Delay(unsigned int n)
  17. {
  18. while(n!=0)
  19. {n--;}
  20. }
  21. //=========================================
  22. //START 函数程序
  23. //功能:开始闪存操作
  24. //==========================================
  25. void Start(void)
  26. {
  27. SCL_DIR_OUT;
  28. SDA_OUT;
  29. SDA_1;
  30. Delay(10);
  31. SCL_1;
  32. Delay(10);
  33. SDA_0;
  34. Delay(10);
  35. SCL_0;
  36. Delay(10);
  37. }
  38. //=========================================
  39. //STOP 函数程序
  40. //功能:停止闪存操作
  41. //==========================================
  42. void Stop(void)
  43. {
  44. SDA_0;
  45. Delay(10);
  46. SCL_1;
  47. Delay(10);
  48. SDA_1;
  49. Delay(10);
  50. }

  51. void TX_Byte(unsigned char WriteData)
  52. {
  53. unsigned char i,j;
  54. j=WriteData;
  55. SDA_OUT;
  56. for (i=0; i<8; i++)
  57. {
  58. if ((j&0x80)==0)
  59. { SDA_0;}
  60. else
  61. { SDA_1;}
  62. j <<=1;
  63. Delay(10);
  64. SCL_1;
  65. Delay(10);
  66. SCL_0;
  67. Delay(10);
  68. }
  69. }

  70. unsigned char RX_Byte(void)
  71. {
  72. unsigned char i;
  73. unsigned char TempData = 0;
  74. SDA_IN;
  75. for (i=0; i<8; i++)
  76. {
  77. Delay(10);
  78. SCL_1;
  79. Delay(10);
  80. TempData <<= 1;
  81. if (J_SDA_1_or_0)
  82. { TempData++; }
  83. SCL_0;
  84. Delay(10);
  85. }
  86. SDA_OUT;
  87. return(TempData);
  88. }
  89. //=========================================
  90. //ACK 函数程序
  91. //功能:挂高电平表示闪存时钟信号
  92. //==========================================
  93. void ReceiveAck(void)
  94. {
  95. SDA_IN;
  96. SCL_1;
  97. Delay(10);
  98. while (J_SDA_1_or_0)
  99. { }
  100. SCL_0;
  101. SDA_OUT;
  102. Delay(10);
  103. }

  104. unsigned char ReadWord(unsigned long int unit,unsigned char *s)
  105. {
  106. unsigned char i;
  107. unsigned char LowAdd = 0;
  108. unsigned char HighAdd = 0;
  109. unsigned char TempData = 0;
  110. LowAdd = (unsigned char)unit;
  111. HighAdd = (unsigned char)(unit >> 8);
  112. SDA_OUT;
  113. Start();
  114. TX_Byte(0xa0);
  115. ReceiveAck();
  116. TX_Byte(HighAdd);
  117. ReceiveAck();
  118. TX_Byte(LowAdd);
  119. ReceiveAck();
  120. Start();
  121. TX_Byte(0xa1);
  122. ReceiveAck();
  123. for(i = 0;i<5;i++)
  124. {
  125. *s= RX_Byte();
  126. *s++;
  127. }

  128. Stop();
  129. Delay(8000);
  130. return(TempData);
  131. }

  132. void WriteWord(unsigned long int unit, unsigned char *s)
  133. {
  134. unsigned char i;
  135. unsigned char LowAdd = 0;
  136. unsigned char HighAdd = 0;
  137. LowAdd = (unsigned char)unit;
  138. HighAdd = (unsigned char)(unit >> 8);
  139. Start();
  140. TX_Byte(0xa0);
  141. ReceiveAck();
  142. TX_Byte(HighAdd);
  143. ReceiveAck();
  144. TX_Byte(LowAdd);
  145. ReceiveAck();

  146. for(i = 0;i<5;i++)
  147. {
  148. TX_Byte(*s);
  149. *s++;
  150. }

  151. Stop();
  152. Delay(8000);
  153. }
  154. #endif
复制代码
结尾,再次感谢富士通半导体的样片。
返回列表