реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Внешняя I2C EEPROM 24AA1025
Pavel_Bor
сообщение Jul 12 2011, 09:05
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Код
.......
void Serial_Flash_Write(unsigned char byte,unsigned char card_adr,unsigned char adress_H,unsigned char adress_L)
{
    SF_Start_Soft();
    SF_Tx_Soft(AA1025_ADDR|card_adr|WR);    //adress Memory Card
    SF_Tx_Soft(adress_H);            //adress High
    SF_Tx_Soft(adress_L);            //adress Low  
    SF_Tx_Soft(byte);
    SF_Stop_Soft();
}
.......



CODE
.......
#define SERIAL_FLASH_DATA_DIR_SET PORTD.DIRSET|=(1<<SERIAL_FLASH_DATA)
#define SERIAL_FLASH_DATA_DIR_CLR PORTD.DIRCLR&=(1<<SERIAL_FLASH_DATA)
#define SERIAL_FLASH_DATA_SET PORTD.OUTSET|=(1<<SERIAL_FLASH_DATA)
#define SERIAL_FLASH_DATA_CLR PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA)

#define SERIAL_FLASH_SCL_DIR_SET PORTD.DIRSET|=(1<<SERIAL_FLASH_SCL)
#define SERIAL_FLASH_SCL_UP PORTD.OUTSET|=(1<<SERIAL_FLASH_SCL)
#define SERIAL_FLASH_SCL_DOWN PORTD.OUTCLR&=(1<<SERIAL_FLASH_SCL)

void SF_Init_Soft(void);
void SF_Start_Soft(void);
void SF_Stop_Soft(void);
void SF_Tx_Soft(unsigned char byte);
unsigned char SF_Rx_Soft(unsigned char last_byte);
unsigned char SF_In_Sda(void);

unsigned char SF_error_soft; //error

void SF_Init_Soft(void) //Init Programm I2C
{

SERIAL_FLASH_DATA_DIR_SET;
SERIAL_FLASH_SCL_DIR_SET;
SERIAL_FLASH_SCL_UP; //and SCL in high impedance condition
SF_error_soft=0; //for first no error :-)
}

void SF_Start_Soft(void) //Set Start condition
{
if(SF_error_soft)
return;
SERIAL_FLASH_DATA_DIR_SET;
SERIAL_FLASH_DATA_SET;
delay_us(100);
SERIAL_FLASH_SCL_UP;
delay_us(100);
SERIAL_FLASH_DATA_CLR;
delay_us(100);
SERIAL_FLASH_SCL_DOWN;
}

void SF_Stop_Soft(void) //Set Start condition
{
SERIAL_FLASH_DATA_DIR_SET;
SERIAL_FLASH_DATA_CLR;
delay_us(100);
SERIAL_FLASH_SCL_UP;
delay_us(100);
SERIAL_FLASH_DATA_SET;
delay_us(100);
if(SF_error_soft)
SF_Init_Soft();
}

void SF_Tx_Soft(unsigned char byte) //Send Byte
{
unsigned char count;
if(SF_error_soft)
return;

SERIAL_FLASH_DATA_DIR_SET;
if(SF_error_soft)
return;
for(count=0;count<8;count++)
{
if(byte&0x80)
SERIAL_FLASH_DATA_SET;
else
SERIAL_FLASH_DATA_CLR;
SERIAL_FLASH_SCL_UP;
delay_us(10);
SERIAL_FLASH_SCL_DOWN;
delay_us(10);
byte<<=1;
}
SERIAL_FLASH_DATA_DIR_CLR;
SERIAL_FLASH_SCL_UP;
SF_error_soft=SF_In_Sda();
rtcTime.status=SF_error_soft;
delay_us(10);
SERIAL_FLASH_SCL_DOWN;
delay_us(10);
}

unsigned char SF_Rx_Soft(unsigned char last_byte)
//Recieve byte,if last_byte=0, then bytes? which recieved is last, and no needed request from master
{
unsigned char data=0;
unsigned char mask=0x80;
unsigned char count;

if(SF_error_soft)
return 0;
SERIAL_FLASH_DATA_DIR_CLR;
for(count=0;count<8;count++)
{
SERIAL_FLASH_SCL_UP;
delay_us(10);
if(SF_In_Sda())
data=data+mask;
mask>>=1;
SERIAL_FLASH_SCL_DOWN;
delay_us(10);
}
SERIAL_FLASH_DATA_DIR_SET;
if(last_byte)
SERIAL_FLASH_DATA_CLR;
else
SERIAL_FLASH_DATA_SET;
SERIAL_FLASH_SCL_UP;
delay_us(10);
SERIAL_FLASH_SCL_DOWN;
delay_us(10);
return data;
}

