问题:我正尝试使用MPLAB X IDE在ATtiny402微控制器中嵌入C代码,以便根据I2C协议执行EEPROM读写操作。但是,我在实现过程中遇到了一些问题,希望您能提供帮助。
上下文:我使用MPLAB X IDE版本6.0.5,并使用C语言对ATtiny402微控制器进行编程。我专门处理I2C协议上的EEPROM读写操作。
我尝试过的:我曾尝试使用Attiny402微控制器、MPLAB X IDE和Proteus软件对24c32存储器芯片执行简单的单字节读写操作。虽然写操作产生了I2C调试器中所见的准确输出,但读操作并未提供令人满意的结果。我之前已问过三次此问题,希望您能提供解决方案。谢谢您的帮助。
#include <xc.h>
#include <util/delay.h>
#define SDA_PIN 1
#define SCL_PIN 2
void i2c_addr_write(uint16_t);
void i2c_data_write(uint8_t);
int main(void)
{
main_init() ;
while(1)
{
main_loop();
}
return 0;
}
void main_init(void)
{
PORTA.DIRSET = (1 << SDA_PIN) | (1 << SCL_PIN);
PORTA.PIN1CTRL &= ~PORT_PULLUPEN_bm;
PORTA.PIN2CTRL &= ~PORT_PULLUPEN_bm;
i2c_start();
i2c_stop();
i2c_start();
i2c_data_write(0x00A0);
i2c_addr_write(0x0001);
i2c_data_write('C');
i2c_stop();
_delay_ms(1000);
i2c_start();
i2c_data_write(0x00A0);
i2c_addr_write(0x0001);
i2c_start();
i2c_data_write(0x00A1); // send read command
uint8_t data = i2c_data_read(); // read data
data = data;
}
void main_loop(void)
{
}
void i2c_start(void)
{
PORTA_OUT |= (1 << PIN1);
_delay_us(4);
PORTA_OUT |= (1 << PIN2);
_delay_us(4);
PORTA_OUT &= ~(1 << PIN1);
_delay_us(4);
PORTA_OUT &= ~(1 << PIN2) ;;
}
void i2c_stop(void)
{
PORTA_OUT &= ~(1 << PIN2) ;
_delay_us(4);
PORTA_OUT &= ~(1 << PIN1);
_delay_us(4);
PORTA_OUT |= (1 << PIN2);
_delay_us(4);
PORTA_OUT |= (1 << PIN1);
_delay_us(4);
}
void i2c_addr_write(uint16_t addr)
{
i2c_data_write((uint8_t)(addr >> 8));
i2c_data_write((uint8_t)(addr & 0xFF));
}
void i2c_data_write(uint8_t data)
{
for(uint8_t i=0;i<8;i++)
{
if(data & 0x80)
{
PORTA_OUT |= (1 << PIN1);
}
else PORTA_OUT &= ~(1 << PIN1);
_delay_us(2);
PORTA_OUT |= (1 << PIN2);
_delay_us(2);
PORTA_OUT &= ~(1 << PIN2) ;;
data =data << 1;
}
PORTA_OUT |= (1 << PIN2) ;
_delay_us(4); PORTA_DIRCLR =(1 << PIN1);
while(PORTA_IN & (1 << PIN1));
PORTA_DIRSET = (1 << PIN1);
_delay_us(4);PORTA_OUT &= ~(1 << PIN2);
}
uint8_t i2c_data_read(void)
{
uint8_t data = 0;
PORTA_DIR &= ~(1 << PIN1);
for (uint8_t i = 0; i < 8; i++) // read 8 bits
{
PORTA_OUT |= (1 << PIN2);
_delay_us(8);
data <<= 1;
if (PORTA_IN & (1 << PIN1))
{
data |= 0x01;
}
else data |= 0x00;
PORTA_OUT &= ~(1 << PIN2) ;
}
// Send ACK bit to EEPROM
PORTA_DIR |= (1 << PIN1);
PORTA_OUT &= ~(1 << PIN1);
_delay_us(2);
PORTA_OUT |= (1 << PIN2);
_delay_us(2);
PORTA_OUT &= ~(1 << PIN2) ;
PORTA_OUT |= (1 << PIN1);
_delay_us(2);
// Send STOP bit to complete the read operation
i2c_stop();
return data;
}
问题:
对于使用MPLAB X IDE的ATtiny402中I2C协议的EEPROM读写操作,此代码是否正确?如果不正确,我应该对代码进行哪些更改以确保其正常工作?使用MPLAB X IDE在ATtiny402中对I2C协议执行EEPROM读写操作时,我应该遵循哪些具体的指导原则或最佳实践?我将非常感谢有关此问题的任何帮助或指导。谢谢你。
1条答案
按热度按时间yfjy0ee71#
在
i2c_data_read
中,SCK上升沿和下降沿之间有8μS延迟,但下降沿和下一个上升沿之间没有延迟:在PIN2
变低之后,下一个周期立即开始,并且PIN2
再次变高。只需在循环体的末尾添加一些延迟。
此外,我建议您在处理I2C时使用开漏方法:将输出配置为
low
并仅切换DIR
寄存器,强制线路变为低电平,或让上拉电阻将其升高。否则,可能会出现以下情况:当MCU输出高电平时,设备试图输出低电平,从而导致短路和输出门过载。