我会为每个IIC总线,定义下面三个函数:
我的评价是,虽然效率不高,但结构化不错,应用方便。可以有多个IIC。
对于大多数应用,单片机时间是够用的,所以不一定要处处关心执行效率。
void iic1_scl(miic_lin_t state)
{
if (state == LIN_STA_LO) {
BC(PORTD, 0);
}
else {
BS(PORTD, 0);
}
}
unsigned char iic1_sda(miic_lin_t state)
{
switch (state) {
case LIN_STA_LO:
BC(PORTD, 1);
break;
case LIN_STA_HI:
BS(PORTD, 1);
break;
case SDA_STA_DOUT:
BS(DDRD, 1);
break;
case SDA_STA_DIN:
BC(DDRD, 1);
break;
case SDA_STA_IN:
return BCK(PIND, 1);
break;
}
return 0;
}
void iic1_delay()
{
volatile unsigned char i;
for (i = 1; i < 5; i++);
}
IIC结构如下:
/** \brief IIC总线控制结构 */
typedef struct {
/** \brief SCL线控制
* \param state SCL线状态
* \warning 本模块不会配置SCL线的输出方向,因此必须事先配置SCL方向为输出
* \arg LIN_STA_LO SCL线输出低电平
* \arg LIN_STA_HI SCL线输出高电平
*/
void (*scl)(miic_lin_t state);
/** \brief SDA线控制
* \param state SDA线状态
* \arg LIN_STA_LO SDA线输出低电平
* \arg LIN_STA_HI SDA线输出高电平
* \arg SDA_STA_DOUT 设置SDA方向为输出
* \arg SDA_STA_DIN 设置SDA方向为输入
* \arg SDA_STA_IN 读取SDA状态
* \return SDA线状态,只有参数state为SDA_STA_IN时才有意义
* \retval 0 SDA线为低电平
* \retval 其它 SDA线为高电平
*/
unsigned char (*sda)(miic_lin_t state);
/** \brief SCL延时
*
* 降低总线时钟频率,一定要保证总线时钟适应设备的总线频率,一般设备为100K或400K
*/
void (*delay)(void);
} miic;
|