unsigned char SF_In_Sda(void) //Return SDA_line level
{
if(PORTD.IN&(1<<SERIAL_FLASH_DATA))
return 1;
else
return 0;
}
.......


Программа работает неверно, при 4 входе в запись нет АСК.
В чем может быть причина?

Сообщение отредактировал IgorKossak - Jul 21 2011, 14:22
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 13 2011, 09:58
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 12 2011, 12:05) *
В чем может быть причина?
http://electronix.ru/forum/index.php?s=&am...st&p=231608 и далее по ветке.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 21 2011, 12:09
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(Сергей Борщ @ Jul 13 2011, 12:58) *

Ветка очень интересная.
из ветки:
1. Изменил код программы.
2. В моей схеме подтяжек нет. Какого номинала подтяжки лучше поставить.
3. При чтении всегда АСК не успевает пройти, как решить эту проблему.

Проблемы:
1. При чтении "неважно чего" получаю 255
2. АСК проходит через раз, независимо это R/W.
3. попробовал через цикл while(!i2cPutbyte(i2cAddr)); АСК проходит но значения также не те.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 21 2011, 12:43
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 21 2011, 15:09) *
1. Изменил код программы.
2. В моей схеме подтяжек нет. Какого номинала подтяжки лучше поставить.
Для небольшой платы и одного slave на частоте до 100КГц хватает 4.7К. Если вы изменили код программы и перестали выдавать единицу из контроллера методом
CODE
#define SERIAL_FLASH_DATA_SET       PORTD.OUTSET|=(1<<SERIAL_FLASH_DATA)
, то у вас вообще все должно перестать работать, что правильно. Как вы умудряетесь читать 255, если единице на шине без подтяжек взяться просто неоткуда - загадка. Разберитесь с этим, будем смотреть дальше.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jul 21 2011, 12:46
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата
В моей схеме подтяжек нет. Какого номинала подтяжки лучше поставить
-4.7ком


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 21 2011, 13:30
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



код изменял в соответствии с тем который описан в ссылке

CODE
#define ADR24AA1025 0xA0 //Адрес карты памяти
#define ADDR_HI 0x08 // Выбор верхней или нижний части памяти
#define ADDR_LOW 0x0
#define CARD_ADDR1 0 //4 карты памяти на шине
#define CARD_ADDR2 2 //
#define CARD_ADDR3 4 //
#define CARD_ADDR4 6

#define READ 0x01 // I2C бит чтения

#define SERIAL_FLASH_DATA 4 // I2C данные: Порт D бит 4
#define SERIAL_FLASH_SCL 5 // I2C строб: Порт D бит 5

#define QDEL delay_us(10) // задержка 10мкс
#define HDEL delay_us(20) // задержка 20мкс

#define I2C_SDL_LO PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA); // DATA = 0
#define I2C_SDL_HI PORTD.OUTSET|=(1<<SERIAL_FLASH_DATA); // DATA = 1

#define I2C_SCL_LO PORTD.OUTCLR&=(1<<SERIAL_FLASH_SCL); //аналогично
#define I2C_SCL_HI PORTD.OUTSET|=(1<<SERIAL_FLASH_SCL);

#define OUT(BIT) (PORTD.DIRSET|=(1<<BIT))
#define IN(BIT) (PORTD.DIRCLR&=(1<<BIT))

#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO;
#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;




