IIC 中断

继续中。。

stm8si2c程序,调试通过 INTERRUPT_HANDLER(I2C_IRQHandler, 19) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ struct SCB_T *system=&system_process; unsigned char i,i2c_sr1,i2c_sr2,i2c_event,i2c__status=0,temp,sr1_analysis_int_resource[8],sr2_analysis_int_resource[8]; char i2c_interrupt_type=0,p;//在一次I2中断中,I2C中断中的中断标志位个数; disableInterrupts();//关总中断 i2c_sr1=I2C->SR1; p=I2C->SR3; i2c_sr2=I2C->SR2; //temp=I2C->SR3; //analysis interrupt resource in i2c->sr1 register sr1_analysis_int_resource[0]=i2c_sr1&I2C_SR1_SB; sr1_analysis_int_resource[1]=i2c_sr1&I2C_SR1_ADDR; sr1_analysis_int_resource[2]=i2c_sr1&I2C_SR1_BTF; sr1_analysis_int_resource[3]=i2c_sr1&I2C_SR1_ADD10; sr1_analysis_int_resource[4]=i2c_sr1&I2C_SR1_STOPF; // sr1_i2c__state[5]=i2c_state&((u8)I2C_SR1_BIT6); sr1_analysis_int_resource[6]=i2c_sr1&I2C_SR1_RXNE; sr1_analysis_int_resource[7]=i2c_sr1&I2C_SR1_TXE; //analysis interrupt resource in i2c->sr2 register sr2_analysis_int_resource[0]=i2c_sr2&I2C_SR2_BERR; sr2_analysis_int_resource[1]=i2c_sr2&I2C_SR2_ARLO; sr2_analysis_int_resource[2]=i2c_sr2&I2C_SR2_AF; sr2_analysis_int_resource[3]=i2c_sr2&I2C_SR2_OVR; sr2_analysis_int_resource[5]=i2c_sr2&I2C_SR2_WUFH; if(sr1_analysis_int_resource[0]==I2C_SR1_SB) {i2c__status=0x01;i2c_interrupt_type++;} if(sr1_analysis_int_resource[1]==I2C_SR1_ADDR) {i2c__status=0x02;i2c_interrupt_type++;} if(sr1_analysis_int_resource[2]==I2C_SR1_BTF) {i2c__status=0x03;i2c_interrupt_type++;} if(sr1_analysis_int_resource[3]==I2C_SR1_ADD10) {i2c__status=0x04;i2c_interrupt_type++;} if(sr1_analysis_int_resource[4]==I2C_SR1_STOPF) {i2c__status=0x05;i2c_interrupt_type++;} if(sr1_analysis_int_resource[6]==I2C_SR1_RXNE) {i2c__status=0x06;i2c_interrupt_type++;} if(sr1_analysis_int_resource[7]==I2C_SR1_TXE) {i2c__status=0x07;i2c_interrupt_type++;} if(sr2_analysis_int_resource[0]==I2C_SR2_BERR) {i2c__status=0x08;i2c_interrupt_type++;} if(sr2_analysis_int_resource[1]==I2C_SR2_ARLO) {i2c__status=0x09;i2c_interrupt_type++;} if(sr2_analysis_int_resource[2]==I2C_SR2_AF) {i2c__status=0x0a;i2c_interrupt_type++;} if(sr2_analysis_int_resource[3]==I2C_SR2_OVR) {i2c__status=0x0b;i2c_interrupt_type++;} if(sr2_analysis_int_resource[5]==I2C_SR2_WUFH) {i2c__status=0x0c;i2c_interrupt_type++;} if(i2c_interrupt_type>=2) /*there are more than one interrupt resource in the time*/ { if(i2c_interrupt_type==2) { if((sr1_analysis_int_resource[1]==I2C_SR1_ADDR)&&(sr1_analysis_int_resource[7]==I2C_SR1_TXE)) { I2C->DR=system->i2c.send_frame.data[system->i2c.send_frame.proc]; system->i2c.send_frame.proc++; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x62; } else if((sr1_analysis_int_resource[7]==I2C_SR1_TXE)&&(sr1_analysis_int_resource[2]==I2C_SR1_BTF)) { system->i2c.send_frame.terminate=0; //set I2C transfer terminate bit; system->i2c.send_frame.mod=0; system->i2c.send_frame.write=0; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x64; } else if((sr1_analysis_int_resource[7]==I2C_SR1_TXE)&&(sr2_analysis_int_resource[2]==I2C_SR2_AF)) { I2C->CR2|=I2C_CR2_STOP; I2C->SR2&=(~I2C_SR2_AF);//clear AF bit; system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x64; } else { system->i2c.error=1; I2C_ITConfig(I2C_IT_EVT, DISABLE); system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x37; } } else { system->i2c.error=1; I2C_ITConfig(I2C_IT_EVT, DISABLE); system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x37; } } else { switch(i2c__status) { case I2C_SR1_SB_proc: //如果是发送模式 if(system->i2c.send_frame.mod==1)//说明本次中断之前是从模式,说明这是在从模式下发的起始位; { //EV5 p=I2C->SR1; I2C->DR=system->i2c.send_frame.add__L; //自动清除I2C_SR1_SB标志 system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x38; } else { if(system->i2c.rev_frame.mod==1) //说明本次中断之间是主模式,这次发的是重复起始位; { //EV6如果是接收模式 p=I2C->SR1; I2C->DR=system->i2c.rev_frame.add__L;//自动清除I2C_SR1_SB标志; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x51; } else { system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x36; } } break; case I2C_SR1_ADDR_proc: p=I2C->SR1; temp=I2C->SR3;//软件读取SR1寄存器后,对SR3寄存器的读操作将清除该位 temp&=(u8)I2C_SR3_TRA; I2C->CR2|=(u8)I2C_CR2_ACK;// 使能应答位 I2C->CR2&=(u8)(~I2C_CR2_POS);//设置接受到当字节应答 //如果是发送模式 if(system->i2c.send_frame.mod==1) { if(temp==(u8)I2C_SR3_TRA) {; } else { system->i2c.error=1; } } else { if(system->i2c.rev_frame.mod==1) { if(temp==0)//machine at a master-receive mod { system->i2c.rev_frame.proc=0; } else { system->i2c.error=1; } } else { system->i2c.error=1; } } system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x52; break; case I2C_SR1_RXNE_proc: if(system->i2c.rev_frame.proci2c.rev_frame.num-3)) { system->i2c.rev_frame.data[system->i2c.rev_frame.proc]=I2C->DR; system->i2c.rev_frame.proc++; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x57; } else if(system->i2c.rev_frame.proc==(u8)(system->i2c.rev_frame.num-2)) { system->i2c.rev_frame.data[system->i2c.rev_frame.proc]=I2C->DR; system->i2c.rev_frame.proc++; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x58; I2C->CR2&=(u8)(~I2C_CR2_ACK);//不返回应答 I2C->CR2|=I2C_CR2_STOP; //发停止位结束这次数据接收; } else if(system->i2c.rev_frame.proc>=(u8)(system->i2c.rev_frame.num-1)) { system->i2c.rev_frame.data[system->i2c.rev_frame.proc]=I2C->DR; system->i2c.rev_frame.proc++; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x59; system->i2c.rev_frame.terminate=0; //set I2C transfer terminate bit; system->i2c.rev_frame.mod=0; system->i2c.rev_frame.read=0; } else { system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0xfb; } break; case I2C_SR1_TXE_proc: if(system->i2c.send_frame.proci2c.send_frame.num-1)) { I2C->DR=system->i2c.send_frame.data[system->i2c.send_frame.proc]; system->i2c.send_frame.proc++; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x61; } else if(system->i2c.send_frame.proc=(u8)(system->i2c.send_frame.num)) { I2C->CR2|=I2C_CR2_STOP; // 发停止位结束 这次数据接收; I2C_ITConfig(I2C_IT_BUF, DISABLE); system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x60; } else { system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0xfc; } break; case I2C_SR2_AF_proc: I2C->CR2|=I2C_CR2_STOP; I2C->SR2&=(~I2C_SR2_AF);//clear AF bit; system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0x63; break; default: system->i2c.error=1; system->i2c.debug.reserve[system->i2c.int_debug_count].type=0xfd; break; } } system->i2c.int_debug_count++; enableInterrupts();//开总中断 }
### 关于IIC中断的使用方法 IIC(Inter-Integrated Circuit)是一种用于短距离通信的串行总线协议。在实际应用中,为了提高系统的实时性和效率,通常会利用中断机制来处理IIC事件。以下是关于IIC中断使用的详细介绍以及示例代码。 #### IIC中断的工作原理 当主机或从机完成特定的操作时(如字节传输完毕、接收到起始信号或停止信号),硬件会产生一个中断请求。通过配置相应的寄存器,可以启用这些中断并编写对应的中断服务程序(ISR)。这样可以在不占用CPU资源的情况下等待数据传输完成[^2]。 #### 配置IIC中断的关键步骤 1. **初始化IIC模块** 设置SCL和SDA引脚的方向,并配置波特率等相关参数。 2. **使能全局中断** 确保微控制器的全局中断被开启,通常是设置`EA=1`(对于51单片机而言)或其他类似的指令。 3. **配置IIC中断源** 启用具体的IIC中断标志位,例如接收/发送完成中断、地址匹配中断等。 4. **编写中断服务程序** 编写针对不同中断类型的响应逻辑,在其中执行必要的操作,比如读取状态寄存器、更新缓冲区指针或者触发下一次传输。 #### 示例代码:基于51单片机的IIC中断实现 下面是一个简单的例子展示如何使用IIC中断进行数据收发: ```c #include <reg52.h> sbit SDA = P3^7; sbit SCL = P3^6; unsigned char rx_data, tx_data = 0xAA; // 定义要发送的数据 bit ack_flag = 0; void IIC_Init() { TMOD |= 0x20; // 初始化定时器模式 TH1 = 0xFD; // 设置波特率为9600bps (假设晶振频率为11.0592MHz) SCON = 0x50; // 工作方式1,允许接收 TI = 1; // 发送标志清零 EA = 1; // 开启全局中断 ES = 1; // 开启串口中断 } // 中断服务函数 void UART_ISR(void) interrupt 4 { if(RI){ // 如果有数据到达 RI = 0; // 清除接收标志 rx_data = SBUF; // 获取接收到的数据 if(rx_data == 'R') { // 假设收到'R'表示启动IIC读操作 IIC_Start(); IIC_SendByte(0xA0); // 设备地址加上写命令 IIC_WaitAck(); // 等待应答 IIC_ReStart(); // 重新开始 IIC_SendByte(0xA1); // 切换到读模式 IIC_WaitAck(); // 等待应答 rx_data = IIC_ReadByte(); // 读取设备返回的一个字节 IIC_NACK(); // 不再需要更多数据 IIC_Stop(); // 结束IIC通讯 } if(tx_data != '\0'){ SBUF = tx_data; // 准备发送下一个字符 TI = 1; // 设置发送标志 } } if(TI){ TI = 0; // 清除发送标志 } } // 主函数 void main(){ IIC_Init(); // 调用初始化函数 while(1){ ; // 循环运行 } } ``` 此段代码展示了基本框架下的UART与IIC结合情况下的中断驱动设计思路[^3]。 #### 注意事项 - 实际开发过程中需查阅具体芯片手册获取精确控制细节。 - 对时间敏感的应用场景可能还需要考虑延时补偿等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值