大数跨境

C语言封装技术

C语言封装技术 芯片之家
2016-12-27
0
导读:最近在研究RT_Thread的源码,发现i2c驱动里有个地方使用的封装的技术,很少见,又感觉很是精妙。

最近在研究RT_Thread的源码,发现i2c驱动里有个地方使用的封装的技术,很少见,又感觉很是精妙。所以特意写个测试模拟程序,并贴上来和大家分享。
个人觉得它非常经典。它使用的模拟的i2c。代码如下:
#include "stdafx.h"

typedef signed int rt_int32_t;
typedef unsigned int rt_uint32_t;

struct rt_i2c_bit_ops
{
    void *data;            /* private data for lowlevel routines */
    void (*set_sda)(void *data, rt_int32_t state);
    void (*set_scl)(void *data, rt_int32_t state);
    rt_int32_t (*get_sda)(void *data);
    rt_int32_t (*get_scl)(void *data);

    void (*udelay)(rt_uint32_t us);

    rt_uint32_t delay_us;  /* scl and sda line delay */
    rt_uint32_t timeout;   /* in tick */
};

//结构体功能函数的使用 它的精妙之处在这里,用宏把结构体函数使用起来
#define SET_SDA(ops, val)   ops->set_sda(ops->data, val)
#define SET_SCL(ops, val)   ops->set_scl(ops->data, val)
#define GET_SDA(ops)        ops->get_sda(ops->data)
#define GET_SCL(ops)        ops->get_scl(ops->data)
//结构体功能函数的使用
#define SDA_L(ops)          SET_SDA(ops, 0)
#define SDA_H(ops)          SET_SDA(ops, 1)
#define SCL_L(ops)          SET_SCL(ops, 0)

//提供对外使用
inline void i2c_delay(struct rt_i2c_bit_ops *ops)
{
    ops->udelay((ops->delay_us + 1) >> 1);
}

inline void i2c_delay2(struct rt_i2c_bit_ops *ops)
{
    ops->udelay(ops->delay_us);
}
//以下为rt_i2c_bit_ops指针函数
void i2c_set_sda(void *data, rt_int32_t state)
{
        if(state)
        {
                printf("sda->H\r\n");
        }else
        {
                printf("sda->L\r\n");
        }
}
void i2c_set_scl(void *data, rt_int32_t state)
{
        if(state)
        {
                printf("scl->H\r\n");
        }else
        {
                printf("scl->L\r\n");
        }
}

rt_int32_t i2c_get_sda(void *data)
{
        printf("sda return 1\r\n");
        return 1;
}
rt_int32_t i2c_get_scl(void *data)
{
        printf("scl return 1\r\n");
        return 1;
}
void udelay(rt_uint32_t us)
{
        printf("udelay %d us\r\n",us);
}
//以上为rt_i2c_bit_ops指针函数


//模拟i2c的其他信号可以类似i2c_restart一样调用
static void i2c_restart(struct rt_i2c_bit_ops *ops)
{
    SDA_H(ops);
    i2c_delay(ops);
    SDA_L(ops);
    i2c_delay(ops);
    SCL_L(ops);
}

int main(int argc, char* argv[])
{
        rt_i2c_bit_ops i2c_ops;
        i2c_ops.data = (void *)0x88;
        i2c_ops.delay_us = 5;
        i2c_ops.udelay = udelay;
        i2c_ops.get_scl = i2c_get_scl;
        i2c_ops.get_sda = i2c_get_sda;
        i2c_ops.set_scl = i2c_set_scl;
         i2c_ops.set_sda = i2c_set_sda;


        printf("==========TEST===========!\n");

        以上设置完专门的i2c接口后,类似与i2c_restart这样的i2c发送和接收的业务逻辑函数基本上不用修改了,直接按不同的i2c接口传参即可完成i2c的功能。
        i2c_restart(&i2c_ops);
        return 0;
}


芯片之家

长按左侧二维码,识别关注




【声明】内容源于网络
0
0
芯片之家
1234
内容 1436
粉丝 0
芯片之家 1234
总阅读252
粉丝0
内容1.4k