社区
嵌入开发(WinCE)
帖子详情
用ATMEGA8开发GY273的程序,为什么I2C没有应答信号呢?
Lucas499
2019-08-24 07:08:54
如题
测了一下IO口的输出电压略小于3.3V
...全文
249
6
打赏
收藏
用ATMEGA8开发GY273的程序,为什么I2C没有应答信号呢?
如题 测了一下IO口的输出电压略小于3.3V
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
6 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
fly 100%
2019-09-03
打赏
举报
回复
这个没准备好是有啥使能位没开?
Lucas499
2019-08-30
打赏
举报
回复
引用 4 楼 迷雾绿洲 的回复:
先降速 波形图看一下,建立时间保持时间是否足够
现在是这样的 I2C通信正常,能够收到应答信号 但是GY273的数据寄存器不能读取,我结合手册和现象,能判断出是 数据没准备好,就被读取了,直接清零 这个有什么解决办法吗?
fly 100%
2019-08-30
打赏
举报
回复
先降速 波形图看一下,建立时间保持时间是否足够
Lucas499
2019-08-24
打赏
举报
回复
是下面一个程序,第一个贴错了~
Lucas499
2019-08-24
打赏
举报
回复
//ICC-AVR application builder : 2009-3-12 17:05:04 // Target : M8 // Crystal: 8.0000Mhz #include <avr/io.h> #include <avr/interrupt.h> #include <macros.h> #include "usart.h" void port_init(void) { DDRB|=0X04;//B2,LED_DOWN,PIN16 DDRC|=0X02;//C1,LED_LEFT,PIN24 DDRC|=0X08;//C3,LED_RIGHT,PIN26 DDRC|=0X20;//C5,LED_UP,PIN28 DDRB|=0X01;//B0,LED_OK,PIN14 DDRD|=0X40;//D6,TEST,PIN12 DDRC&=~0X01;//C0,KEY_LEFT,PIN23 DDRC&=~0X04;//C2,KEY_RIGHT,PIN25 DDRC&=~0X10;//C4,KEY_UP,PIN27 DDRB&=~0X02;//B1,KEY_DOWN,PIN15 DDRD&=~0X80;//D7,KEY_OK,PIN13 PORTC |= 0xFF; PORTB |= 0xFF; PORTD |= 0xFF; } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up cli(); //disable all interrupts port_init(); MCUCR = 0x00; //MCU Control Register GICR = 0x00; //General Interrupt Control Register TIMSK = 0x00; //timer interrupt sources sei(); //re-enable interrupts //all peripherals are now initialized } /************************************************************************* 用 途:iic发送接收 Taget :mega8 crystal :8M 介 绍:PC4-SDA PC5-SCK/SCL //*********************************************************************** I2C 状态定义 MT 主方式传输 MR 主方式接受 ***************************/ #define START 0x08 #define RE_START 0x10 #define MT_SLA_ACK 0x18 #define MT_SLA_NOACK 0x20 #define MT_DATA_ACK 0x28 #define MT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40 #define MR_SLA_NOACK 0x48 #define MR_DATA_ACK 0x50 #define MR_DATA_NOACK 0x58 #define RD_DEVICE_ADDR 0x3c //前4位器件固定,后三位看连线,最后1位是读写指令位 #define WD_DEVICE_ADDR 0x3d #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生 #define TestAck() (TWSR&0xf8) //观察返回状态 #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答 #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答 #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR /*延时子程序*/ void delay_ms(int time) { int i; for(;time>0;time--) for(i=0;i<1000;i++); } //初始化 void iic_init() { TWBR= 0x20; //设置波特率 TWSR= 0x00; //设置预分频比 TWCR= 0x44; //使能应答,使能TWI DDRC|=(1<<PC4)|(1<<PC5); PORTC|=(1<<PC4)|(1<<PC5); } /********************************************* I2C总线写一个字节 返回0:写成功 返回1:写失败 **********************************************/ unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress) { Start(); //I2C启动 Wait(); if(TestAck()!=START) return 1; //ACK Send_Char(0x11);//测试用 Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式 Wait(); Send_Char(0x22);//测试用 if(TestAck()!=MT_SLA_ACK) return 1; //ACK Send_Char(0x33);//测试用 Write8Bit(RegAddress); //写器件相应寄存器地址 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; //ACK Write8Bit(Wdata); //写数据到器件相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; //ACK Stop(); //I2C停止 delay_ms(100); //延时 return 0; } /********************************************* I2C总线读一个字节 返回非0:读成功 返回0:读失败 **********************************************/ unsigned char iic_read(unsigned RegAddress) { unsigned char temp; Start();//I2C启动 Wait(); if (TestAck()!=START) return 1; //ACK Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式 Wait(); if (TestAck()!=MT_SLA_ACK) return 1; //ACK Write8Bit(RegAddress); //写器件相应寄存器地址 Wait(); if (TestAck()!=MT_DATA_ACK) return 1; Start(); //I2C重新启动 Wait(); if (TestAck()!=RE_START) return 1; Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式 Wait(); if(TestAck()!=MR_SLA_ACK) return 1; //ACK Twi(); //启动主I2C读方式 Wait(); if(TestAck()!=MR_DATA_NOACK) return 1; //ACK temp=TWDR; //读取I2C接收数据 Stop(); //I2C停止 return temp; } //**************************************************************************** void main() { unsigned char i,j; port_init(); init_devices(); usart_Init(); iic_init(); i=iic_write(0xaa,0X10);//在0X10地址写入数据0XAA if (i==1) PORTB=0x1;//若写入失败(i=1),B口0x01;若写入成功,B口输出0X02 else PORTB=0x2; j=iic_read(0X10);//读出0x10地址的数据 if(j==1) PORTD=0xff; //若读出失败(j=1),D口全灭;若读出成功,D口输出0XAA else PORTD=j; while(1) { ; } }
Lucas499
2019-08-24
打赏
举报
回复
附上程序 //ICC-AVR application builder : 2009-3-12 17:05:04 // Target : M8 // Crystal: 8.0000Mhz #include <avr/io.h> #include <avr/interrupt.h> #include <macros.h> #include "usart.h" void port_init(void) { DDRB|=0X04;//B2,LED_DOWN,PIN16 DDRC|=0X02;//C1,LED_LEFT,PIN24 DDRC|=0X08;//C3,LED_RIGHT,PIN26 DDRC|=0X20;//C5,LED_UP,PIN28 DDRB|=0X01;//B0,LED_OK,PIN14 DDRD|=0X40;//D6,TEST,PIN12 DDRC&=~0X01;//C0,KEY_LEFT,PIN23 DDRC&=~0X04;//C2,KEY_RIGHT,PIN25 DDRC&=~0X10;//C4,KEY_UP,PIN27 DDRB&=~0X02;//B1,KEY_DOWN,PIN15 DDRD&=~0X80;//D7,KEY_OK,PIN13 PORTC |= 0xFF; PORTB |= 0xFF; PORTD |= 0xFF; } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up cli(); //disable all interrupts port_init(); MCUCR = 0x00; //MCU Control Register GICR = 0x00; //General Interrupt Control Register TIMSK = 0x00; //timer interrupt sources sei(); //re-enable interrupts //all peripherals are now initialized } /************************************************************************* 用 途:iic发送接收 Taget :mega8 crystal :8M 介 绍:PC4-SDA PC5-SCK/SCL //*********************************************************************** I2C 状态定义 MT 主方式传输 MR 主方式接受 ***************************/ #define START 0x08 #define RE_START 0x10 #define MT_SLA_ACK 0x18 #define MT_SLA_NOACK 0x20 #define MT_DATA_ACK 0x28 #define MT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40 #define MR_SLA_NOACK 0x48 #define MR_DATA_ACK 0x50 #define MR_DATA_NOACK 0x58 #define RD_DEVICE_ADDR 0x3c //前4位器件固定,后三位看连线,最后1位是读写指令位 #define WD_DEVICE_ADDR 0x3d #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生 #define TestAck() (TWSR&0xf8) //观察返回状态 #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答 #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答 #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR /*延时子程序*/ void delay_ms(int time) { int i; for(;time>0;time--) for(i=0;i<1000;i++); } //初始化 void iic_init() { TWBR= 0x20; //设置波特率 TWSR= 0x00; //设置预分频比 TWCR= 0x44; //使能应答,使能TWI DDRC|=(1<<PC4)|(1<<PC5); PORTC|=(1<<PC4)|(1<<PC5); } /********************************************* I2C总线写一个字节 返回0:写成功 返回1:写失败 **********************************************/ unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress) { Start(); //I2C启动 Wait(); if(TestAck()!=START) return 1; //ACK Send_Char(0x11);//测试用 Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式 Wait(); Send_Char(0x22);//测试用 if(TestAck()!=MT_SLA_ACK) return 1; //ACK Send_Char(0x33);//测试用 Write8Bit(RegAddress); //写器件相应寄存器地址 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; //ACK Write8Bit(Wdata); //写数据到器件相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; //ACK Stop(); //I2C停止 delay_ms(100); //延时 return 0; } /********************************************* I2C总线读一个字节 返回非0:读成功 返回0:读失败 **********************************************/ unsigned char iic_read(unsigned RegAddress) { unsigned char temp; Start();//I2C启动 Wait(); if (TestAck()!=START) return 1; //ACK Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式 Wait(); if (TestAck()!=MT_SLA_ACK) return 1; //ACK Write8Bit(RegAddress); //写器件相应寄存器地址 Wait(); if (TestAck()!=MT_DATA_ACK) return 1; Start(); //I2C重新启动 Wait(); if (TestAck()!=RE_START) return 1; Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式 Wait(); if(TestAck()!=MR_SLA_ACK) return 1; //ACK Twi(); //启动主I2C读方式 Wait(); if(TestAck()!=MR_DATA_NOACK) return 1; //ACK temp=TWDR; //读取I2C接收数据 Stop(); //I2C停止 return temp; } //**************************************************************************** void main() { unsigned char i,j; port_init(); init_devices(); usart_Init(); iic_init(); while(1) { ; } }
Arduino 系列:Arduino Uno 系列 (基于
ATmega
328P)_(10).
I2C
通信
I2C
通信
I2C
(Inter-Integrated Circuit)是一种用于短距离通信的串行总线协议,由Philips(现为NXP)公司在1980年代初
开发
。
I2C
总线允许多个设备通过两根线(SCL和SDA)实现互连,其中SCL(Serial Clock Line)为时钟线,SDA(Serial Data Line)为数据线。
I2C
总线的主要特点是支持多主多从设备、简单的硬件连接以及较慢的传输速率(标准模式100 kbps,快速模式400 kbps,高速模式3.4 Mbps)。
I2C
总线的基本概念
GY-30光强度模块:精确测量与智能应用
开发
指南
GY-30光强度模块,也常被称为光敏传感器模块,主要由BH1750FVI数字光强度传感器构成。这种模块能够进行高精度的环境光强度测量,并通过
I2C
通信协议进行数据的传递,广泛应用于各种光强度监测的场合。
STM32 MPU6050 六轴陀螺仪教程(HAL 库零基础入门)
MPU6050 通过总线与 STM32 通信。
I2C
是由 Philips 公司
开发
的一种简易的双线串行通信协议,旨在减少芯片间连接线,简化硬件设计 (Arduino 通过
I2C
驱动 LCD1602 液晶屏 – Arduino 实验室SDA(数据线):双向串行数据线,负责在主设备和从设备之间传输数据。SCL(时钟线):由主设备产生的时钟
信号
线,用于同步数据传输。在
I2C
总线中,每个从设备都有唯一的7位地址用于识别,主设备通过地址来选择与哪一个从设备通信 (
基于Arduino的MLX90614红外温度传感器项目实战
I2C
总线由两条
信号
线组成::用于传输数据。:由主设备控制,用于同步数据传输。这两条线均为双向开漏输出,因此在使用时必须外接上拉电阻(通常为4.7kΩ),以确保
信号
的稳定性和完整性。MLX90614是一种非接触式的红外温度传感器,能够通过检测物体发射的红外辐射来测量其表面温度。其核心原理基于斯特藩-玻尔兹曼定律(Stefan-Boltzmann Law),该定律指出:一个理想黑体在热平衡状态下,其单位面积上辐射的总能量与其绝对温度的四次方成正比。
基于RDA5807M与Arduino Nano的触摸控制FM收音机
开发
实战
Arduino Nano提供两个固定的I²C引脚:A4 → SDA(数据线)A5 → SCL(时钟线)这些引脚连接到
ATmega
328P的内部TWI模块,支持开漏输出模式,符合I²C电气规范。RDA5807M模块通常提供以下关键引脚:VCC:2.7–3.6V电源输入(多数模块内置LDO,可接5V)GND:接地SDA:I²C数据线SCL:I²C时钟线ADDR:地址选择引脚(决定I²C地址)RESET:复位输入(低电平有效)
嵌入开发(WinCE)
19,524
社区成员
41,569
社区内容
发帖
与我相关
我的任务
嵌入开发(WinCE)
硬件/嵌入开发 嵌入开发(WinCE)
复制链接
扫一扫
分享
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章