Софтовый i2c и общение с датчиком DS1624

Возник на горизонте один проект, в котором было решено использовать новые контроллеры с продвинутым Сигма-дельта АЦП 24бит (!) MSP430AFE253. У контроллера встроенно три(!) независимых сигма-дельта АЦП, и это чудо в компеле стоит около 2$.
Заказал у TI some Free samples и попросил заказчика купить небольшую партию для установочного производства… Срок поставки 3 недели. Решил пока поэксперементировать с недавно пришедшими по FedEx в наши *ня двумя новыми MSP430G2452, которые дружат с Launchpad после обновления прошивки. На них и отработаю soft i2c.
Проблема у 253 следующая: там нет аппаратного модуля i2c. Но этот кристалл также должен управлять цифровыми потенциометрами по этому протоколу. Сначала я пригорюнился, но потом храбро решил реализовать i2c программно. В режиме мастера это не так сложно…

Digipot тоже ехал с эльфийского Запада неторопливо. Поэтому, порывшись по сусекам обнаружил завалявшийся DS1624 — продвинутый цифровой термометр, с точностью до 0.3С.
Почему нет? попробую считать температуру, используя софтовый i2c.
Нашел замечательную библиотеку у levap. Вся библиотека состоит из 2х файлов — i2c_soft.h и i2c_soft.c.
Достаточно в i2c_soft.h прописать какие порты и пины используются, и почти все заработает. Правда его библиотека под msp-gcc, а я проект делал в Code composer studio. Поэтому вызов функции nop() пришлось заменить на _nop().
Для линий данных использовал GPIO пин 2.4 а для синхронизации 2.3.

#define	I2COUT		P2OUT    // Write to Port
#define	I2CIN		P2IN     // Read from Port
#define	I2CDIR		P2DIR    // Set Port Direction
#define	I2CSEL		P2SEL    // Alternative Port Fuctions


#define SDA       	BIT4     // Serial Data Line PIN
#define SCL       	BIT3     // Serial Clock Line PIN


Потом распаял на макетке датчик температуры, 2 подтягивающих резистора 4.7кОм на Vcc, заземлил выходы датчика A1-A3 (см. даташит).
Вот что получилось:
подключение
Снимал телефоном, качество не очень. Но понять что к чему подключено можно. На датчик +5В брал с USB разъема.
Для быстрой смены параметров кристалла использовал Grace — новую визуальную примочку к CCS от TI. Позволяет визуально задавать параметры кристалла (тактирование, пины, USI и т.д.). Неплохая вещь, хотя можно и без нее.
Вот код общения с датчиком по i2c:
#define ACCESS_MEM      0x17
#define ACCESS_CONF     0xAC
#define READ_TEMP       0xAA
#define START_CONVERT   0xEE
#define STOP_CONVERT    0x22
#define READ            0x01
#define WRITE           0x00






unsigned int DS1624ReadTemperature(void)
{
    volatile unsigned int temp, ack;
    i2c_Init();
    i2c_Start();
    ack=i2c_Write(0x90); // W=0,R=1 b1001000W 
    ack=i2c_Write(START_CONVERT); 
    while(1)
    {
  	i2c_Start();
        ack=i2c_Write(0x90);
        ack=i2c_Write(ACCESS_CONF);
        i2c_Start();
        ack=i2c_Write(0x90);
        if (i2c_Read(0) & 0x80)
            break;
    }
    i2c_Start();
    ack=i2c_Write(0x90);
    ack=i2c_Write(READ_TEMP);
    i2c_Start();
    ack=i2c_Write(0x91);//read
    temp = (unsigned int)i2c_Read(1);//1st byte
   // temp <<= 8;
   // temp |= (unsigned int)i2c_Read(1);//2nd byte. дает точность 0.3С после запятой. Ненадо
   if (temp>125)//если t меньше 0
   {
   		temp = 255-temp;
   }
   
    i2c_Stop();
    return temp;
}

PS это репост статьи из моего бложика

UPD приложил исходники проекта в CSS по просьбе господина haradrime
Файлы в топике: soft_i2c.zip

Комментарии (45)

RSS свернуть / развернуть
А можно ли шить MSP430AFE253 через Launchpad?
0
  • avatar
  • ZiB
  • 13 сентября 2011, 10:10
