完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
各位大佬好, 最近在使用NUC970芯片, 使用官方提供的BSP中I2C代码测试, 功能是完全正常的. 查看数据手册, 发现有支持Software Mode I2C, 所以想尝试下使用这个模式编写I2C功能,但是失败了, 想问下各位大佬是否有成功的可否分享下!
下面有几点疑惑请各位大佬帮忙解答下: 1.在软模式下,操作I2Cn Software Mode Register(I2Cn_SWR)寄存器中的SDW,SCW是否和使用IO口模拟I2C一样, 通过操作这两个位产生START, STOP, READ等指令? 2.在软模式下, I2Cn Control and Status Register(I2Cn_CSR)寄存器中的状态位是否可以正常使用 ? |
|
相关推荐
1个回答
|
|
在使用NUC970的I2C的Software Mode时,需要注意以下几点:
1. 在软模式下,操作I2Cn_SWR寄存器中的SDW,SCW是产生START, STOP, READ等指令的关键。SDW等于0时,表示发出SCL时钟信号并保持高电平,SDW等于1时,表示发出SCL时钟信号并拉低SDA信号。SCW等于0时,表示将SDA信号拉高,SCW等于1时,表示将SDA信号拉低。 2. 在软模式下,I2Cn_CSR寄存器中的状态位需要根据不同的硬件设计进行修改,不能直接按照官方提供的代码进行修改。一般来说,接收状态和发送状态可以正常使用,但是其他状态需要根据实际情况进行设置。 3. 使用I2C的Software Mode时,需要使用CPU的延时功能来控制I2C的时序,因此需要对CPU和外设的时钟进行精确定时,以确保I2C时序的准确性。 4. I2C的Software Mode相比于硬件模式来说,操作复杂度和时间开销都会增加,因此需要根据实际需求来选择合适的模式。 以下示例代码可以作为参考: ``` #define I2C_GPIO_SCL 0 /* GPIO0 */ #define I2C_GPIO_SDA 1 /* GPIO1 */ #define I2C_DELAY() delay_cycles(10) void init_i2c_gpio(void) { /* config i2c gpio */ outpw(REG_SYS_GPD_MFPL,(inpw(REG_SYS_GPD_MFPL)&0x00FFFFFF)|0x33000000); /* config gpio as output, SDA=1, SCL=1 */ gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_OUTPUT | GPIO_CFG_SPEED_DEFAULT | GPIO_CFG_PULL_DISABLE); gpio_configure(I2C_GPIO_SCL, GPIO_CFG_MODE_OUTPUT | GPIO_CFG_SPEED_DEFAULT | GPIO_CFG_PULL_DISABLE); gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); } void i2c_start(void) { gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_LOW); I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_LOW); } void i2c_stop(void) { gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_LOW); I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); I2C_DELAY(); } int i2c_send_byte(unsigned char data) { int i; for (i =0; i < 8; i++) { gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_LOW); I2C_DELAY(); if(data & 0x80) gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); else gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_LOW); I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); data <<=1; } /* receive ack */ gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_INPUT | GPIO_CFG_PULL_DISABLE); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); if (gpio_get_input_value(I2C_GPIO_SDA) == GPIO_PIN_LOW) { /* ack */ gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_OUTPUT | GPIO_CFG_PULL_DISABLE); gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_LOW); } else { /* nack */ gpio_set_output(I2C_GPIO_SDA, GPIO_PIN_HIGH); } I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_LOW); gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_OUTPUT | GPIO_CFG_PULL_DISABLE); return 0; } int i2c_receive_byte(unsigned char *data, int ack) { int i; gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_INPUT | GPIO_CFG_PULL_DISABLE); *data = 0; for (i = 0; i < 8; i++) { gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); *data <<= 1; if (gpio_get_input_value(I2C_GPIO_SDA) == GPIO_PIN_HIGH) *data |= 0x01; gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_LOW); I2C_DELAY(); } gpio_configure(I2C_GPIO_SDA, GPIO_CFG_MODE_OUTPUT | GPIO_CFG_PULL_DISABLE); gpio_set_output(I2C_GPIO_SDA, ack ? GPIO_PIN_LOW : GPIO_PIN_HIGH); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_HIGH); I2C_DELAY(); gpio_set_output(I2C_GPIO_SCL, GPIO_PIN_LOW); return 0; } ``` |
|
|
|
只有小组成员才能发言,加入小组>>
692 浏览 0 评论
1106 浏览 1 评论
2473 浏览 5 评论
2808 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2646 浏览 6 评论
使用eim外接fpga可是端口一点反应都没有有没有大哥指点一下啊
653浏览 9评论
649浏览 7评论
请教大神怎样去解决iMX6Q在linux3.0.35内核上做AP失败的问题呢
781浏览 6评论
628浏览 5评论
668浏览 5评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 06:05 , Processed in 0.954260 second(s), Total 80, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号