找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4605|回复: 0
打印 上一主题 下一主题
收起左侧

STM32学习--读写AT24C02

[复制链接]
跳转到指定楼层
楼主
ID:81272 发表于 2015-5-27 16:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
完整源代码下载: 24c02.RAR (116.69 KB, 下载次数: 44)

  1. /*******************************************************************************

  2. STM32学习日志(6)----读写AT24C02

  3. 编译环境:        EWARM V5.30
  4. 硬件环境:        南京万利 EK-STM32F
  5. 主芯片        :        STM32F103VBT6
  6. STM32 FW:   V3.0.0
  7. 作者        :        szlihongtao
  8. 时间        :          2010-06-30
  9. *******************************************************************************/
  10. /**
  11.   ******************************************************************************
  12.   * @file    Project/Template/main.c
  13.   * @author  MCD Application Team
  14.   * @version V3.0.0
  15.   * @date    04/06/2009
  16.   * @brief   Main program body
  17.   ******************************************************************************
  18.   * @copy
  19.   *
  20.   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  21.   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  22.   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  23.   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  24.   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  25.   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  26.   *
  27.   * <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
  28.   */

  29. /* Includes ------------------------------------------------------------------*/
  30. #include "stm32f10x.h"
  31. #include "stm32_m.h"

  32. /** @addtogroup Template_Project
  33.   * @{
  34.   */

  35. /* Private typedef -----------------------------------------------------------*/
  36. /* Private define ------------------------------------------------------------*/
  37. /* Private macro -------------------------------------------------------------*/
  38. /* Private variables ---------------------------------------------------------*/
  39. /* Private function prototypes -----------------------------------------------*/
  40. /* Private functions ---------------------------------------------------------*/

  41. /**
  42.   * @brief  Main program.
  43.   * @param  None
  44.   * @retval : None
  45.   */
  46. //******************************************************************************
  47. // 延时50ms
  48. //******************************************************************************
  49. static void delay(void)
  50. {
  51.         INT32U i;
  52.     static INT32U jjj=5240*50;

  53.         for (i=0; i<jjj; i++);
  54. }
  55. //******************************************************************************
  56. static void delayms(INT16U cnt)
  57. {
  58.         INT16U i;

  59.         while(cnt--)
  60.                 for (i=0; i<7333; i++);
  61. }
  62. //******************************************************************************
  63. // 时钟设置初始化
  64. //******************************************************************************
  65. static void RCC_Configuration(void)
  66. {
  67.   ErrorStatus HSEStartUpStatus;
  68. /*
  69. RCC_AdjustHSICalibrationValue 调整内部高速晶振(HSI)校准值
  70. RCC_ITConfig 使能或者失能指定的RCC中断
  71. RCC_ClearFlag 清除RCC的复位标志位
  72. RCC_GetITStatus 检查指定的RCC中断发生与否
  73. RCC_ClearITPendingBit 清除RCC的中断待处理位
  74. */
  75.           /* RCC system reset(for debug purpose) */
  76.           // 时钟系统复位
  77.           RCC_DeInit();

  78.         // 使能外部的8M晶振
  79.         // 设置外部高速晶振(HSE)
  80.           /* Enable HSE */
  81.           RCC_HSEConfig(RCC_HSE_ON);

  82.         // 使能或者失能内部高速晶振(HSI)
  83.         RCC_HSICmd(DISABLE);

  84.         // 等待HSE起振
  85.         // 该函数将等待直到HSE就绪,或者在超时的情况下退出
  86.           /* Wait till HSE is ready */
  87.           HSEStartUpStatus = RCC_WaitForHSEStartUp();

  88.           if(HSEStartUpStatus == SUCCESS)
  89.           {
  90.             /* HCLK = SYSCLK */
  91.                 // 设置AHB时钟(HCLK)
  92.             RCC_HCLKConfig(RCC_SYSCLK_Div1);        // 72 MHz

  93.             /* PCLK1 = HCLK/2 */
  94.                 // 设置低速AHB时钟(PCLK1)
  95.             RCC_PCLK1Config(RCC_HCLK_Div2);        // 36 MHz

  96.             /* PCLK2 = HCLK */
  97.                 // 设置高速AHB时钟(PCLK2)
  98.             RCC_PCLK2Config(RCC_HCLK_Div1);        // 72 MHz

  99.             /* ADCCLK = PCLK2/8 */
  100.                 // 设置ADC时钟(ADCCLK)
  101.                    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

  102.                 // 设置USB时钟(USBCLK)
  103.                 // USB时钟 = PLL时钟除以1.5
  104.                 RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

  105.                 // 设置外部低速晶振(LSE)
  106.                 RCC_LSEConfig(RCC_LSE_OFF);

  107.                 // 使能或者失能内部低速晶振(LSI)
  108.                 // LSE晶振OFF
  109.                 RCC_LSICmd(DISABLE);

  110.                 // 设置RTC时钟(RTCCLK)
  111.                 // 选择HSE时钟频率除以128作为RTC时钟
  112.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);

  113.                 // 使能或者失能RTC时钟
  114.                 // RTC时钟的新状态
  115.                 RCC_RTCCLKCmd(DISABLE);

  116.             /* Flash 2 wait state */
  117.             FLASH_SetLatency(FLASH_Latency_2);

  118.             /* Enable Prefetch Buffer */
  119.             FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  120.             /* PLLCLK = 8MHz * 9 = 72 MHz */
  121.                 // 设置PLL时钟源及倍频系数
  122.             RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

  123.             /* Enable PLL */
  124.                 // 使能或者失能PLL
  125.             RCC_PLLCmd(ENABLE);

  126.             /* Wait till PLL is ready */
  127.                 // 检查指定的RCC标志位设置与否
  128.             while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  129.             {
  130.             }

  131.             /* Select PLL as system clock source */
  132.                 // 设置系统时钟(SYSCLK)
  133.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  134.             /* Wait till PLL is used as system clock source */
  135.                 // 返回用作系统时钟的时钟源
  136.             while(RCC_GetSYSCLKSource() != 0x08)
  137.             {
  138.             }
  139.   }

  140.         // 使能或者失能AHB外设时钟
  141.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1
  142.                                                         |RCC_AHBPeriph_DMA2
  143.                                                         |RCC_AHBPeriph_SRAM
  144.                                                         |RCC_AHBPeriph_FLITF
  145.                                                         |RCC_AHBPeriph_CRC
  146.                                                         |RCC_AHBPeriph_FSMC
  147.                                                         |RCC_AHBPeriph_SDIO,DISABLE);
  148.         // 使能或者失能APB1外设时钟
  149.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL,DISABLE);

  150.         // 强制或者释放高速APB(APB2)外设复位
  151.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ALL,ENABLE);
  152.         // 退出复位状态
  153.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ALL,DISABLE);

  154.         // 强制或者释放低速APB(APB1)外设复位
  155.         RCC_APB1PeriphResetCmd(RCC_APB1Periph_ALL,ENABLE);

  156.         // 强制或者释放后备域复位
  157.         RCC_BackupResetCmd(ENABLE);

  158.         // 使能或者失能时钟安全系统
  159.         RCC_ClockSecuritySystemCmd(DISABLE);
  160. }
  161. //******************************************************************************
  162. // NVIC设置
  163. //******************************************************************************
  164. static void NVIC_Configuration(void)
  165. {
  166. }
  167. //******************************************************************************
  168. // SysTick设置初始化
  169. //******************************************************************************
  170. static void SysTick_Config1(void)
  171. {
  172.         #define SystemFreq                72000000.0        // 单位为Hz
  173.         #define TB_SysTick                100000.0                // 单位为uS,与示波器实测一致

  174.         INT32U ticks;

  175.         ticks=(INT32U)((TB_SysTick/1000000.0)*SystemFreq);
  176.         ticks=ticks;
  177.         //SysTick_Config(ticks);
  178. }
  179. //******************************************************************************
  180. // GPIO设置
  181. //******************************************************************************
  182. static void GPIO_Configuration(void)
  183. {
  184.         GPIO_InitTypeDef GPIO_InitStructure;

  185.         // 使能或者失能APB2外设时钟
  186.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);

  187.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  188.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  189.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  190.           GPIO_Init(GPIOC, &GPIO_InitStructure);

  191.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
  192.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  193.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  194.           GPIO_Init(GPIOD, &GPIO_InitStructure);

  195.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;        // at24c02----SCLK
  196.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  197.           GPIO_Init(GPIOB, &GPIO_InitStructure);

  198.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;        // at24c02----SDA
  199.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  200.           GPIO_Init(GPIOB, &GPIO_InitStructure);

  201.         GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); // SCLK=1;SDA=1
  202. }
  203. //******************************************************************************
  204. // LED5亮
  205. //******************************************************************************
  206. void Led_RW_ON(void)
  207. {
  208.           GPIO_SetBits(GPIOC,GPIO_Pin_4);
  209. }
  210. //******************************************************************************
  211. // LED5灭
  212. //******************************************************************************
  213. void Led_RW_OFF(void)
  214. {
  215.           GPIO_ResetBits(GPIOC,GPIO_Pin_4);
  216. }
  217. //******************************************************************************
  218. // 主程序
  219. //******************************************************************************
  220. int main(void)
  221. {
  222.         INT8U i;

  223.         RCC_Configuration();
  224.           GPIO_Configuration();
  225.         NVIC_Configuration();
  226.           SysTick_Config1();
  227.         delay();

  228.         for (i=0;i<3;++i)
  229.         {
  230.                 Led_RW_ON();
  231.                 delayms(100);
  232.                 Led_RW_OFF();
  233.                 delayms(100);
  234.         }
  235.         at24c02_test();
  236. //------------------------------------------------------------------------------
  237.         for (;;)
  238.         {
  239.                 GPIOC->ODR ^= GPIO_Pin_7;        // led2 toogle
  240.                 delayms(100);
  241.         }
  242. }
  243. //******************************************************************************
  244. #ifdef  USE_FULL_ASSERT

  245. /**
  246.   * @brief  Reports the name of the source file and the source line number
  247.   *   where the assert_param error has occurred.
  248.   * @param file: pointer to the source file name
  249.   * @param line: assert_param error line source number
  250.   * @retval : None
  251.   */
  252. void assert_failed(uint8_t* file, uint32_t line)
  253. {
  254.   /* User can add his own implementation to report the file name and line number,
  255.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  256.   /* Infinite loop */
  257.   while (1)
  258.   {
  259.   }
  260. }
  261. #endif

  262. /**
  263.   * @}
  264.   */
  265. //******************************************************************************
  266. /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
  267. //******************************************************************************
  268. /*
  269.         LED2---------PC7
  270.         LED3---------PC6
  271.         LED4---------PC5
  272.         LED5---------PC4

  273.         KEY2---------PD3
  274.         KEY3---------PD4
  275. */