нет, так как AFE только в корпусе TSSOP20
0
А через переходник или ISP разъем? Другими словами, оно Spy-Bi-Wire держит?
0
  • avatar
  • Vga
  • 13 сентября 2011, 10:21
SPW держит
0
сибки.
жаль что ОЗУ мало :( 512 байт всего.
0
  • avatar
  • ZiB
  • 13 сентября 2011, 10:31
а зачем больше?
0
для фильтров и прочей ерунды
0
  • avatar
  • ZiB
  • 13 сентября 2011, 11:00
>>Поэтому вызов функции nop() пришлось заменить на _nop().
сделай условную компиляцию… типа

#if defied __GNUC__
  // do nothing
#elif defined __TI_COMPILER_VERSION__
  #define nop() _nop()
#endif
0
библиотека не моя :) я просто разместил объяву %)
0
Для прошивки MSP430AFE253 подойдёт такой программатор?
www.ebay.com/itm/Advanced-MSP430-BSL-USB-programmer-download-cable-/160644297600?pt=LH_DefaultDomain_0&hash=item2567257380#ht_1515wt_1139
0
точно не скажу, но BSL это не айс. Нужен JTAG чтобы была возможность отлаживать программу в железе. дешевые программаторы делает Olimex, сам я разорился на MSP-FET430UIF www.ti.com/tool/msp-fet430uif за 99$. (Зато пересылка бесплатная FedEx)
0
Ага, спс. На первых парАх думаю и без JTAG обойдусь.
Вопрос остаётся в силе.
0
осталось сделать универсальные функции записи/чтения 8- и 16-битного блока с возможностью использования программного/аппаратного I2C
0
вот код I2C:

#include «io430.h»
#include «i2c-soft.h»

volatile unsigned int i;
volatile int16_t res;
volatile uint8_t t1,t2;

#define ACCESS_MEM 0x17
#define ACCESS_CONF 0xAC
#define READ_TEMP 0xAA
#define START_CONVERT 0xEE
#define STOP_CONVERT 0x22
#define READ 0x01
#define WRITE 0x00

unsigned int DS1624ReadTemperature(void)
{
volatile unsigned int temp, ack;
i2c_Init();
i2c_Start();
ack=i2c_Write(0x90); // W=0,R=1 b1001000W
ack=i2c_Write(START_CONVERT);
while(1)
{
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(ACCESS_CONF);
i2c_Start();
ack=i2c_Write(0x90);
if (i2c_Read(0) & 0x80)
break;
}
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(READ_TEMP);
i2c_Start();
ack=i2c_Write(0x91);//read
temp = (unsigned int)i2c_Read(1);//1st byte
// temp <<= 8;
// temp |= (unsigned int)i2c_Read(1);//2nd byte. дает точность 0.3С после запятой. Ненадо
if (temp>125)//если t меньше 0
{
temp = 255-temp;
}
i2c_Stop();
return temp;

}
не могу откомпилировать выдает ошибку :«Error[e46]: Undefined external „main“ referred in ?cstart ( E:\Program Files\IAR Systems\Embedded Workbench 6.0\430\LIB\DLIB\dl430fn.r43 )», пользуюсь IAR в .h все поменял на свое. что делать?
0
У тебя нету точки входа, т.е. функции main(). Либо файл с ней не включен в проект.
0
куда main вставить? я просто не знаю, как его включить? можно ли все это затолкать в внутрь main?
0
Для начала изучи язык С.
0
не могли бы привести полный код, для изучения блин и так все тяжко.
0
Я не думаю, что с такими вопросами полный код тебе поможет. Кроме того, у меня его банально нет, а писать специально новый — лень.
0
ну ладно, в двух словах если в main в ставить бесконечный цикл чтения из переменной temp? так можно сделать?
0
я же написал что проект в CSS. А ты в ИАРе его компилировать пытаешься. Полный код приложен во вложении. Там и main есть.
0
Вот открыл файл main.c:
/*
* ======== Standard MSP430 includes ========
*/
#include <msp430.h>

/*
* ======== Grace related includes ========
*/
#include <ti/mcu/msp430/csl/CSL.h>
#include «i2c-soft.h»

volatile unsigned int i;
volatile int16_t res;
volatile uint8_t t1,t2;

#define ACCESS_MEM 0x17
#define ACCESS_CONF 0xAC
#define READ_TEMP 0xAA
#define START_CONVERT 0xEE
#define STOP_CONVERT 0x22
#define READ 0x01
#define WRITE 0x00

