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

 
 
> I2C на Си, Программная реализация
addi
сообщение Sep 28 2008, 16:28
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 679
Регистрация: 9-08-06
Пользователь №: 19 422



Злравствуйте, прошу поделиться отработанным кодом программной реализации I2C на Си для микроконтроллера, т.к свой вариант работает в некоторых случаях неправильно, пока не нашел причину.

Заранее благодарен.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Sep 28 2008, 17:52
Сообщение #2


Гуру
******

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



Цитата(addi @ Sep 28 2008, 19:28) *
т.к свой вариант работает в некоторых случаях неправильно, пока не нашел причину.
Ну так показали бы - вместе и нашли бы.
CODE
#ifndef I2C_SOFT_H__
#define I2C_SOFT_H__
#include <stdint.h>

#include "../common/Hardware.h"

template <uint8_t address>
class i2c_t
{
public:
static void on() {}
static void off() {}
static uint8_t read(bool ack);
static bool write(uint8_t byte);
private:
static void start();
static void stop();
static INLINE inline void SDA_low() { DRIVER(SDA, OUTPUT); }
static INLINE inline void SDA_high() { DRIVER(SDA, INPUT); }
static INLINE inline bool SDA_get() { return ACTIVE(SDA); }
static INLINE inline void SCL_low() { DRIVER(SCL, OUTPUT); }
static INLINE inline void SCL_high() { DRIVER(SCL, INPUT); }
};

template <uint8_t address>
void i2c_t<address>::start()
{
SDA_high();
SCL_high();
nop(); //nop(); nop(); nop(); // ~0.6us TSU:SUA
SDA_low();
nop(); //nop(); nop(); nop(); // ~0.6us THD:STA
SCL_low();
}

template <uint8_t address>
void i2c_t<address>::stop()
{
SDA_low();
nop(); //nop(); nop(); nop(); // ~0.6us TSU:SUA
SCL_high();
nop(); //nop(); nop(); nop(); // ~0.6us TSU:STO
SDA_high();
nop(); //nop(); nop(); nop(); // ~1.3us TBUF - TSU:SUA delay by wrapping commands
}

template <uint8_t address>
bool i2c_t<address>::write(uint8_t value)
{
uint8_t Counter = 8;
do
{
if(value & (1 << 7))
{
SDA_high();
}
else
{
SDA_low();
}
SCL_high();

value <<= 1;
SCL_low();
}
while(--Counter);


SDA_high();
SCL_high();
nop(); nop();

if(SDA_get())
{
stop();
return false;
}
SCL_low();
return true;
}

template <uint8_t address>
uint8_t i2c_t<address>::read(bool ack)
{
uint8_t Counter = 8;
uint8_t Result = 0;
do
{
SDA_high();
SCL_high();
Result <<= 1;

if(SDA_get())
Result |= 1;

SCL_low();
}
while (--Counter);

if(ack)
SDA_low();
else
SDA_high();
SCL_high();
nop(); nop();
SCL_low();
return Result;
}

#endif // I2C_SOFT_H__


--------------------
На любой вопрос даю любой ответ
"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



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

 


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


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