英文:
24c32a eeprom write operation not working with attiny402..am i mistaken?
问题
#define sda_on PORTA_DIRSET = PIN1_bm ; PORTA_OUTSET = PIN1_bm ;
#define sda_read PORTA_DIRCLR = PIN1_bm ;while(PORTA_IN & (PIN1_bm));PORTA_DIRSET = PIN1_bm ;
#define sda_off PORTA_DIRSET = PIN1_bm ;PORTA_OUTCLR = PIN1_bm ;
#define scl_on PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
#define scl_off PORTA_DIRSET = PIN2_bm ;PORTA_OUTCLR = PIN2_bm ;
#include <xc.h>
#include <util/delay.h>
void i2c_start(void)
{
sda_on;
scl_on;
_delay_ms(10);
sda_off;
_delay_ms(10);
scl_off;
}
void i2c_stop(void)
{
sda_off;
scl_off;
_delay_ms(10);
scl_on;
_delay_ms(10);
sda_on;
}
void i2c_data_write(unsigned char data)
{
for(int i=0;i<8;i++)
{
if(data & 0x80)
{
sda_on;
}
else sda_off;
_delay_ms(10);
scl_on;
_delay_ms(10);
scl_off;
data = data << 1;
}
scl_on;
sda_on;
_delay_ms(10);
sda_read;
_delay_ms(10);
scl_off;
_delay_ms(10);
}
英文:
#define sda_on PORTA_DIRSET = PIN1_bm ; PORTA_OUTSET = PIN1_bm ;
#define sda_read PORTA_DIRCLR = PIN1_bm ;while(PORTA_IN & (PIN1_bm));PORTA_DIRSET = PIN1_bm ;
#define sda_off PORTA_DIRSET = PIN1_bm ;PORTA_OUTCLR = PIN1_bm ;
#define scl_on PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
#define scl_off PORTA_DIRSET = PIN2_bm ;PORTA_OUTCLR = PIN2_bm ;
#include <xc.h>
#include <util/delay.h>
void i2c_start(void)
{
sda_on;
scl_on;
_delay_ms(10);
sda_off;
_delay_ms(10);
scl_off;
}
void i2c_stop(void)
{
sda_off;
scl_off;
_delay_ms(10);
scl_on;
_delay_ms(10);
sda_on;
}
void i2c_data_write(unsigned char data)
{
for(int i=0;i<8;i++)
{
if(data & 0x80)
{
sda_on;
}
else sda_off;
_delay_ms(10);
scl_on;
_delay_ms(10);
scl_off;
data = data << 1;
}
scl_on;
sda_on;
_delay_ms(10);
sda_read;
_delay_ms(10);
scl_off;
_delay_ms(10);
}
Its a just write operation in 24c32a eeprom using by Attiny402..its not working ..im using simulating with debugging by proteus software....i2c debugger gives always question mark while im run the simulation help me..
答案1
得分: 1
一个快速的答案:这些宏应该被改成使用按位或赋值|=
和按位与赋值&=
。
#define sda_on PORTA_DIRSET |= PIN1_bm; PORTA_OUTSET |= PIN1_bm;
#define scl_on PORTA_DIRSET |= PIN2_bm; PORTA_OUTSET |= PIN2_bm;
宏sda_on
将PORTA_OUTSET
设置为值PIN1_bm
,而宏scl_on
将PORTA_OUTSET
设置为值PIN2_bm
。
从这些宏中,我们知道sda
和scl
这两个引脚都在PORTA
上,并且这些宏使用了这两个引脚的位掩码。通常,端口引脚的位掩码只有一个位被设置,例如0x01或0x02或0x04等等。
然后,在i2c_start()
函数的开头,一个sda_on
后面跟着一个scl_on
,这会使得PORTA
的值设置为PIN2_bm
而不是正确的值PIN1_bm | PIN2_bm
,这样可以将两个引脚都设置为i2c起始条件的设置时间内的高电平。
void i2c_start(void)
{
sda_on; // PORTA_DIRSET |= PIN1_bm; PORTA_OUTSET |= PIN1_bm;
scl_on; // PORTA_DIRSET |= PIN2_bm; PORTA_OUTSET |= PIN2_bm;
// 此时,PORTA_DIRSET |= PIN2_bm; PORTA_OUTSET |= PIN2_bm;
// 但是不是PORTA_DIRSET |= PIN1_bm | PIN2_bm; PORTA_OUTSET |= PIN1_bm | PIN2_bm;
_delay_ms(10);
sda_off;
_delay_ms(10);
scl_off;
}
所以,粗略的解决方案是将宏修改为如下所示。
#define scl_on PORTA_DIRSET |= PIN2_bm; PORTA_OUTSET |= PIN2_bm;
#define scl_off PORTA_DIRSET &= ~PIN2_bm; PORTA_OUTCLR &= ~PIN2_bm;
或者,如果没有其他引脚与之共享同一个端口,你可以将两个引脚分别放在两个端口上,例如sda
放在PORTA
上,scl
放在PORTB
上,这样按位或赋值|=
和按位与赋值&=
将不是必要的。
英文:
a quick answer: those macros should be changed to use bit-wise-OR assignment |=
and bit-wise-AND assignment &=
instead.
#define sda_on PORTA_DIRSET = PIN1_bm ; PORTA_OUTSET = PIN1_bm ;
#define scl_on PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
The macro sda_on
sets PORTA_OUTSET
to the value PIN1_bm
, while the macro scl_on
sets PORTA_OUTSET
to the value PIN2_bm
.
From those macros, we know the two pins sda
and scl
are both on PORTA
, and the macros operate with bit-mask for the two pins. In general, a bit-mask of port pin would have only one bit set, like 0x01 or 0x02 or 0x04, and so on.
Then, at the beginning of i2c_start()
, a sda_on
is followed by a scl_on
, that makes the value of PORTA
set to PIN2_bm
but not the correct value PIN1_bm | PIN2_bm
which will set both pins to high level for the setup-time of a start-condition of i2c.
void i2c_start(void)
{
sda_on; // PORTA_DIRSET = PIN1_bm ; PORTA_OUTSET = PIN1_bm ;
scl_on; // PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
// at this point, PORTA_DIRSET = PIN2_bm ;PORTA_OUTSET = PIN2_bm ;
// But not, PORTA_DIRSET = PIN1_bm | PIN2_bm ;PORTA_OUTSET = PIN1_bm | PIN2_bm ;
_delay_ms(10);
sda_off;
_delay_ms(10);
scl_off;
}
So, the rough solution is to change the macros like the followings.
#define scl_on PORTA_DIRSET |= PIN2_bm ;PORTA_OUTSET |= PIN2_bm ;
#define scl_off PORTA_DIRSET &= ~PIN2_bm ;PORTA_OUTCLR &= ~PIN2_bm ;
Or, you could use two ports for the two pins, like sda
on PORTA
and scl
on PORTB
, if there is no other pin sharing the same port, then the bit-wise-OR assignment |=
and bit-wise-AND assignment &=
would be not necessary.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论