复制代码
  1. //***************************************************************************
  2. // at24c02的驱动程序
  3. // LihongTao
  4. //***************************************************************************
  5. // V0.01
  6. // 2009-06-05
  7. /***************************************************************************/
  8. #include "stm32f10x.h"
  9. #include "stm32_m.h"
  10. #include "at24c02.h"
  11. /***************************************************************************/
  12. #define                WriteDeviceAddress         0xa0
  13. #define                ReadDviceAddress                 0xa1

  14. static GPIO_InitTypeDef GPIO_InitStructure;
  15. /***************************************************************************/
  16. static void set_at24c02_sda(void)
  17. {
  18.         GPIO_SetBits(GPIOB,GPIO_Pin_7);
  19. }
  20. /***************************************************************************/
  21. static void clr_at24c02_sda(void)
  22. {
  23.         GPIO_ResetBits(GPIOB,GPIO_Pin_7);
  24. }
  25. /***************************************************************************/
  26. static void set_at24c02_sclk(void)
  27. {
  28.         GPIO_SetBits(GPIOB,GPIO_Pin_6);
  29. }
  30. /***************************************************************************/
  31. static void clr_at24c02_sclk(void)
  32. {
  33.         GPIO_ResetBits(GPIOB,GPIO_Pin_6);
  34. }
  35. /***************************************************************************/
  36. static void set_sda_input(void)
  37. {
  38.         set_at24c02_sda();

  39.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;        // SDA
  40.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  41.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  42.           GPIO_Init(GPIOB, &GPIO_InitStructure);                // 设置为输入上拉
  43. }
  44. /***************************************************************************/
  45. static void set_sda_output(void)
  46. {
  47.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;        // SDA
  48.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  49.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  50.           GPIO_Init(GPIOB, &GPIO_InitStructure);                // 设置为OC
  51. }
  52. /***************************************************************************/
  53. // 指令之间的延时,经过测试,必须要!!!!,延时过短的话会导致24c02读写出错
  54. //***************************************************************************
  55. static void delay10us(void)
  56. {
  57.         INT16U i;

  58.         for(i=0;i<500;++i);
  59. }
  60. //***************************************************************************
  61. // 启动
  62. // 当 SCL=1时 SDA  1---> 0
  63. /***************************************************************************/
  64. static void Start(void)
  65. {
  66.         clr_at24c02_sclk();
  67.         delay10us();

  68.         set_at24c02_sda();
  69.         delay10us();

  70.         set_at24c02_sclk();
  71.         delay10us();

  72.         clr_at24c02_sda();
  73.         delay10us();

  74.         clr_at24c02_sclk();
  75.         delay10us();
  76. }
  77. //***************************************************************************
  78. // 停止
  79. // 当 SCL=1时 SDA  0---> 1
  80. /***************************************************************************/
  81. static void Stop(void)
  82. {
  83.         clr_at24c02_sclk();
  84.         delay10us();

  85.         clr_at24c02_sda();
  86.         delay10us();

  87.         set_at24c02_sclk();
  88.         delay10us();

  89.         set_at24c02_sda();
  90.         delay10us();
  91. }
  92. //***************************************************************************
  93. // 不给24c02应答
  94. /***************************************************************************/
  95. static void NoAck(void)
  96. {
  97.         clr_at24c02_sclk();
  98.         delay10us();

  99.         set_at24c02_sda();
  100.         delay10us();

  101.         set_at24c02_sclk();
  102.         delay10us();
  103. }
  104. //***************************************************************************
  105. // 检测24c02的应答信号
  106. // 0表示有应答,1表示无应答
  107. /***************************************************************************/
  108. static bit TestAck(void)
  109. {
  110.         bit f_ack_at24c02;

  111.         set_at24c02_sda();
  112.         delay10us();

  113.         clr_at24c02_sclk();
  114.         delay10us();

  115.         set_sda_input();

  116.         delay10us();
  117.         f_ack_at24c02=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);

  118.         set_at24c02_sclk();
  119.         delay10us();

  120.         clr_at24c02_sclk();
  121.         delay10us();

  122.         set_sda_output();

  123.         return (f_ack_at24c02);
  124. }
  125. //***************************************************************************
  126. // 发送8bit数据
  127. /***************************************************************************/
  128. static void Write8Bit(INT8U input)
  129. {
  130.         INT8U i;

  131.         for(i=0;i<8;++i)
  132.         {
  133.                 if (input&0x80)
  134.                 {
  135.                         set_at24c02_sda();
  136.                 }
  137.                 else
  138.                 {
  139.                         clr_at24c02_sda();
  140.                 }

  141.                 set_at24c02_sclk();
  142.                 delay10us();
  143.                 input<<=1;

  144.                 clr_at24c02_sclk();
  145.                 delay10us();
  146.         }
  147. }
  148. //***************************************************************************
  149. // 往指定地址写数据
  150. // 写成功返回 1
  151. // 写出错返回 0
  152. /***************************************************************************/
  153. bit at24c02_wr_byte(INT8U RomAddress, INT8U data1)
  154. {
  155.         INT8U i;

  156.         Start();
  157.         Write8Bit(WriteDeviceAddress);

  158.         if (TestAck())
  159.         {
  160.                 Stop();
  161.                 return (0);
  162.         }

  163.         Write8Bit(RomAddress);
  164.         TestAck();

  165.         Write8Bit(data1);
  166.         TestAck();

  167.         Stop();

  168.         for(i=0;i<250;++i)
  169.                 delay10us();

  170.         return (1);
  171. }
  172. //***************************************************************************
  173. // 读取8bit数据
  174. /***************************************************************************/
  175. static INT8U Read8Bit(void)
  176. {
  177.         INT8U i,rbyte;

  178.         set_sda_input();
  179.         delay10us();

  180.         rbyte=0;
  181.         for(i=0;i<8;++i)
  182.         {
  183.                 rbyte<<=1;
  184.                 delay10us();

  185.                 if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7))
  186.                         rbyte|=0x01;

  187.                 delay10us();

  188.                 set_at24c02_sclk();
  189.                 delay10us();

  190.                 clr_at24c02_sclk();
  191.         }

  192.         set_sda_output();

  193.         return(rbyte);
  194. }
  195. /***************************************************************************/
  196. // 读成功返回 1
  197. // 读出错返回 0
  198. /***************************************************************************/
  199. bit at24c02_rd_byte(INT8U RomAddress,INT8U* data1)
  200. {
  201.         Start();
  202.         Write8Bit(WriteDeviceAddress);

  203.         if (TestAck())
  204.         {
  205.                 Stop();
  206.                 return (0);
  207.         }

  208.         Write8Bit(RomAddress);
  209.         TestAck();

  210.         Start();
  211.         Write8Bit(ReadDviceAddress);
  212.         TestAck();

  213.         *data1=Read8Bit();
  214.         NoAck();

  215.         Stop();
  216.         return (1);
  217. }

  218. #if 1
  219. const INT8U arr_random[10] =
  220.         {0x8c,0xf2,0x3a,0x77,0x44,0x33,0x22,0x9d,0xdd,0xbb};
  221. //*****************************************************************************
  222. void at24c02_test(void)
  223. {
  224.         static bit f_eeprom;
  225.         INT8U i,temp,arr_24c02[16];

  226.         for(i=0;i<10;++i)
  227.         {
  228.                 temp = arr_random[i];
  229.                 f_eeprom=at24c02_wr_byte(i,temp);
  230.                 i=i;
  231.         }

  232.         for(i=0;i<10;++i)
  233.                 arr_24c02[i]=0;

  234.         for(i=0;i<10;++i)
  235.         {
  236.                 f_eeprom=at24c02_rd_byte(i,&arr_24c02[i]);
  237.                 i=i;
  238.         }
  239.         i=0;        // 在此设置断点,可以查看从at24c02读出的数据

  240.         for(i=0;i<10;++i)
  241.                 arr_24c02[i]=0;
  242. }
  243. #endif
  244. /***************************************************************************/
  245. /***************************************************************************/
  246. /***************************************************************************/
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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