/*
* ======== main ========
*/

unsigned int DS1624ReadTemperature(void)
{
volatile unsigned int temp, ack;
i2c_Init();
i2c_Start();
ack=i2c_Write(0x90); // W=0,R=1 b1001000W
ack=i2c_Write(START_CONVERT);
while(1)
{
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(ACCESS_CONF);
i2c_Start();
ack=i2c_Write(0x90);
if (i2c_Read(0) & 0x80)
break;
}
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(READ_TEMP);
i2c_Start();
ack=i2c_Write(0x91);//read
temp = (unsigned int)i2c_Read(1);//1st byte
// temp <<= 8;
// temp |= (unsigned int)i2c_Read(1);//2nd byte. дает точность 0.3С после запятой.
if (temp>125)//если t меньше 0
{
temp = 255-temp;
}
i2c_Stop();
return temp;
}

int main(int argc, char *argv[])
{
CSL_init(); // Activate Grace-generated configuration
P1OUT=BIT6;//зажгем диод
while(1)
{
P1OUT ^= BIT0 + BIT6; // Toggle P1.0 using exclusive-OR
res=DS1624ReadTemperature();
for (i = 0xFFF; i > 0; i--)
{
_nop();
}
}
}
а что это за библиотека "#include <ti/mcu/msp430/csl/CSL.h>" ?, тут main за комментирован
/*
* ======== main ========
*/
или все что идет в низу и есть main?
0
юноша, срочно учите матчасть!
+1
Он уже знает про комментарии!!! :)
Осталось чуток почитать...
0
Спасибо, читаю ном есть не ясности)а что это за библиотека все таки #include <ti/mcu/msp430/csl/CSL.h?
в тут значение температуры записываться в volatile unsigned int temp, вот а потом куда это значение идет? Функции i2c_Start(),i2c_Init(),i2c_Stop() вызываются с файла i2c-soft.c? Потом тут еще есть два бесконечных цикла while(1)
{
i2c_Start(); // вызываем i2c_Start() да?
ack=i2c_Write(0x90); // Записываем в константу ack значение 0x90 (Запись)?
ack=i2c_Write(ACCESS_CONF); // записываем в ack (0xAC) готовим запись в slave?
i2c_Start(); // вызываем Старт отправки да?
ack=i2c_Write(0x90); // опять заносим в ack 0x90
if (i2c_Read(0) & 0x80) // а это что какое то условие непонятно (((( что это?
break;
}
Парни хочу разобраться с этим, нужна ваша помощь, вот спасибо.
0
Мне надо читать значение температуры и отправлять ее в ком порт компьютера. вот.
0
CSL.h делает утилита визуальной настройки периферии Grace
0
А как увеличить частоту по I2C, а то у меня она не велика. осцилом гляжу там 1кГц гдето.
0
снизь количество пустых циклов в i2c_soft.c
0
Вот попробовал написать, Чтение температуры по I2C с DS1621.

#include «io430.h»

#include «J:\MSP430\I2C\i2c-soft.h»
#include «J:\MSP430\I2C\i2c-soft.c»

#define ACCESS_MEM 0x17
#define ACCESS_CONF 0xAC
#define READ_TEMP 0xAA
#define START_CONVERT 0xEE
#define STOP_CONVERT 0x22
#define READ 0x01
#define WRITE 0x00

volatile int temp, ack;

int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
i2c_Init(); // инициализация
i2c_Start(); // Старт
ack=i2c_Write(0x90);// Команда записи SLAVE адрес
ack=i2c_Write (READ_TEMP);// Команда записи чтения Температуры AAh
i2c_Start();// Опять Старт
ack=i2c_Write (0x91);// Команда Записи R =1 W=0
while(1)
{
temp = (unsigned int) i2c_Read(1); // Бесконечный цикл записи температуры в переменную temp
}

}

Можно так сделать? у меня MSP430G2231
0
Наверно так лучше
#include «io430.h»

#include «J:\MSP430\I2C\i2c-soft.h»
#include «J:\MSP430\I2C\i2c-soft.c»

#define ACCESS_MEM 0x17
#define ACCESS_CONF 0xAC
#define READ_TEMP 0xAA
#define START_CONVERT 0xEE
#define STOP_CONVERT 0x22
#define READ 0x01
#define WRITE 0x00