// Запись байта на устройство
bool i2cPutbyte(uint8_t cool.gif
{
int8_t i;
uint8_t j;
rtcTime.status=0;
j=0x80;
for (i=7;i>=0;i--)
{
if ( b & j )
I2C_SDL_HI;
else
I2C_SDL_LO; // address bit
I2C_SCL_TOGGLE; // clock HI, delay, then LO
j >>= 1;
}
IN(SERIAL_FLASH_DATA); // change direction to input on SDA line (may not be needed)
I2C_SDL_HI; // leave SDL HI
// added

HDEL;
I2C_SCL_HI; // clock back up
HDEL;
b = (PORTD.IN&SERIAL_FLASH_DATA); // get the ACK bit
rtcTime.status=b; //отслеживаю АСК и через раз он равен 1.

I2C_SCL_LO; // not really ??
OUT(SERIAL_FLASH_DATA); // change direction back to output
HDEL;
return (b == 0); // return ACK value
}




// чтение байта из устройство
uint8_t i2cGetbyte(uint8_t last)
{
int i;
uint8_t b = 0;

I2C_SDL_HI; // make sure pullups are ativated
IN(SERIAL_FLASH_DATA); // change direction to input on SDA line (may not be needed)

for(i=7;i>=0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
if((PORTD.IN&(1<<SERIAL_FLASH_DATA))!=0){ b |= 1;} // Может быть что-то здесь?
b <<= 1;
HDEL;
I2C_SCL_LO; // clock LO
}

OUT(SERIAL_FLASH_DATA); // change direction to output on SDA line

if (last)
I2C_SDL_HI; // set NAK
else
I2C_SDL_LO; // set ACK

I2C_SCL_TOGGLE; // clock pulse
I2C_SDL_HI; // leave with SDL HI
return b; // return received byte
}



//! Initialize I2C communication
void i2cInit(void)
{
OUT(SERIAL_FLASH_DATA); // set SDA as output
OUT(SERIAL_FLASH_SCL); // set SCL as output
I2C_SDL_HI; // set I/O state and pull-ups
I2C_SCL_HI; // set I/O state and pull-ups
}




//Чтение одного байта с указанием адреса
uint8_t i2ceepromReadByte(uint16_t memAddr,unsigned char card,bool H_L)
{
uint8_t i2cAddr=0;

I2C_START;
if (H_L) i2cAddr=((ADR24AA1025&0xfe)||ADDR_HI||card);
else i2cAddr=((ADR24AA1025&0xfe)||card);

i2cPutbyte(i2cAddr));
i2cPutbyte((memAddr>>8) & 0xff)
i2cPutbyte(memAddr & 0xff);
HDEL;
I2C_SCL_HI; // do a repeated START
I2C_START; // transition

while(!i2cPutbyte(i2cAddr||READ)); // resend DEVICE, with READ bit set
memAddr = i2cGetbyte(1);
I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
return ((uint8_t)memAddr);
}




// Запись одного байта с указанием адреса
void i2ceepromWriteByte(uint16_t memAddr,unsigned char card, bool H_L, uint8_t data)
{
uint8_t i2cAddr=0;

I2C_START;
if (H_L) i2cAddr=((ADR24AA1025&0xfe)||ADDR_HI||card);
else i2cAddr=((ADR24AA1025&0xfe)||card);

i2cPutbyte(i2cAddr);
i2cPutbyte((memAddr>>8) & 0xff)
i2cPutbyte(memAddr & 0xff);
i2cPutbyte(data);

I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
}


Цитата
Как вы умудряетесь читать 255, если единице на шине без подтяжек взяться просто неоткуда - загадка. Разберитесь с этим, будем смотреть дальше.

Самому интересно. Буду пытаться найти ошибку.

Вызов идет вот отсюда

CODE
i2ceepromWriteByte(0,CARD_ADDR1, 0, 15); //Пишу значение 15 на младшую часть памяти 1, с адресом 0.
Digit(rtcTime.status); // отслеживаю АСК

i2ceepromWriteByte(0,CARD_ADDR1, 0, 15);
Digit(rtcTime.status);

i2ceepromWriteByte(0,CARD_ADDR1, 0, 15);
Digit(rtcTime.status);

i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);

i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);

i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);

Digit(i2ceepromReadByte(0,CARD_ADDR1,0)); // читаю и вывожу на экран
Digit(rtcTime.status); // слежу за АСК

Digit(i2ceepromReadByte(0,CARD_ADDR1,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(0,CARD_ADDR1,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);

Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);


Данный результат
0 0 4 0 0 0 // АСК=1 при 3 записи... Динамически изменяется при прошивке

|| 1 ячейка 1 пам ||2 ячейка 2 пам || карта 3 3 пам || Карта 3 пока что отсутсвует. Читать нечего. Но появляются какие-то данные.
44 0 218 0 150 0 186 0 110 0 182 0 36 0 150 0 222 0 Похоже что сеанс чтения прошел без ошибок. Но почему тогда читаемые с одной ячейки постоянно меняются? Плавающий адрес?

Сообщение отредактировал IgorKossak - Jul 21 2011, 14:20
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 21 2011, 13:48
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 21 2011, 16:30) *
код изменял в соответствии с тем который описан в ссылке
Читайте еще раз, до просветления.

Так делать нельзя:
CODE
#define I2C_SDL_LO      PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA);       // DATA = 0
#define I2C_SDL_HI      PORTD.OUTSET|=(1<<SERIAL_FLASH_DATA);        // DATA = 1

