[STM8] CAT24WCxx存储器实验(I2C硬件接口)

[复制链接]
 楼主| 500days 发表于 2016-10-22 17:39 | 显示全部楼层 |阅读模式
实验目的
通过STM8芯片集成的I2C硬件接口读写CAT24C02存储器。
49.2 STM8芯片I2C总线连接管脚
图片1.png (36.24 KB, 下载次数: 0)
下载附件
8 小时前 上传


图49.1  I2C总线连接管脚

49.3 程序文件设计      49.3.1  main.c文件中的程序
主程序就实现初始化和调用驱动程序,这样主程序控制思路清晰,流程简单。要想了解全面详实的程序,请大家参考光盘(网盘)中程序及程序注释。
  1. /***********************************************************************
  2. *   说    明: CAT24WCxx存储器实验(I2C硬件接口)
  3. *   开发平台: 剑齿虎STM8开发板        
  4. *   作    者: 刘洋 张殿东
  5. *   版    本: V1.0
  6. *   日    期: 2016-05-03   
  7. *
  8. *   IAR开发环境    版本 V2.20.1
  9. *   ST库函数       版本 V2.2.0
  10. ***********************************************************************/
  11. #include "pbdata.h"//引入自定义公共头文件
  12. void BSP_Configuration(void);//硬件初始化函数声明
  13. /***********************************************************************
  14. *   函 数 名: main
  15. *   功能说明: c程序入口
  16. *   形    参:无
  17. *   返 回 值: 错误代码(无需处理)
  18. ***********************************************************************/
  19. int main(void)
  20. {
  21.   BSP_Configuration();//硬件驱动初始化函数
  22.   
  23.   AT24Cxx_Demo1();
  24.   
  25.   while(1)//主程序循环,反复执行循环体里的语句
  26.   {
  27.    
  28.   }
  29. }
  30. /***********************************************************************
  31. *   函 数 名: BSP_Configuration
  32. *   功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
  33. *   形    参:无
  34. *   返 回 值: 无
  35. ***********************************************************************/
  36. void BSP_Configuration(void)
  37. {  
  38.   CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//时钟速度为内部16M,1分频,
  39.   UART1_Congfiguration();//调用RS232串口1初始化函数
  40.   LED_Init();//调用LED初始化函数
  41.   I2C_EE_Init();
  42.   rim();//打开总中断
  43. }
  44. /*断言函数:它的作用是在编程的过程中为程序提供参数检查*/
  45. #ifdef USE_FULL_ASSERT
  46. void assert_failed(u8* file,u32 line)
  47. {
  48.   while(1)
  49.   {
  50.   }
  51. }
  52. #endif


 楼主| 500days 发表于 2016-10-22 17:40 | 显示全部楼层
pbdata.c文件中的程序
  1. #include "pbdata.h"   //引入自定义公共头文件
  2. /***************************************************************************
  3. *   函 数 名: delay_us
  4. *   功能说明: 微秒延时程序,注意此函数的运行环境为(16M时钟速度)
  5. *   形    参:nCount要延时的微秒数,输入nCount=1微妙
  6. *   返 回 值: 无
  7. ***************************************************************************/
  8. void delay_us(u16 nCount)   //16M 晶振时  延时 1个微妙
  9. {
  10.     nCount*=3;//等同于 nCount=nCount*3  相当于把nCount变量扩大3倍
  11.     while(--nCount);//nCount变量数值先减一,再判断nCount的数值是否大于0,大于0循环减一,等于0退出循环。
  12. }
  13. /***************************************************************************
  14. *   函 数 名: delay_ms
  15. *   功能说明: 毫秒延时程序,注意此函数的运行环境为(16M时钟速度)
  16. *   形    参:nCount要延时的毫秒数,输入nCount=1毫秒
  17. *   返 回 值: 无
  18. ***************************************************************************/
  19. void delay_ms(u16 nCount)  //16M 晶振时  延时 1个毫秒
  20. {
  21.     while(nCount--)//先判断while()循环体里的nCount数值是否大于0,大于0循环,减一执行循环体,等于0退出循环。
  22.     {
  23.         delay_us(1000);//调用微妙延时函数,输入1000等译演示1毫秒。
  24.     }
  25. }
  26. /***************************************************************************
  27. *   函 数 名: Get_decimal
  28. *   功能说明: 获得数值小数部分
  29. *   形    参:dt输入数据 deci小数位数,最多保留4位小数
  30. *   返 回 值: 放大后的小数部分
  31. ***************************************************************************/
  32. u16 Get_decimal(double dt,u8 deci)   //获得数值小数部分
  33. {
  34.     long x1=0;
  35.     u16 x2=0,x3=0;
  36.     if(deci>4) deci=4;
  37.     if(deci<1) deci=1;
  38.     x3=(u16)pow(10, deci);
  39.     x1=(long)(dt*x3);
  40.     x2=(u16)(x1%x3);
  41.     return x2;
  42. }
