s3c2440裸机-I2c编程-3.i2c中断服务程序

发布时间:2023-07-21  

Start信号之后,发出设备地址,在第9个时钟就会产生一个中断,我们根据i2c的流程图来编写中断程序。


每传输完一个数据将产生一个中断,I2C操作的主体在中断服务程序,它可以分为两部分:写操作,读操作。


完整code如下:


static p_i2c_msg p_cur_msg;

 

int isLastData(void)

{

        if (p_cur_msg->cnt_transferred == p_cur_msg->len - 1)

                return 1;  /* 正要开始传输最后一个数据 */

        else 

                return 0;

}

 

void resume_iic_with_ack(void)

{

        unsigned int iiccon = IICCON;

        iiccon |= (1<<7); /* 回应ACK */

        iiccon &= ~(1<<4); /* 恢复IIC操作 */

        IICCON =  iiccon;

}

 

void resume_iic_without_ack(void)

{

        unsigned int iiccon = IICCON;

        iiccon &= ~((1<<7) | (1<<4)); /* 不回应ACK, 恢复IIC操作 */

        IICCON =  iiccon;

}

 

void i2c_interrupt_func(int irq)

{

        int index;

        unsigned int iicstat = IICSTAT;

        unsigned int iiccon;

 

        //printf("i2c_interrupt_func! flags = %dnr", p_cur_msg->flags);

 

        p_cur_msg->cnt_transferred++;

        

        /* 每传输完一个数据将产生一个中断 */

 

        /* 对于每次传输, 第1个中断是"已经发出了设备地址" */

 

        if (p_cur_msg->flags == 0)        /* write */

        {

                /* 对于第1个中断, 它是发送出设备地址后产生的

                 * 需要判断是否有ACK

                 * 有ACK : 设备存在

                 * 无ACK : 无设备, 出错, 直接结束传输

                 */

                if (p_cur_msg->cnt_transferred == 0)  /* 第1次中断 */

                {

                        if (iicstat & (1<<0)) /*iicstat [0] == 1表示no ack*/

                        { /* no ack */

                                /* 停止传输 */

                                IICSTAT = 0xd0;

                                IICCON &= ~(1<<4); //clear pending bit

                                p_cur_msg->err = -1;

                                printf("tx err, no acknr");

                                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);//clear pending bit

        }

        else

        {

                /* 停止传输 */

                IICSTAT = 0xd0;

                IICCON &= ~(1<<4);

                delay(1000);

        }

        }

        else /* read */

        {

                /* 对于第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); //clear pending bit

                                p_cur_msg->err = -1;

                                printf("rx err, no acknr");

                                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);

        }

}


写操作:


        if (p_cur_msg->flags == 0)        /* write */

        {

                /* 对于第1个中断, 它是发送出设备地址后产生的

                 * 需要判断是否有ACK

                 * 有ACK : 设备存在

                 * 无ACK : 无设备, 出错, 直接结束传输

                 */

                if (p_cur_msg->cnt_transferred == 0)  /* 第1次中断 */

                {

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>