zoukankan      html  css  js  c++  java
  • rtthread 添加 i2c 24c02

    查询iic配置过程

    文件路径: /drivers/board.h

    1.使能RTT i2c驱动

      

     2.使能I2C总线

      打开 /drivers/board.h   

      #define BSP_USING_I2C1
      #ifdef BSP_USING_I2C1
      #define BSP_I2C1_SCL_PIN GET_PIN(H, 4)
      #define BSP_I2C1_SDA_PIN GET_PIN(H, 5)
      #endif

    3.验证

      

    #include <rtthread.h>
    #include <rtdevice.h>
    #include <board.h>
    
    #include <string.h>
    #include <stdlib.h>
    
    #define DBG_ENABLE
    #define DBG_SECTION_NAME "fm24xx"
    #define DBG_LEVEL DBG_LOG
    #define DBG_COLOR
    #include <rtdbg.h>
    
    #include "bsp_fm24cl16b.h"
    /*
    fm24cl16b
    16kb -->2kB
    
    器件地址
     1 0 1 0  A2 A1 A0  R/W
    
    地址為11位:3bit 段地址  8bit行地址
    0X000      ~   0X07FF
    0000 0000   ~  0000 0111 1111 1111
    
    */
    
    
    
    #define FM24CXX_ADDR (0x50)                      //A0 A1 A2 connect GND
    
    #if (EE_TYPE == FM24C02)
        #define FM24CXX_PAGE_BYTE               256
        #define FM24CXX_MAX_MEM_ADDRESS         256
    #elif (EE_TYPE == FM24C04)
        #define FM24CXX_PAGE_BYTE               256
        #define FM24CXX_MAX_MEM_ADDRESS         512
    #elif (EE_TYPE == FM24C08)
        #define FM24CXX_PAGE_BYTE               256
        #define FM24CXX_MAX_MEM_ADDRESS         1024
    #elif (EE_TYPE == FM24C16)
        #define FM24CXX_PAGE_BYTE               256
        #define FM24CXX_MAX_MEM_ADDRESS         2048
    #endif
    
    #ifndef EEP_I2CBUS_NAME
    #define EEP_I2CBUS_NAME          "i2c1"  /* 连接的I2C总线设备名称 */
    #endif
    
    
    
    static const char * i2c_bus_device_name = "i2c1";
    static const rt_uint8_t eeprom_addr = 0x50; /* 1010A2A1A0 - R/W */
    
    rt_err_t fm24cxx_read(fm24cxx_device_t dev,rt_uint8_t read_addr,rt_uint8_t *read_buff,rt_uint8_t read_len)
    {
    
        rt_err_t result;
        rt_uint8_t read_addr_buffer1[2];
        struct rt_i2c_msg msgs[2];
        read_addr_buffer1[0] = (uint8_t)(read_addr>>8);
        read_addr_buffer1[1] = (uint8_t)read_addr;
    
        result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
        msgs[0].addr = eeprom_addr;
        msgs[0].flags = RT_I2C_WR; /* Write to slave */
        msgs[0].buf = read_addr_buffer1; /* eeprom offset. */
        msgs[0].len = 1;
    
        msgs[1].addr  = eeprom_addr;
        msgs[1].flags = RT_I2C_RD; /* Read from slave */
        msgs[1].buf   = read_buff;
        msgs[1].len   = read_len;
        if( rt_i2c_transfer(dev->i2c, msgs, 2) != 2 )
        {
            LOG_E("re-read EEPROM fail!");
           return RT_ERROR;
        }
        rt_mutex_release(dev->lock);
        return RT_EOK;
    }
    
    rt_err_t fm24cxx_write(fm24cxx_device_t dev,rt_uint8_t write_addr,rt_uint8_t *write_buff,rt_uint8_t write_len)
    {
        rt_err_t result;
        rt_uint8_t write_addr_buffer[2];
        struct rt_i2c_msg msgs[2];
        write_addr_buffer[0] = (uint8_t)(write_addr>>8);
        write_addr_buffer[1] = (uint8_t)write_addr;
        result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
        msgs[0].addr = eeprom_addr;
        msgs[0].flags = RT_I2C_WR; /* Write to slave */
        msgs[0].buf = write_addr_buffer; /* eeprom offset. */
        msgs[0].len = 1;
    
        msgs[1].addr  = eeprom_addr;
        msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START; /* Read from slave */
        msgs[1].buf   = write_buff;
        msgs[1].len   = write_len;
    
        if( rt_i2c_transfer(dev->i2c, msgs, 2) != 2 )
        {
            LOG_E("read EEPROM fail!");
            return RT_ERROR;
        }
        rt_mutex_release(dev->lock);
        return RT_EOK;
    }
    rt_err_t fm24cxx_check(fm24cxx_device_t dev)
    {
        struct rt_i2c_msg msgs[2];
        rt_uint8_t buffer[2];
        buffer[0]= 0x31;
        fm24cxx_write(dev, FM24CXX_MAX_MEM_ADDRESS-1, &buffer[0],1);
        fm24cxx_read(dev, FM24CXX_MAX_MEM_ADDRESS-1, &buffer[1],1);
        if(buffer[0]!=buffer[1])
        {
            rt_kprintf("checke fail
    ");
            return RT_ERROR;
        }
        return RT_EOK;
    }
    
    
    rt_err_t fm24cxx_page_write(fm24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
    {
        rt_err_t result = RT_EOK;
        uint16_t pageWriteSize = FM24CXX_PAGE_BYTE - WriteAddr % FM24CXX_PAGE_BYTE;
    
        RT_ASSERT(dev);
    
        if(WriteAddr + NumToWrite > FM24CXX_MAX_MEM_ADDRESS)
        {
            return RT_ERROR;
        }
    
        result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
        if(result == RT_EOK)
        {
            while (NumToWrite)
            {
                if(NumToWrite > pageWriteSize)
                {
                    if(fm24cxx_write(dev, WriteAddr, pBuffer, pageWriteSize))
                    {
                        result = RT_ERROR;
                    }
                    rt_thread_mdelay(EE_TWR);    // wait 5ms befor next operation
    
                    WriteAddr += pageWriteSize;
                    pBuffer += pageWriteSize;
                    NumToWrite -= pageWriteSize;
                    pageWriteSize = FM24CXX_PAGE_BYTE;
                }
                else
                {
                    if(fm24cxx_write(dev, WriteAddr, pBuffer, NumToWrite))
                    {
                        result = RT_ERROR;
                    }
                    rt_thread_mdelay(EE_TWR);   // wait 5ms befor next operation
    
                    NumToWrite = 0;
                }
            }
        }
        else
        {
            LOG_E("The at24cxx could not respond  at this time. Please try again");
        }
    
        rt_mutex_release(dev->lock);
        return result;
    }
    
    rt_err_t at24cxx_page_read(fm24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
    {
        rt_err_t result = RT_EOK;
        uint16_t pageReadSize = FM24CXX_PAGE_BYTE - ReadAddr % FM24CXX_PAGE_BYTE;
    
        RT_ASSERT(dev);
    
        if(ReadAddr + NumToRead > FM24CXX_MAX_MEM_ADDRESS)
        {
            return RT_ERROR;
        }
    
        result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
        if(result == RT_EOK)
        {
            while (NumToRead)
            {
                if(NumToRead > pageReadSize)
                {
                    if(fm24cxx_read(dev, ReadAddr, pBuffer, pageReadSize))
                    {
                        result = RT_ERROR;
                    }
    
                    ReadAddr += pageReadSize;
                    pBuffer += pageReadSize;
                    NumToRead -= pageReadSize;
                    pageReadSize = FM24CXX_PAGE_BYTE;
                }
                else
                {
                    if(fm24cxx_read(dev, ReadAddr, pBuffer, NumToRead))
                    {
                        result = RT_ERROR;
                    }
                    NumToRead = 0;
                }
            }
        }
        else
        {
            LOG_E("The at24cxx could not respond  at this time. Please try again");
        }
    
        rt_mutex_release(dev->lock);
        return result;
    }
    /**
     * fm24 初始化函数 用于开辟设备对象内存
     * @param i2c_bus_name 总线名
     * @param AddrInput 设备地址
     * @return
     */
    fm24cxx_device_t fm24cxx_init(const char * i2c_bus_name,rt_uint8_t AddrInput)
    {
        fm24cxx_device_t dev;
        RT_ASSERT(i2c_bus_name);
    
        dev = rt_calloc(1, sizeof(struct fm24cxx_device));//动态创建内存
        if (dev == RT_NULL)
        {
          LOG_E("Can't allocate memory for fm24cxx device on '%s' ", i2c_bus_name);
          return RT_NULL;
        }
    
        dev->i2c = rt_i2c_bus_device_find(i2c_bus_name);
        if (dev->i2c == RT_NULL)
        {
           LOG_E("Can't find fm24cxx device on '%s' ", i2c_bus_name);
           rt_free(dev);
           return RT_NULL;
        }
    
        dev->lock = rt_mutex_create("mutex_fm24cxx", RT_IPC_FLAG_FIFO);
        if (dev->lock == RT_NULL)
        {
           LOG_E("Can't create mutex for fm24cxx device on '%s' ", i2c_bus_name);
           rt_free(dev);
           return RT_NULL;
        }
    
        dev->AddrInput = AddrInput;
        return dev;
    }
    /**
     * fm24对象内存释放
     * @param dev fm24对象
     */
    void fm24cxx_deinit(fm24cxx_device_t dev)
    {
      RT_ASSERT(dev);
      rt_mutex_delete(dev->lock);
      rt_free(dev);
    }
    /**
     * fm24 finsh测试函数
     * @param argc 输入参数个数
     * @param argv 输入参数数组
     * @return
     */
    rt_err_t fm24cxx(int argc, char *argv[])
    {
        static fm24cxx_device_t dev= RT_NULL;
        uint8_t TEST_BUFFER[] = "WELCOM TO RTT";
          if (argc > 1)
          {
              if (!strcmp(argv[1], "probe"))
              {
                  if (argc > 2)
                  {
                      /* initialize the sensor when first probe */
                      if (!dev || strcmp(dev->i2c->parent.parent.name, argv[2]))
                      {
                          /* deinit the old device */
                          if (dev)
                          {
                              fm24cxx_deinit(dev);
                          }
                          dev = fm24cxx_init(argv[2], atoi(argv[3]));
                      }
                  }
                  else
                  {
                      rt_kprintf("at24cxx probe <dev_name> <AddrInput> - probe sensor by given name
    ");
                  }
              }
              else if (!strcmp(argv[1], "read"))
              {
                  if (dev)
                  {
                      uint8_t testbuffer[50];
    
                      /* read the eeprom data */
                      at24cxx_page_read(dev, 0, testbuffer, sizeof(TEST_BUFFER));
    
                      rt_kprintf("read at24cxx : %s
    ", testbuffer);
    
                  }
                  else
                  {
                      rt_kprintf("Please using 'at24cxx probe <dev_name>' first
    ");
                  }
              }
              else if (!strcmp(argv[1], "write"))
              {
                  fm24cxx_page_write(dev, 0, TEST_BUFFER, sizeof(TEST_BUFFER));
                  rt_kprintf("write ok
    ");
              }
              else if (!strcmp(argv[1], "check"))
              {
                  if (fm24cxx_check(dev) != RT_EOK)
                  {
                      rt_kprintf("check faild 
    ");
                  }else{
                      rt_kprintf("check ok 
    ");
                  }
              }
              else
              {
                  rt_kprintf("Unknown command. Please enter 'at24cxx0' for help
    ");
              }
          }
          else
          {
              rt_kprintf("Usage:
    ");
              rt_kprintf("fm24cxx probe <dev_name>   - probe eeprom by given name
    ");
              rt_kprintf("fm24cxx check              - check eeprom fm24cxx 
    ");
              rt_kprintf("fm24cxx read               - read eeprom fm24cxx data
    ");
              rt_kprintf("fm24cxx write              - write eeprom fm24cxx data
    ");
    
          }
    }
    
    
    
    #ifdef RT_USING_FINSH
    #include <finsh.h>
    MSH_CMD_EXPORT(fm24cxx, fm24cxx);
    #endif // RT_USING_FINSH

  • 相关阅读:
    领域驱动设计下系统层次结构风格(转载)
    习语
    Dynamic load of a c++ dll in C#?http://www.codecomments.com/archive29020047216328.html
    C#调用DLL文件时参数对应表
    13G编程电子书开始提供BT下载
    如何在C#中加载自己编写的动态链接库(DLL)
    Problem in calling C++ dll from C# Code
    用C++编写的基于双向链表的CPtrArray类
    C++(new and malloc0
    How to create a DLL library in C and then use it with C#
  • 原文地址:https://www.cnblogs.com/wt88/p/14043587.html
Copyright © 2011-2022 走看看