pbdata.h文件中的程序
  1. #ifndef _PBDATA_H//宏定义,定义文件名称
  2. #define _PBDATA_H
  3. #include "stm8s.h"//引入STM8的头文件
  4. #include <stdio.h>//需要引用这个头文件才能实现
  5. #include "math.h"//需要引用这个头文件才能实现
  6. #include "led.h"  //引用LED头文件
  7. #include "uart1.h"//引用RS232头文件
  8. #include "at24cxx.h"
  9. void delay_us(u16 nCount); //微秒延时程序
  10. void delay_ms(u16 nCount); //毫秒延时程序
  11. u16 Get_decimal(double dt,u8 deci);   //获得数值小数部分
  12. #endif //定义文件名称结束


 楼主| 500days 发表于 2016-10-22 17:41 | 显示全部楼层
at24cxx.c文件中的程序
  1. #include "pbdata.h"
  2. void I2C_EE_Init(void)
  3. {
  4.     I2C_Init(I2C_Speed,0,I2C_DUTYCYCLE_2,I2C_ACK_CURR,I2C_ADDMODE_7BIT,16);//I2C初始化
  5.     I2C_Cmd(ENABLE);//使能I2C功能
  6. }
  7. void I2C_EE_BufferWrite(u8* pBuffer,u16 WriteAddr,u8 NumByte)//I2C写函数
  8. {
  9.     while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));//获取指定的标志状态(判断总线状态)
  10.     I2C_GenerateSTART(ENABLE); //I2C起始信号   
  11.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));//检测指定信号状态(EV5事件)如果没有发送完成在这里等待
  12.     if(EE_TYPE>AT24C16)
  13.     {
  14.         I2C_Send7bitAddress(EEPROM_ADDRESS,I2C_DIRECTION_TX);
  15.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  16.         I2C_SendData((u8)(WriteAddr>>8));
  17.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  18.     }
  19.     else
  20.     {   //1010 000 0        I2C_Send7bitAddress(EEPROM_ADDRESS+((WriteAddr/256)<<1),I2C_DIRECTION_TX);
  21.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  22.     }
  23.     I2C_SendData((u8)(WriteAddr));
  24.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  25.     while(NumByte--)
  26.     {
  27.         I2C_SendData(*pBuffer);
  28.         pBuffer++;
  29.         if(NumByte==0)
  30.         {
  31.             while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  32.         }
  33.         else
  34.         {
  35.             while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  36.         }        
  37.     }
  38.     I2C_GenerateSTOP(ENABLE);     
  39. }
  40. void I2C_EE_BufferRead(u8* pBuffer,u16 ReadAddr,u8 NumByte)
  41. {
  42.     while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  43.     I2C_GenerateSTART(ENABLE);   
  44.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
  45.     if(EE_TYPE>AT24C16)
  46.     {
  47.         I2C_Send7bitAddress(EEPROM_ADDRESS,I2C_DIRECTION_TX);
  48.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  49.         I2C_SendData((u8)(ReadAddr>>8));
  50.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  51.     }
  52.     else
  53.     {   //1010 000 0
  54.     I2C_Send7bitAddress(EEPROM_ADDRESS+((ReadAddr/256)<<1),I2C_DIRECTION_TX);
  55.         while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  56.     }
  57.     I2C_SendData((u8)(ReadAddr));
  58.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  59.     I2C_GenerateSTART(ENABLE);   
  60.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
  61.     I2C_Send7bitAddress(EEPROM_ADDRESS,I2C_DIRECTION_RX);
  62.     while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  63.     while(NumByte)
  64.     {
  65.         if(NumByte==1)
  66.         {
  67.             I2C_AcknowledgeConfig(I2C_ACK_NONE);
  68.             I2C_GenerateSTOP(ENABLE);
  69.         }
  70.         if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
  71.         {
  72.             *pBuffer=I2C_ReceiveData();
  73.             pBuffer++;
  74.             NumByte--;
  75.         }
  76.     }
  77.     I2C_AcknowledgeConfig(I2C_ACK_CURR);
  78. }
  79. void AT24Cxx_Demo1(void)
  80. {
  81.     u8 TX_buf[]="LY-STM8";//测试数据
  82.     u8 RX_buf[8];
  83.     delay_ms(2);
  84.     I2C_EE_BufferWrite(TX_buf,0x20,7);
  85.     delay_ms(20);
  86.     I2C_EE_BufferRead(RX_buf,0x20,7);
  87.     RX_buf[7]='\0';//加上'\0',数组才能正确打印出来
  88.     printf("%s\r\n",RX_buf);   
  89. }


 楼主| 500days 发表于 2016-10-22 17:41 | 显示全部楼层