#define I2C_SCL_LO      PORTD.OUTCLR&=(1<<SERIAL_FLASH_SCL);         //аналогично
#define I2C_SCL_HI      PORTD.OUTSET|=(1<<SERIAL_FLASH_SCL);


Надо делать так:
CODE
#define I2C_SDL_LO      PORTD.DIRSET=(1<<SERIAL_FLASH_DATA);       // OUTPUT!!!!, DATA = 0
#define I2C_SDL_HI      PORTD.DIRCLR=(1<<SERIAL_FLASH_DATA);       // INPUT!!!      DATA = 1

#define I2C_SCL_LO      PORTD.DIRSET=(1<<SERIAL_FLASH_SCL);         //аналогично
#define I2C_SCL_HI      PORTD.DIRCLR=(1<<SERIAL_FLASH_SCL);
А перед всем этим записать в эти биты порта 0, чтобы включение порта на вывод выдавало 0 на линию, а при переключении на ввод - появлялась единица от резистора подтяжки.

Писал эти строки и возник странный, казалось бы, вопрос - процессор-то у вас какой? Судя по наличию регистров DIRSET и DIRCLR можно предположить что-то из хмег. Я с ними не работал, но вы уверены, что в эти регистры нужно писать через &= и |= ? Зачем делать отдельные регистры, если работать с ними через чтение-модификацию-запись? Я написал строки выше исходя из логики портов ARM, если что - поправьте запись, но чтобы она отражала то, что написано в комментариях.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 22 2011, 06:17
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата
Надо делать так:
Код
#define I2C_SDL_LO      PORTD.DIRSET=(1<<SERIAL_FLASH_DATA);       // OUTPUT!!!!, DATA = 0
#define I2C_SDL_HI      PORTD.DIRCLR=(1<<SERIAL_FLASH_DATA);       // INPUT!!!      DATA = 1

#define I2C_SCL_LO      PORTD.DIRSET=(1<<SERIAL_FLASH_SCL);         //аналогично
#define I2C_SCL_HI      PORTD.DIRCLR=(1<<SERIAL_FLASH_SCL);
А перед всем этим записать в эти биты порта 0, чтобы включение порта на вывод выдавало 0 на линию, а при переключении на ввод - появлялась единица от резистора подтяжки.


#define I2C_SDL_LO PORTD.DIRSET=(1<<SERIAL_FLASH_DATA); // OUTPUT!!!! (При такой записи получаем PORTD.DIRSET=0x04 остальные функции порта теряются поэтому PORTD.DIRSET|=0x04)

I2C_SDL_LO в данном случае будет контролировать только направление. А состояние порта контролирует PORTD.OUTSET


Цитата
А перед всем этим записать в эти биты порта 0, чтобы включение порта на вывод выдавало 0 на линию, а при переключении на ввод - появлялась единица от резистора подтяжки.

Ну тогда пожалуй так:
Код
#define I2C_SDL_LO      PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA); PORTD.DIRSET|=(1<<SERIAL_FLASH_DATA);       // OUTPUT, DATA = 0
#define I2C_SDL_HI      PORTD.DIRSET|=(1<<SERIAL_FLASH_DATA);    PORTD.DIRCLR&=(1<<SERIAL_FLASH_DATA);       // INPUT, DATA = 1



Повесил подтяжки. Без изменений.

Сообщение отредактировал Pavel_Bor - Jul 22 2011, 07:35
Go to the top of the page
 
+Quote Post
Андрей190
сообщение Jul 22 2011, 07:27
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 24-12-06
Из: Орел
Пользователь №: 23 838



если речь об XMEGA
то, как уже выше было сказано, в конструкции

PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA);
PORTD.DIRCLR&=(1<<SERIAL_FLASH_DATA);

"&" не нужен

PORTD.OUTCLR=(1<<SERIAL_FLASH_DATA);
PORTD.DIRCLR=(1<<SERIAL_FLASH_DATA);

Сообщение отредактировал Андрей190 - Jul 22 2011, 07:30
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 22 2011, 07:56
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 22 2011, 09:17) *
(При такой записи получаем PORTD.DIRSET=0x04 остальные функции порта теряются поэтому PORTD.DIRSET|=0x04)
Еще раз подумайте, зачем разработчики заложили два регистра - DIRSET и DIRCLR? Наверное для того, чтобы записью в один устанавливать линии на вывод, а записью во второй - на ввод. Записью, а не чтением-изменением-записью.

