Вопрос по коду
- Войдите на сайт для отправки комментариев
Приветствую Всех.
Прошу помощи в переводе кода с PIC на платформу Arduino.
Из задачи:
Пример программного кода Мастера I2C
Этот пример показывает, как написать программное обеспечение Мастера I2C , включающее поддержку длинных синхро импульсов. Он написан на Cи для процессора PIC, но может быть перенесен на большинство процессоров с минимальными изменениями.
Так как линии SCL и SDA имеют открытый тип утечки, мы используем регистр управления с тремя состояниями, чтобы управлять выводом, сохраняя на выходе низкий уровень сигнала. Выводы порта должны по-прежнему читаться, так как они определены через SCL_IN и SDA_IN. Эти определения и их инициализация, вероятно, все, что Вы должны изменить в программе для другого процессора.
#define SCL TRISB4 // шина I2C #define SDA TRISB1 // #define SCL_IN RB4 // #define SDA_IN RB1 //
Для того, чтобы инициализировать порты, нужно установить выходные резисторы в 0 и регистры с тремя состояниями в 1, что отключит выводы и позволит установить на них высокий уровень сигнала с помощью резисторов.
SDA = SCL = 1; SCL_IN = SDA_IN = 0;
Мы используем маленькую подпрограмму задержки между изменениями в SDA и SCL, чтобы дать четкую последовательность на шине I2C. Это не больше чем просто вызов подпрограммы и возврат из нее.
void i2c_dly(void)
{
}
Следующие 4 функции делают: примитивное начало, завершение, чтение и запись последовательности. Все транзакции по шине I2C могут быть выполнены на основе этих функций.
void i2c_start(void)
{
SDA = 1; // последовательность стартовых битов i2c
i2c_dly();
SCL = 1;
i2c_dly();
SDA = 0;
i2c_dly();
SCL = 0;
i2c_dly();
}
void i2c_stop(void)
{
SDA = 0; // последовательность завершающих битов i2c
i2c_dly();
SCL = 1;
i2c_dly();
SDA = 1;
i2c_dly();
}
.............................................................
Как вышеуказанное будет "выглядеть" (для пинов A4,A5 (SDA,SCL)) для Ардуино?
Прошу Вашей помощи!
С уважением, GregoryAT.
p.s. Интересует именно момент инициализации (программно) портов для I2C и конкретно из приведённого кода.
Посмотрите hardware\arduino\avr\libraries\Wire\src\utility\twi.c , void twi_init(void), void twi_disable(void)
Оно?
Посмотрите hardware\arduino\avr\libraries\Wire\src\utility\twi.c , void twi_init(void), void twi_disable(void)
Оно?
Благодарю за ответ andryn.
Смотрел, но мне необходимо перевести именно то что описано выше (в моём посте).
Если я просто "возьму" например void twi_init(void), то ещё проще Wire.beginTransmission(address) и
Wire.endTransmission() ...
1. Пример софт-И2С - говенный. В том смысле, что неправильный.
2. А4 и А5 - пины для ХАРД-И2С, то есть аппаратного, можно на них и софтверный заводить.
3. примеров софт И2С под АВР (Ардуино)- дохера и больше, с разной аккуратностью и разной степенью вовлеченности ассемблера.
В теме "Attiny13 101 применение" есть моя личная реализация.... щас поищу... нашел - сообщение 966
вот код софт-и2с без ассемблера, изучай, он для тиньки, для 328 сам переделаешь. Обрати внимание на закоментированные while!!!! С т.н. "медленным слейвом" работать можно только раскоментировав это циклы ожидания освобождения шины. Для экрана 1602 или RTC - можно без них. Этот код старый и некрасивый. Если что - я поищу посвежее.
... и да, если не секрет, за каким хером тебе нужен софт-И2С?
#define _NOP() asm volatile("nop") // delay() для тиньки и свой нормальный, а delayMicroseconds() дурной //поэтому свой нужен //а вот глобального такого дефайна может и не быть, как ни странно, так для страховки завел #define F_CPU 4800000UL #define LOOP_CYCLES 8 #define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0)))) inline __attribute__((gnu_inline)) void asm_delay(uint16_t delay){ uint16_t u=us(delay); do _NOP(); while(delay--); } #define wdelay_us(x) asm_delay(us(x)) #define wdelay(x) delay(x) /*****************************************************/ //дальше мелкий вариант i2c на любых ногах //если работать через функции (закоментировано) то будет переносимость хоть куда #define IICR 1 #define IICW 0 // на 100КГц примерно по 4 мкс нужно держать уровни SCL - со скоростью сами экспериментируйте, мне не нужно было #define I2CDelay() wdelay_us(5) #define SDA_Pin 0 #define SCL_Pin 1 /* #define SDA_In() digitalRead(SDA_Pin) #define SCL_In() digitalRead(SCL_Pin) void SDA_Hi() { digitalWrite(SDA_Pin, HIGH); pinMode(SDA_Pin, INPUT);} void SDA_Lo() { digitalWrite(SDA_Pin, LOW ); pinMode(SDA_Pin, OUTPUT);} void SCL_Hi() { digitalWrite(SCL_Pin, HIGH); pinMode(SCL_Pin, INPUT);} void SCL_Lo() { digitalWrite(SCL_Pin, LOW ); pinMode(SCL_Pin, OUTPUT);} */ #define SDA_In() (PINB & 0B00000001) #define SCL_In() (PINB & 0B00000010) inline void SDA_Hi() { PORTB |= 0B00000001; DDRB &= 0B11111110;} inline void SDA_Lo() { PORTB &= 0B11111110; DDRB |= 0B00000001;} inline void SCL_Hi() { PORTB |= 0B00000010; DDRB &= 0B11111101;} inline void SCL_Lo() { PORTB &= 0B11111101; DDRB |= 0B00000010;} void I2CInit (void) { SDA_Hi(); SCL_Hi(); } void I2CStart (void) { SCL_Hi(); //while (!SCL_In()); I2CDelay(); SDA_Lo(); I2CDelay(); SCL_Lo(); } void I2CStop (void) { SCL_Lo(); SDA_Lo(); I2CDelay(); SCL_Hi(); //while(!SCL_In()); I2CDelay(); SDA_Hi(); I2CDelay(); } boolean I2CWrite(byte b) { byte i = 1<<7; boolean ack=0; while(i) { //I2CDelay(); if (b & i) SDA_Hi(); else SDA_Lo(); I2CDelay(); SCL_Hi(); I2CDelay(); SCL_Lo(); i>>=1; } SDA_Hi(); I2CDelay(); SCL_Hi(); // while(!SCL_In()); if ( SDA_In()==0 ) ack = 1; I2CDelay(); SCL_Lo(); SDA_Hi(); return ack; } byte I2CRead(boolean ack) { byte i=8; byte b=0; while(i--) { b <<= 1; SCL_Lo(); SDA_Hi(); I2CDelay(); SCL_Hi(); //while(!SCL_In()); if (SDA_In()) b |= 1; I2CDelay(); SCL_Lo(); } if (ack) SDA_Lo(); else SDA_Hi(); I2CDelay(); SCL_Hi(); //while(!SCL_In()); I2CDelay(); SCL_Lo(); return (b); }to:wdrakula
Благодарю за помощь, буду разбираться.
p.s. to All, пост по-прежнему актуален.
С уважением, GregoryAT.
Как вышеуказанное будет "выглядеть" (для пинов A4,A5 (SDA,SCL)) для Ардуино?
Стесняюсь спросить, на какой твой вопрос не получен ответ в моем коде?
Слепой или тупой?
Стесняюсь спросить, на какой твой вопрос не получен ответ в моем коде?
Слепой или тупой?
Ответ - афтор мозахист.
to:wdrakula
Теперь уже я стесняюсь спросить:
//Стесняюсь спросить, на какой твой вопрос не получен ответ в моем коде?
//
Если по поводу приведённого Вами листинга, то я поблагодарил Вас и сообщил что буду разбираться, разве я что-нибудь написал Вам по поводу Вашего кода?
И ещё, кому Вы адресуете вопрос:
Слепой или тупой?
to:mykaida:
От Вас, уважаемый вообще "тишина" (по поводу поста), так Вы ещё
умудряетесь предпринимать попытки оскорблять. Вам заняться нечем?
to:mykaida:
От Вас, уважаемый вообще "тишина" (по поводу поста), так Вы ещё
умудряетесь предпринимать попытки оскорблять. Вам заняться нечем?
Ну как сказать - Вы (Вы) хотите писать ассемблер на си? Флаг Вам в руки. Зачем?
from:mykaida
Ну как сказать - Вы (Вы) хотите писать ассемблер на си? Флаг Вам в руки. Зачем?
to:mykaida
Вам оно надо?
p.s.А флаг оставьте при себе.
to: wdrakula:
Большое спасибо за помощь, то что надо.
С уважением, GregoryAT.