at24cxx.h文件中的程序
  1. #ifndef _AT24CXX_H  //宏定义,定义文件名称
  2. #define _AT24CXX_H
  3. #include "stm8s.h"//引用STM8头文件
  4. #define AT24C01  127
  5. #define AT24C02  255
  6. #define AT24C04  511
  7. #define AT24C08  1023
  8. #define AT24C16  2047
  9. #define AT24C32  4095
  10. #define AT24C64  8191
  11. #define AT24C128 16383
  12. #define AT24C256 32767
  13. #define EE_TYPE  AT24C02
  14. #define I2C_Speed 100000
  15. #define EEPROM_ADDRESS 0xA0
  16. void I2C_EE_Init(void);
  17. void I2C_EE_BufferWrite(u8* pBuffer,u16 WriteAddr,u8 NumByte);
  18. void I2C_EE_BufferRead(u8* pBuffer,u16 ReadAddr,u8 NumByte);
  19. void AT24Cxx_Demo1(void);
  20. #endif
at24cxx.h文件中的程序
  1. #ifndef _AT24CXX_H  //宏定义,定义文件名称
  2. #define _AT24CXX_H
  3. #include "stm8s.h"//引用STM8头文件
  4. #define AT24C01  127
  5. #define AT24C02  255
  6. #define AT24C04  511
  7. #define AT24C08  1023
  8. #define AT24C16  2047
  9. #define AT24C32  4095


 楼主| 500days 发表于 2016-10-22 17:42 | 显示全部楼层
at24cxx.h文件中的程序
  1. #ifndef _AT24CXX_H  //宏定义,定义文件名称
  2. #define _AT24CXX_H
  3. #include "stm8s.h"//引用STM8头文件
  4. #define AT24C01  127
  5. #define AT24C02  255
  6. #define AT24C04  511
  7. #define AT24C08  1023
实验效果      
通讯过程如“图49.2  I2C总线通讯效果”,没按一次复位键,I2C工作一次,打印出数组“LY_STM8”。


图49.2  I2C总线通讯效果

dongnanxibei 发表于 2016-10-22 18:07 | 显示全部楼层
断言函数:它的作用是在编程的过程中为程序提供参数检查
楼主,我不是很懂这个,能否给详细说说。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

120

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部