我会为每个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;
|