码迷,mamicode.com
首页 > 其他好文 > 详细

i2c框架

时间:2018-11-27 01:20:27      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:表示   arm   res   ==   产生   lse   sum   while   std   

目录


title: iic框架
tags: ARM
date: 2018-11-05 13:44:58
---

i2c框架

寄存器

技术分享图片

技术分享图片

技术分享图片

/* 配置引脚用于I2C*/
GPECON &= ~((3<<28) | (3<<30));
GPECON |= ((2<<28) | (2<<30));

/* 设置时钟 */
/* [7] : IIC-bus acknowledge enable bit, 1-enable in rx mode
     * [6] : 时钟源, 0: IICCLK = fPCLK /16; 1: IICCLK = fPCLK /512
     * [5] : 1-enable interrupt
     * [4] : 读出为1时表示中断发生了, 写入0来清除并恢复I2C操作
     * [3:0] : Tx clock = IICCLK/(IICCON[3:0]+1).
     * Tx Clock = 100khz = 50Mhz/16/(IICCON[3:0]+1)
     */
IICCON = (1<<7) | (0<<6) | (1<<5) | (30<<0);

中断配置: IIC没有次中断源.直接配置INTMSK即可INTMSK &= ~(1<<27);

主机发送

技术分享图片

int do_master_tx(p_i2c_msg msg)
{
    p_cur_msg = msg;
    
    msg->cnt_transferred = -1;
    msg->err = 0;
    
    /* 设置寄存器启动传输 */
    /* 1. 配置为 master tx mode */
    IICCON |= (1<<7); /* TX mode, 在ACK周期释放SDA */
    IICSTAT = (1<<4);
        
    /* 2. 把从设备地址写入IICDS */
    IICDS = msg->addr<<1;
    
    /* 3. IICSTAT = 0xf0 , 数据即被发送出去, 将导致中断产生 */
    IICSTAT = 0xf0;
    

    /* 后续的传输由中断驱动 */

    /* 循环等待中断处理完毕 */
    while (!msg->err && msg->cnt_transferred != msg->len);

    if (msg->err)
        return -1;
    else
        return 0;
}

主机接收

技术分享图片

int do_master_rx(p_i2c_msg msg)
{
    p_cur_msg = msg;

    msg->cnt_transferred = -1;
    msg->err = 0;
    
    /* 设置寄存器启动传输 */
    /* 1. 配置为 Master Rx mode */
    IICCON |= (1<<7); /* RX mode, 在ACK周期回应ACK */
    IICSTAT = (1<<4);
        
    /* 2. 把从设备地址写入IICDS */
    IICDS = (msg->addr<<1)|(1<<0);
    
    /* 3. IICSTAT = 0xb0 , 从设备地址即被发送出去, 将导致中断产生 */
    IICSTAT = 0xb0;
    

    /* 后续的传输由中断驱动 */

    /* 循环等待中断处理完毕 */
    while (!msg->err && msg->cnt_transferred != msg->len);

    if (msg->err)
        return -1;
    else
        return 0;
}

中断处理

注意

  1. 连续读的最后一个字节不响应ack,以用来终止读.
  2. 在读写第一个字节的时候,判断是否有ack来判断是否设备存在

技术分享图片

if (p_cur_msg->flags == 0)  /* write */
{
    /* 对于第1个中断, 它是发送出设备地址后产生的
         * 需要判断是否有ACK
         * 有ACK : 设备存在
         * 无ACK : 无设备, 出错, 直接结束传输
         */
    if (p_cur_msg->cnt_transferred == 0)  /* 第1次中断 */
    {
        if (iicstat & (1<<0))
        { /* no ack */
            /* 停止传输 */
            IICSTAT = 0xd0;
            IICCON &= ~(1<<4);//挂起标志
            p_cur_msg->err = -1;
            printf("tx err, no ack\n\r");
            delay(1000);
            return;
        }
    }

    if (p_cur_msg->cnt_transferred < p_cur_msg->len)
    {
        /* 对于其他中断, 要继续发送下一个数据
             */
        IICDS = p_cur_msg->buf[p_cur_msg->cnt_transferred];
        IICCON &= ~(1<<4);//挂起标志
    }
    else
    {
        /* 停止传输 */
        IICSTAT = 0xd0;
        IICCON &= ~(1<<4);//挂起标志
        delay(1000);
    }
}

/* 对于第1个中断, 它是发送出设备地址后产生的
 * 需要判断是否有ACK
 * 有ACK : 设备存在, 恢复I2C传输, 这样在下一个中断才可以得到第1个数据
 * 无ACK : 无设备, 出错, 直接结束传输
 */
if (p_cur_msg->cnt_transferred == 0)  /* 第1次中断 */
{
    if (iicstat & (1<<0))
    { /* no ack */
        /* 停止传输 */
        IICSTAT = 0x90;
        IICCON &= ~(1<<4);
        p_cur_msg->err = -1;
        printf("rx err, no ack\n\r");
        delay(1000);
        return;
    }
    else  /* ack */
    {
        /* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
        /* 恢复I2C传输 */
        if (isLastData())
        {
            resume_iic_without_ack();
        }
        else
        {
            resume_iic_with_ack();
        }
        return;
    }
}

/* 非第1个中断, 表示得到了一个新数据
 * 从IICDS读出、保存
 */
if (p_cur_msg->cnt_transferred < p_cur_msg->len)
{
    index = p_cur_msg->cnt_transferred - 1;
    p_cur_msg->buf[index] = IICDS;

    /* 如果是最后一个数据, 启动传输时要设置为不回应ACK */
    /* 恢复I2C传输 */
    if (isLastData())
    {
        resume_iic_without_ack();
    }
    else
    {
        resume_iic_with_ack();
    }
}
else
{
    /* 发出停止信号 */
    IICSTAT = 0x90;
    IICCON &= ~(1<<4);//清标志
    delay(1000);
}

程序框架

技术分享图片

技术分享图片

i2c框架

标签:表示   arm   res   ==   产生   lse   sum   while   std   

原文地址:https://www.cnblogs.com/zongzi10010/p/10023645.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!