完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
这两天弄得有点艰辛呐~因为我是才接触AMR的,导师要求是能看懂程序,可以进行注释。今天弄的是I2C,接触到中断我就有点混乱了==认真学习一天后还是很有收获的。 对I2C的操作其实也是几个寄存器的功能操作。初始化首先是I/O口的功能选择为I2C,即PINSEL0=0X00000050;然后是总线速率的设定,根据计算公式:总线速率=FPCLK/(I2CSCLH+I2CSCLL),计算出I2CSCLH和I2CSCLL的值;接着是I2C的中断允许,代码如下:
/* 设置I2C中断允许 */ VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断 VICVectCntl0 = 0x29; // I2C通道分配到IRQ slot 0,即优先级最高 VICVectAddr0 = (int)IRQ_I2C; // 设置I2C中断向量地址 VICIntEnable = 0x0200; // 使能I2C中断 其中I2C中断向量地址代码如下: void __irq IRQ_I2C(void) { uint8 sta; sta = I2C0STAT; // 读出I2C状态字 switch(I2C0STAT) { case 0x08: // 己发送起始条件 if(1==I2C_suba_en) I2C0DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址 else I2C0DAT = I2C_sla; // 否则直接发送从机地址 和写位(0写) I2C0CONCLR = 0x28; // SI=0 break; case 0x10: I2C0DAT = I2C_sla; // 重启动总线后,发送从地址 I2C0CONCLR = 0x28; // SI=0 break; case 0x18: // 已发送SLA+W,并已接收应答 if(0==I2C_suba_en) // 无子地址,则直接发送数据 { if(I2C_num>0) { I2C0DAT = *I2C_buf++; I2C0CONCLR = 0x28; I2C_num--; } else { I2C0CONSET = 0x10; // 无数据发送,结束总线 I2C0CONCLR = 0x28; I2C_end = 1; // 设置总线操作结束标志 } break; } if(1==I2C_suba_en) // 发送子地址 { I2C0DAT = I2C_suba; I2C0CONCLR = 0x28; } if(2==I2C_suba_en) { I2C0DAT = I2C_suba; I2C0CONCLR = 0x28; I2C_suba_en = 0; // 子地址己处理 } break; case 0x28: // 已发送I2C数据,并接收到应答 if(0==I2C_suba_en) // 无子地址,则直接发送数据 { if(I2C_num>0) { I2C0DAT = *I2C_buf++; I2C0CONCLR = 0x28; I2C_num--; } else { I2C0CONSET = 0x10; // 无数据发送,结束总线 I2C0CONCLR = 0x28; I2C_end = 1; } break; } if(1==I2C_suba_en) // 若是指定地址读,则重新启动总线 { I2C0CONSET = 0x20; I2C0CONCLR = 0x08; I2C_suba_en = 0; // 子地址己处理 } break; case 0x20: case 0x30: case 0x38: I2C0CONCLR = 0x28; // 总线进入不可寻址从模式 I2C_end = 0xFF; // 总线出错,设置标志 break; case 0x40: // 己发送SLA+R,并已接收到应答 if(1==I2C_num) // 最后一字节,接收数据后发送非应答信号 { I2C0CONCLR = 0x2C; // AA=0,接收到数据后产生非应答 } else // 接收数据并发送应答信号 { I2C0CONSET = 0x04; // AA=1,接收到数据后产生应答 I2C0CONCLR = 0x28; } break; case 0x50: *I2C_buf++ = I2C0DAT; // 读取数据 I2C_num--; if(1==I2C_num) { I2C0CONCLR = 0x2C; // AA=0,接收到数据后产生非应答 } else { I2C0CONSET = 0x04; // AA=1,接收到数据后产生应答 I2C0CONCLR = 0x28; } break; case 0x58: *I2C_buf++ = I2C0DAT; // 读取最后一字节数据 I2C0CONSET = 0x10; // 结束总线 I2C0CONCLR = 0x28; I2C_end = 1; break; case 0x48: I2C0CONCLR = 0x28; // 总线进入不可寻址从模式 I2C_end = 0xFF; break; default: break; } VICVectAddr = 0x00; // 中断处理结束 } 即根据状态寄存器I2CSTAT中的不同的值进行不同的中断操作。这样之后便可以进行数据的发送和接收了。 发送数据时,令I2C0CONSET = 0x60,即STA=1,即可进入I2C主发送模式,立即发送一个起始条件,SI也跟着置1,此时状态代码就为08H,进入相应的中断处理程序,将从地址和写位装入I2CDAT中,然后SI=0,然后就发送从地址和写位,收到应答后SI再次置1,然后又进入不同的中断程序,。。。一直进行下去,知道数据发送完成,退出中断。主接收过程也差不多。 |
|
相关推荐
|
|
回帖后跳转到最后一页
|
|
|
|
|
|
好想玩玩stm32,可是没钱买开发版!等寒假工过后再买来玩
|
|
|
|
|
|
7120 浏览 3 评论
8382 浏览 1 评论
8612 浏览 0 评论
Protues中自己封装的芯片元件无Program File、Clock Frequency选项怎么解决,求求大神了!
10453 浏览 1 评论
基于51单片机的车辆倒车雷达报警系统,HC-SR04超声波测距,全套资料
1317 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-12 10:12 , Processed in 0.406857 second(s), Total 40, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号