完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一、 简介
1、关于中断 能触发的中断事件只有两个:
传输模式也是有两种:
主要由10个部分组成:
非FIFO模式下 CPU将用于传输的数据写入I2CDXR,并从I2CDRR读取接收到的数据。 将I2C模块配置为发送器时,写入I2CDXR的数据将复制到I2CXSR,并在SDA引脚上一次移出一位。 I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//配置为发送模式 当I2C模块被配置为接收器时,接收到的数据被转移到I2CRSR,然后复制到I2CDRR I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);//配置为接收模式 时钟生成: 为了满足所有的12C协议定时规格,12C模块的时钟必须在7- 12mhz之间。 只有当I2C模块处于复位状态(I2CMDR中的IRS=0)时,才能初始化预分频器。 只有当IRS更改为1时,预定频率才生效。 •I2CCLKL中的ICCL。对于每个主时钟周期,ICCL确定信号低的时间量。 •I2CCKLH中的ICCH。对于每个主时钟周期,ICCH确定信号高电平的时间量。 //对应代码最后一部分I2C_DUTYCYCLE_50可以使SCL的占空比为50%或者33% I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 10000, I2C_DUTYCYCLE_50); 引脚配置: 先配置GPyGMUX,配置GPxQSELn为异步模式,配置GPyPUD为内部上拉模式 GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAA, GPIO_DIR_MODE_OUT);//GPIO_DIR_MODE_IN GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_STD);//GPIO_PIN_TYPE_PULLUP GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC);//异步 GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLA, GPIO_DIR_MODE_OUT);//GPIO_DIR_MODE_IN GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_STD);//GPIO_PIN_TYPE_PULLUP GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC);//异步 GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA); GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA); 三、I2C模块操作详情 I2C模块有四种基本工作模式: [tr]工作模式描述[/tr]
起始信号和结束信号 //刚刚配置的信息特指以下两个函数: I2C_setDataCount(I2CA_BASE,2); I2C_putData(I2CA_BASE, ADDR);//发送设备地址 I2C_sendStartCondition(I2CA_BASE);//发送起始信号,并将刚刚配置的信息发送出 I2C_sendStopCondition(I2CA_BASE);//发送终止信号 设置数据长度 I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);//配置数据长度为8位 7位地址模式 I2C_setAddressMode(I2CA_BASE,I2C_ADDR_MODE_7BITS);//设置为7位地址位寻址模式 在该模式下以CAT24C02为例 当A2 = A1 = A0 = 0时,写模式为0xA0,读模式为0xA1,但在TMS320F280049C的I2C模块不需要考虑R/W位只考虑前7位,即输入0x50即可。 I2C_setSlaveAddress(I2CA_BASE, 0x50); 1 主机发送一个字节数据后自动会在数据后检测ACK信号 我看了很久官方的中断程序和中断相关的介绍= =。由于我太菜,看了个寂寞,复刻不出,网上除了官方基本没有例程(反正我没找到例程),因此我自己写了一个利用TMS320F280049C的硬件I2C读写ATC24C02的的程序(非中断)程序运行效率不高,但是吧,能用就行= =。 #define Delay_MinTime 1*1000 // I2C PIN #define DEVICE_GPIO_PIN_SDAA 32U // GPIO number for I2C SDAA #define DEVICE_GPIO_PIN_SCLA 33U // GPIO number for I2C SCLA #define DEVICE_GPIO_CFG_SDAA GPIO_32_I2CA_SDA // "pinConfig" for I2C SDAA #define DEVICE_GPIO_CFG_SCLA GPIO_33_I2CA_SCL // "pinConfig" for I2C SCLA #define SLAVE_ADDRESS 0x50 //初始化 void HAL_setupI2CA(void) { //IO初始化 GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAA, GPIO_DIR_MODE_OUT);//GPIO_DIR_MODE_IN GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_STD);//GPIO_PIN_TYPE_PULLUP GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC); GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLA, GPIO_DIR_MODE_OUT);//GPIO_DIR_MODE_IN GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_STD);//GPIO_PIN_TYPE_PULLUP GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC); GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA); GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA); //I2C模块初始化 I2C_disableModule(I2CA_BASE); I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50); I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8); I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS); I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE); I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN); //中断源为:检测到停止位,寄存器访问准备就绪 I2C_enableInterrupt(I2CA_BASE, I2C_INT_STOP_CONDITION | I2C_INT_REG_ACCESS_RDY); I2C_enableFIFO(I2CA_BASE); I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF); I2C_enableModule(I2CA_BASE); } //写一个字节数据到24C02 int16_t EE24CX_Write_Byte(uint16_t ADDR,uint16_t Data) { I2C_setDataCount(I2CA_BASE,2); I2C_putData(I2CA_BASE, ADDR);//发送需要写入的地址 I2C_putData(I2CA_BASE, Data);//发送需要写入的数据 I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//设置为发送模式 I2C_sendStartCondition(I2CA_BASE);//发送起始信号,并将刚刚配置的信息发送出 I2C_sendStopCondition(I2CA_BASE);//发送终止信号 DEVICE_DELAY_US(Delay_MinTime); return 1; } //读24C02指定地址的一个字节 uint16_t EE24CX_Read_Byte(unsigned char ADDR) { uint16_t Data; I2C_setDataCount(I2CA_BASE,1); I2C_putData(I2CA_BASE, ADDR);//发送地址信息 I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//配置为发送模式 I2C_sendStartCondition(I2CA_BASE);//发送起始信号 DEVICE_DELAY_US(Delay_MinTime); I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);//配置为接收模式 I2C_sendStartCondition(I2CA_BASE);//发送起始信号 DEVICE_DELAY_US(Delay_MinTime); Data = I2C_getData(I2CA_BASE);//读取数据 I2C_sendNACK(I2CA_BASE);//发送NACK I2C_sendStopCondition(I2CA_BASE);//发送停止信号 DEVICE_DELAY_US(Delay_MinTime); return Data; } //写多个字节到24C02(这里没有按照按页写的时序) //参数ADDR为读取的起始地址,*Data是发送缓存区,Number是发送的字节数 uint16_t IIC_Write_NByte(uint16_t ADDR,uint16_t *Data,uint16_t Number) { uint16_t i = 0; for(i = 0;i < Number;i++) { EE24CX_Write_Byte(ADDR+i,(*Data)); Data++; } return 1; } //从24C02读取多个字节(这个是按照规格书的多字节读取时序写的) //参数ADDR为读取的起始地址,*Data是接收缓存区,Number是读取的字节数 uint16_t IIC_Read_NByte(uint16_t ADDR,uint16_t * Data,int16_t Number) { uint16_t i = 0; uint16_t i_16 = 0; I2C_setDataCount(I2CA_BASE,1); I2C_putData(I2CA_BASE, ADDR);//发送地址信息 I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);//配置为发送模式 I2C_sendStartCondition(I2CA_BASE);//发送起始信号 DEVICE_DELAY_US(Delay_MinTime);//该延时必须有否则无法读取I2C数据 I2C_setDataCount(I2CA_BASE,Number);//设置需要接收的数据量 I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);//配置为接收模式 I2C_sendStartCondition(I2CA_BASE);//发送起始信号 DEVICE_DELAY_US(Delay_MinTime);//该延时必须有否则不能正确读取的I2C数据 while(i < Number) { i_16 = (i+1) % 16; i++; *Data = I2C_getData(I2CA_BASE);//读取数据 Data++; if(i != 0 && i_16 == 0) DEVICE_DELAY_US(Delay_MinTime);//这个延时必须有,如果没有在读取的数据量超过16字节时读取时序会出错 } if(i == Number) { I2C_sendStopCondition(I2CA_BASE);//发送停止信号 } DEVICE_DELAY_US(Delay_MinTime); return 1; } 如果有幸想通了怎么用中断,再研究分享吧,现在水平不够,就这样吧 |
|
|
|
只有小组成员才能发言,加入小组>>
3269 浏览 9 评论
2947 浏览 16 评论
3446 浏览 1 评论
8967 浏览 16 评论
4041 浏览 18 评论
1084浏览 3评论
562浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
556浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2294浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1850浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-13 13:26 , Processed in 0.916575 second(s), Total 50, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号