volatile int temp, ack;

int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
while(1)
{
i2c_Init();
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write (READ_TEMP);
i2c_Start();
ack=i2c_Write (0x91);
temp = (unsigned int) i2c_Read(1);
i2c_Stop();
}
}
0
Как выдать в порт P1.0, P1.1, P1.2, P1.3
Значений temp, то есть если температура 1100, то P1.0 чтобы вывести 1, в P1.1 = 1, P1.2 = 0, P1.3 =0. То есть как вывести информацию параллельно в порт P1.
0
ПАРНИ УРАААА ВСЕ ЗАРАБОТАЛО) ВОТ КОД С ВЫВОДОМ ТЕМПЕРАТУРЫ В ПОРТ МК430G2231.
#include «io430.h»

#include «J:\MSP430\I2C\i2c-soft.h»
#include «J:\MSP430\I2C\i2c-soft.c»

#define ACCESS_MEM 0x17
#define ACCESS_CONF 0xAC
#define READ_TEMP 0xAA
#define START_CONVERT 0xEE
#define STOP_CONVERT 0x22
#define READ 0x01
#define WRITE 0x00

volatile unsigned int temp, ack;

int main( void )
{
P1DIR |=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5;
WDTCTL = WDTPW + WDTHOLD;
while(1)
{
i2c_Init();

i2c_Start();
ack=i2c_Write(0x90); // W=0,R=1 b1001000W
ack=i2c_Write(START_CONVERT);
while(1)
{
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(ACCESS_CONF);
i2c_Start();
ack=i2c_Write(0x90);
if (i2c_Read(0) & 0x80)
break;
}
i2c_Start();
ack=i2c_Write(0x90);
ack=i2c_Write(READ_TEMP);
i2c_Start();
ack=i2c_Write(0x91);//read
temp = (unsigned int)i2c_Read(1);//1st byte
if (temp>125)
{
temp = 255-temp;
}
P1OUT = temp;
i2c_Stop();
}
}
0
#include «J:\MSP430\I2C\i2c-soft.h»
#include «J:\MSP430\I2C\i2c-soft.c»
За абсолютные пути к инклюдам руки надо отрывать сразу.
i2c_stop() я ы размести сразу после последнего read.
Ну и для кода есть специальный тег — <code>, позволяющий сохранить форматирование.
0
я ы размести
Черт. «я бы разместил».
0
НЕ судите строго, я только учусь, вот. Спсибо за наставления все запомню и буду исправляться.
0
Бля, нахер постить куски кода в коментах топика? Неужели так сложно начать изучать язык с начала, а не выносить мозг=) Ведь здесь самые азы «Умными» вопросами в землю втаптываются! Ну как говорить с пятиклассником о тригонометрии просто… Чессна слово. Может я и зануда, ноя считаю так нельзя.
А если я начну хирурга так спрашивать!
ЗЫ
Кто был за снижение порога вхождения.
ЗЫЗЫ
Просто накипело…
0
Кто был за снижение порога вхождения.
Вот он порог и не осилил, потому и задает вопросы) Вопрос-то как раз по тому самому С, который не отличается низким порогом вхождения.
0
Да ладно, уж в самых примитивных программах и книгах про main уж точно толдычат на каждом шагу, а уж про то, как вывести полуслово или слово или два бита на пины порта это уж точно перебор. Ну нельзя же начинать читать книгу с середины, а то и с конца…
0
Вот видишь. Он даже это не осилил. Чего уж тут ожидать.
Да и пофиг тащемта. Надо будет — осилит. Не надо… На дурацкие вопросы редко отвечают по существу — неинтересно.
0
Какая частота проца и скорость I2C?
0
  • avatar
  • Amigo
  • 09 октября 2013, 10:41
Спасибо за статью.
А мне пришли недавеча образцы от TI — «TMP112», буду на MSP430G2553 заводить это дело )
0
если не секрет, какими путями пришли? а то есть информация, что федекс прекратил доставку в Россию.
0
похоже на ложь, так как посылка FedEx пришла три дня назад )
Заказывал обычно, на рабочую почту и адрес
0
Это возможно по экономическим соображениям, ибо в РФ разрабатывается электроники (по сравнению с Китаем или Тайванем) — ну просто капля в океане
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.