QUOTE (Pavel_Bor @ Jul 22 2011, 09:17) *
Ну тогда пожалуй так:
Зачем каждый раз писать в PORTD.OUTCLR, если вы никогда не пишете этот бит в PORTD.OUTSET? Состояние порта остается прежним, в OUTCLR можно записать один раз при старте контроллера. В I2C_SDL_HI вы тоже погорячились.
QUOTE (Pavel_Bor @ Jul 22 2011, 09:17) *
Повесил подтяжки. Без изменений.
Попробуйте вставить ожидание нажатия кнопки после каждого изменения на I2C и добейтесь (наблюдая вольтметром), чтобы там появлялись именно те уровни, которые вы ожидаете.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 22 2011, 08:02
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(Сергей Борщ @ Jul 22 2011, 10:56) *
Еще раз подумайте, зачем разработчики заложили два регистра - DIRSET и DIRCLR? Наверное для того, чтобы записью в один устанавливать линии на вывод, а записью во второй - на ввод. Записью, а не чтением-изменением-записью.

Скорее всего. Ведь есть отдельно - PORTD.DIR=0xff; и в этом случае нужно использовать логику.
Цитата
Зачем каждый раз писать в PORTD.OUTCLR, если вы никогда не пишете этот бит в PORTD.OUTSET? Состояние порта остается прежним, в OUTCLR можно записать один раз при старте контроллера. В I2C_SDL_HI вы тоже погорячились.

Не совсем понял
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 22 2011, 08:25
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 22 2011, 11:02) *
Скорее всего. Ведь есть отдельно - PORTD.DIR=0xff; и в этом случае нужно использовать логику.
О! Слова юноши, но мужа.

QUOTE (Pavel_Bor @ Jul 22 2011, 11:02) *
Не совсем понял
Если внимательно посмотреть логику порта, то там есть регистр OUT, который хранит выводимое значение, и регистр DIR, который подключает выход регистра OUT к ножке порта. Т.е. если вы один раз записали в нужный бит регистра OUT ноль и больше ничего в этот битик не пишите, то этот ноль оттуда никуда не денется, значит прописать его туда достаточно лишь один раз, а не в каждом I2C_SDL_LO


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 22 2011, 08:46
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(Сергей Борщ @ Jul 22 2011, 11:25) *
О! Слова юноши, но мужа.

Если внимательно посмотреть логику порта, то там есть регистр OUT, который хранит выводимое значение, и регистр DIR, который подключает выход регистра OUT к ножке порта. Т.е. если вы один раз записали в нужный бит регистра OUT ноль и больше ничего в этот битик не пишите, то этот ноль оттуда никуда не денется, значит прописать его туда достаточно лишь один раз, а не в каждом I2C_SDL_LO


А если мне этот битик нужно поднять в 1? например когда я отправляю данные. Этот бит может изменяться
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 22 2011, 09:06
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Pavel_Bor @ Jul 22 2011, 11:46) *
А если мне этот битик нужно поднять в 1?
Мама! И здесь, и в ветке на которую я вас послал основная мысль была одна:
QUOTE (Сергей Борщ @ Jul 21 2011, 16:48) *
чтобы включение порта на вывод выдавало 0 на линию, а при переключении на ввод - появлялась единица от резистора подтяжки.

"Выдавать" единицу на линии I2C из контроллера записью в OUT 1 нельзя по идеологии самой шины!


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 22 2011, 09:42
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(Сергей Борщ @ Jul 22 2011, 12:06) *
Мама! И здесь, и в ветке на которую я вас послал основная мысль была одна:
"Выдавать" единицу на линии I2C из контроллера записью в OUT 1 нельзя по идеологии самой шины!


Выходит что на линии всегда висит единица, кроме тех моментов, когда микросхема или контроллер формируют ноль?
Чтобы выдавать единицу достаточно направление порта сделать входом с включенной подтяжкой? (Вот здесь OUT=1)?

Получается что смысла в инициализации тогда тоже нет.

А как насчет вот этих строк
Код
#define     SERIAL_FLASH_DATA  4           // I2C данные: Порт D бит 4
#define     SERIAL_FLASH_SCL    5           // I2C строб:  Порт D бит 5
......
if((PORTD.IN&(SERIAL_FLASH_DATA))!=0){ b |= 1;} // При чтении            
..........                                                                   //                           PORTD&0b00000100 ?
b = (PORTD.IN&(SERIAL_FLASH_DATA));                 // При записи


Я думаю здесь ошибка.

Сообщение отредактировал Pavel_Bor - Jul 22 2011, 09:30
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.0167 секунд с 7
ELECTRONIX ©2004-2016