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次中断 */

                {

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

相关文章

    。 芯片的选择。通常用于发数据的时候选择哪个芯片接收。例如一根SPI总线可以挂载多个设备,DDR总线上也会挂载多颗DDR内存芯片,此时就需要CS来控......
    的数据手册才知。 CS:Chip Select,片选。 芯片的选择。通常用于发数据的时候选择哪个芯片接收。例如一根SPI总线可以挂载多个设备,DDR总线上也会挂载多......
    记录就能获得其地址。 串口模式很占用串口资源,我并没有使用该模式进行开发,仅仅使用了官方的上位机进行测试,鉴定模组的好坏。 确认模组没问题,选用IIC接口进行开发,这样一条总线可以挂载多个模块,只需要总线......
    上的每个设备都具有不同的识别地址 (5)每次数据传输都是由主机发起,且时钟总是由主机提供 2. I2C 硬件框图 (1)I2C 支持带仲裁功能的多设备通信,在一条总线上可以挂载多I2C 外设 (2)I2C 两条总线......
    I2C驱动详解(2024-07-17)
    线连接ARM9 I2C控制器,通过控制来控制I2C设备的识别设备地址、读、写操作;如图所示 从中所知:I2C线上可以挂载很多个I2C设备;挂载简单,只需要一根数据线和一根时钟线就可以挂载上去,通过......
    不懂CAN协议?如何避免总线仲裁失败?;总线是可以挂载多个控制单元,每个单元均可以发送和接收数据,为了避免发生冲突,协议规定只有等信道空闲时刻优先级高的单元才能占有总线并发送数据,那么......
    不懂CAN协议?如何避免总线仲裁失败?;CAN总线是可以挂载多个控制单元,每个单元均可以发送和接收数据,为了避免发生冲突,协议规定只有等信道空闲时刻优先级高的单元才能占有总线并发送数据,那么CAN......
    上。 3.2 I2C程序设计 该系统设计采用的TEA5767 和AT24C02 都为I2C 接口的芯片,I2C 总线可以实现多主双向同步数据传送,也就是说在一个主机IIC 总线下可以挂多个IIC......
    上各串联有一个“2.2千欧”的电阻。 1.2.3 通讯节点 从 CAN 通讯网络图可了解到,CAN 总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于 CAN 通讯......
    单元都可以进行CRC8 和CRC16校验。CRC校验功能将在STM32与MMC/SD卡进行SPI通信的时候发挥显著作用。 2. .两线串行总线接口(I2C) 在STM32中,除了......

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

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

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

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

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

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

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