По поводу DS1621. Вот исходник для DS1621, подключенного к LPT-порту
писишки. Транслировался BC 3.1. Писалось наспех, только чтобы померить
температуру винчестера - так что за качество просьба не пинать (одноразовая
программа). Половинки градусов показывает - только что запустил, написала 30.5
градусов. Адрес контроллера на I2C - см #define DS1621. Адрес LPT-порта -
#define port.
Кстати - может быть, что проблемы с I2C возникают из-за того, что при
чтении при приеме последнего байта шлется ACK - а этого делать не надо.
#include <stdio.h>
#include <dos.h>
#define DS1621 0x92 // Адрес = 001
// Определения знаковых и беззнаковых типов
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
// Описание битов в порту +0 по записи
#define wVDD 0x40 // Питание
#define wSCL 0x20 // Такт
#define wSDA 0x80 // Данные
// Описание битов в порту +1 по чтению
#define rSDA 0x40 // Данные
#define rOUT 0x20 // Выход термостата
// Макросы для работы
// Ввод данных с порта
#define GET() inport(port+1)
// Вывести все сигналы
#define OUTFULL(v) outport(port, (v))
// Вывести только SDA и SCL, с паузой
#define OUT(v) OUTFULL(wVDD | (v)); Pause()
#define port 0x378
//-------------------------------------------------------------
// Короткая пауза (10 мкс для 100 кГц)
//-------------------------------------------------------------
void Pause(void)
{
int i;
for (i = 0; i < 20; i++)
GET();
}
//-------------------------------------------------------------
// Послать START
// SDA ^^^\_______
// SCL ^^^^^^^\___
//-------------------------------------------------------------
void Start(void)
{
OUT(wSDA | wSCL);
OUT(wSCL);
OUT(0);
}
//-------------------------------------------------------------
// Послать STOP
// SDA ______/^^^^^
// SCL ___/^^^^^^^^
//-------------------------------------------------------------
void Stop(void)
{
OUT(0);
OUT(wSCL);
OUT(wSDA | wSCL);
}
//-------------------------------------------------------------
// Ввести подтверждение с шины
// 0 - подтверждение есть, 1 - нет
//-------------------------------------------------------------
byte Ack(void)
{
byte v;
v = 0;
OUT(wSDA);
OUT(wSDA | wSCL);
if ((GET() & rSDA) != 0)
v = 1;
OUT(wSDA);
return v;
}
//-------------------------------------------------------------
// Передать байт на шину I2C, ввести подтверждение
//-------------------------------------------------------------
byte WriteByte(byte v)
{
byte m;
m = 0x80;
do {
if (v & m)
{
OUT(wSDA);
OUT(wSDA | wSCL);
OUT(wSDA);
}
else
{
OUT(0);
OUT(wSCL);
OUT(0);
}
m >>= 1;
} while (m);
return Ack();
}
//-------------------------------------------------------------
// Принять байт с шины I2C, послать подтверждение
// ack = 0 - подтверждение не шлем
//-------------------------------------------------------------
byte ReadByte(int ack)
{
byte n;
byte v;
n = 8; // счетчик бит
do {
v = (v << 1) | Ack(); // принять очередной бит
} while (--n != 0);
if (ack == 0)
{
OUT(wSDA);
OUT(wSDA | wSCL);
OUT(wSDA);
}
else
{
OUT(0);
OUT(wSCL);
OUT(0);
}
return v;
}
byte I2C_Write(byte cmd, byte *addr, int len)
{
Start();
if (WriteByte(DS1621) != 0)
goto Error;
if (WriteByte(cmd) != 0)
goto Error;
while (len != 0)
{
if (WriteByte(*addr++) != 0)
goto Error;
len--;
}
Stop();
return 0;
Error:
Stop();
return 1;
}
byte I2C_Read(byte cmd, byte *addr, int len)
{
Start();
if (WriteByte(DS1621) != 0)
goto Error;
if (WriteByte(cmd) != 0)
goto Error;
Start();
if (WriteByte(DS1621 | 1) != 0)
goto Error;
while (len != 0)
{
len--;
*addr++ = ReadByte(len);
}
Stop();
return 0;
Error:
Stop();
return 1;
}
byte buf[10];
byte DS_Stat(void)
{
if (I2C_Read(0xAC, buf, 1) != 0)
return 1;
if ((buf[0] & 0x0F) != 0x0A)
{
buf[0] = 2;
if (I2C_Write(0xAC, buf, 1) != 0)
return 1;
}
return I2C_Write(0xEE, buf, 0);
}
int main(void)
{
if (DS_Stat() != 0)
{
printf("Ошибка DS_Stat\n");
return 4;
}
if (I2C_Read(0xAA, buf, 2) != 0)
{
printf("Ошибка чтения температуры\n");
return 4;
}
printf("Температура = %d.%d\n", buf[0], ((buf[1] >> 7) & 1) * 5);
return 0;
}
With best regards...
Vladimir.