Отговори на тема  [ 8 мнения ] 
Сензор за температура 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Яну 03, 2013 11:53 am
Мнения: 17
Мнение Сензор за температура
Имам проблем с инициализирането на температурен сензор tcn75 и pic16f886 използвайки i2c. Някой може ли да ми даде примерен код или начин за инициализацията. Благодаря предварително.


Чет Яну 03, 2013 12:00 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Май 29, 2007 2:23 pm
Мнения: 3714
Местоположение: Високо в планината
Мнение Re: Сензор за температура
Преди около 1,5 год. имах някакви проблеми с него. Потърси из форума.

_________________
Хайде де!


Чет Яну 03, 2013 12:40 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение Re: Сензор за температура
tcn75 или tcn75a?

Ако ще четеш темепратура : за версията без а (стария модел) - няма нужда от инициализация - директно четеш адрес 0 два байта. Дава 9 битов резултат (като във втория байт, старшия бит май беше най-младшия бит от резултата.) За версията с а (новия модел) е същото за 9 битов резултат - няма нужда от инициализация с цел обратна съвместимост. За 12 бита вече се пишеше в някакъв регистър - което вече е един вид инициализация. Нито при четене нито при писане има някакви особенности, стига да се спазват описаните в даташита спецификации за четене/писане, които до колкото си спомням са си съвсем стандартно i2c.

Което според мен ще рече, че нещо не правиш правилно с i2c-то.


Чет Яну 03, 2013 3:48 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Яну 03, 2013 11:53 am
Мнения: 17
Мнение Re: Сензор за температура
Сензорът е tcn75a.
Все още не съм го пуснал, защото в момента пиша кода. Имам затруднение при комуникацията с чипа, защото немога да разбера как да я направя.


Чет Яну 03, 2013 3:58 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение Re: Сензор за температура
Е та на кво го пишеш тоя код?

Тоя пик има хардуерен i2c - малко е крив, ама работи.

Реално погледнато нямаш проблем с комуникацията с чипа, а просто не знаеш как да подкараш i2c шината.


Чет Яну 03, 2013 4:13 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Яну 03, 2013 11:53 am
Мнения: 17
Мнение Re: Сензор за температура
void I2CInit(void)
{
TRISC3 = 1;
TRISC4 = 1;
SSPSTAT |= 0x80;
SSPCON = 0x28;
SSPADD = 0x28;
}

void I2CStart()
{
SEN = 1;
while(SEN);

}


void I2CStop()
{
PEN = 1;
while(PEN);
}


void I2CRestart()
{
RSEN = 1;
while(RSEN);
}


void I2CAck()
{
ACKDT = 0;
ACKEN = 1;
while(ACKEN);
}


void I2CNak()
{
ACKDT = 1;
ACKEN = 1;
while(ACKEN);
}
void I2CWait()
{
while ( ( SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );

}
void I2CSend(unsigned char dat)
{
SSPBUF = dat;
while(BF);
I2CWait();
}
unsigned char I2CRead(void)
{
unsigned char temp;

RCEN = 1;
while(!BF);
temp = SSPBUF;
I2CWait();
return temp;
}

Toва ми е кода за i2c. Проблема, е че не знам как да стане тази комуникация и как да я напиша.


Чет Яну 03, 2013 6:08 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение Re: Сензор за температура
Пиша по спомен, та ако някой види грешка да свирка.

последователността е следната:

1.старт
2.изпращане на адрес(хардуерен + write/read в зависимост това дали ще четеш директно или първо ще подадеш адрес на клетката за четене)
3.чакаш ack
4.1. ако ще четеш директно си четеш
4.1.1. ако ще четеш още подаваш ack и пак четеш
4.1.2. ако няма да четеш, даваш noack и/или stop
4.2. ако първо ще подадеш адрес :
4.2.1. подаваш адреса (трябва в точка 2 бита да ти е за писане)
4.2.2. REstart!!!
4.2.3. изпращаш ПАК хардуерния адрес с бит за чете
4.2.4. чакаш ack
4.2.5. четеш
4.2.6. ако пак ще четеш : пращаш ack и четеш (колкото байта искаш да прочетеш
4.2.7. noack и/или stop

Това го има описано навсякъде из нетя.

В конкретния случай имаш
i2cstart
i2csend(адреса с бит0 = 1)
--- тука трябва да си сложиш проверка за ack от дивайса и евентуално да го изчакаш мъничко
i2cread(старши байт)
i2cack
i2cread(младши байт)
i2cnak или директно i2cstop

Намери си начин за излизане от тия функции дори и да не се изпълни условието за излизане - всичко става - така написано принципно има вероятност програмата там да увисне и да чака до "видов ден" бита да стане 0...


Пет Яну 04, 2013 10:42 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Яну 03, 2013 11:53 am
Мнения: 17
Мнение Re: Сензор за температура
Наложи се да си сменя чипа от pic16f886 на pic16f913, сложих му готов код i2c от примерите на hi-tech. Проблема ми, е че при компилиране на иницилазацията на tcn75 ми дава грешка и другият ми проблем е как да изпратя информацията от контролера към LCD.
кода за tcn 75

Код:
#include <htc.h>
#ifndef _XTAL_FREQ
   #define _XTAL_FREQ 8000000
#endif
#include "tcn.h"
#include "i2c.h"
#define data1
#define data2
#define data3
#define   my_string
void TCN75a_init()
   {   
      i2c_Stop();
      i2c_Restart();
      i2c_WriteTo(0x48);   /* zapis v u-vo 1001000 */
      signed char i2c_ReadAcknowledge();
      i2c_PutByte(0x00);   /* izprashtane na data 0x00 */
      signed char i2c_ReadAcknowledge();
      i2c_ReadFrom(0x48);         /* chetene ot 1001000 */
      data1 = i2c_GetByte(I2C_MORE);   /* read one byte */
      data2 = i2c_GetByte(I2C_MORE);   /* read another */
      i2c_GetString(my_string, 7);   /* read 7 bytes */
      i2c_ReadFrom(0x48);
      data3 = i2c_GetByte(I2C_LAST);   /* last byte read */
/* check for errors */
      if(i2c_PutByte(0xff))
    my_error_routine();   /* bus error or ~ack */
   }


код за i2c

#include   <htc.h>
#include    "i2c.h"


void i2c_Stop(void)
   {
   

   SDA_LOW();               /* natroivam data da e nisko */
   SCL_HIGH();
   
   __delay_us(I2C_TM_DATA_SU);
   SCL_DIR = I2C_INPUT;      
   __delay_us(I2C_TM_STOP_SU);
   SDA_HIGH();               /* prehod ot nisko vuv visoko sustoianie */
   __delay_us(I2C_TM_BUS_FREE);   /* vreme za koeto bus pistata e svobodna predi sledvashtia start */
   SDA_DIR = I2C_INPUT;   

   return;
   }

/*
*    Izprashtane naa restart/start 
*/

void i2c_Restart(void)
   {
   SCL_LOW();               /* Clock nisko sustoianie */
   SDA_HIGH();               /* Clock visoko sustoianie */

   __delay_us(I2C_TM_DATA_SU);

   SCL_DIR = I2C_INPUT;      
   __delay_us(I2C_TM_SCL_HIGH);

   SDA_LOW();            
   __delay_us(I2C_TM_START_HD);
   return;
   }

/*
*    Izprashtane na byte kum slave   
*/

unsigned char i2c_SendByte(unsigned char byte)
   {
   signed char i;

   for(i=7; i>=0; i--)
      {
      SCL_LOW();               
      

        SDA_DIR = ((byte>>i)&0x01);
           if ((byte>>i)&0x01)
                 {      
               SDA_HIGH();
                 }
                    else
                        {
                        SDA_LOW();
                        }
                           __delay_us(I2C_TM_DATA_SU);
                           SCL_DIR = I2C_INPUT;      
                     
                           if(i2c_WaitForSCL())   
                              return TRUE;         /* greshka na bus */
                     
                           __delay_us(I2C_TM_SCL_HIGH);
      }
   
   return FALSE;
   }

/*
*    Izprashtane na adress i data kum slave
*      - 7-bit address (lsb ignored)
*/
unsigned char  i2c_SendAddress(unsigned char address, unsigned char rw)
   {
   return i2c_SendByte(address | (rw?1:0));
   }

/*
*    Proverka za ackn
*      - vrushta ack or ~ack, or ERROR ako ima ghreshka na bus
*/
signed char i2c_ReadAcknowledge(void)
{
   unsigned char ack;

   SCL_LOW();                  /* clock low */
   SDA_DIR = I2C_INPUT;         /* zabranqva data - chaka ack */
   __delay_us(I2C_TM_SCL_TO_DATA);   
   SCL_DIR = I2C_INPUT;      
   __delay_us(I2C_TM_DATA_SU);
   ack = SDA;                  /* chete acknowledge */

   /* izchakva slave da pusne clock sled izprashtaneto na byte*/
   if(i2c_WaitForSCL())
      return I2C_ERROR;
   return ack;
}

/*
*    Chetene na byte ot slave
*/

int i2c_ReadByte(void)
{
   unsigned char i;
   unsigned char byte = 0;

   for(i=0; i<8; i++)
   {
      SCL_LOW();               
      __delay_us(I2C_TM_SCL_LOW);
      SDA_DIR = I2C_INPUT;      

      SCL_DIR = I2C_INPUT;      
      if(i2c_WaitForSCL())
         return I2C_ERROR;
      __delay_us(I2C_TM_SCL_HIGH);
      byte = byte << 1;      /* chetene na sledv bit */
      byte |= SDA;
   }
   return (int)byte;
}

/*
* Izprashane  (~)acknowledge na slave
*/

void i2c_SendAcknowledge(unsigned char status)
{
   SCL_LOW();
   if ( status & 0x01)
      {
      SDA_LOW();            
      }
         else
          {
      SDA_HIGH();
         }
            __delay_us(I2C_TM_DATA_SU);
            SCL_DIR = I2C_INPUT;      /* float clock high */
            __delay_us(I2C_TM_SCL_HIGH);
            return;
}

/*
*    Izprashta byte kum slave i razreshava transfera
*/

signed char i2c_PutByte(unsigned char data)
{
   if(i2c_SendByte(data))
      return I2C_ERROR;
   return i2c_ReadAcknowledge();   
}
   

/*
* Vzima byrtet ot slave i razreshava transfera
*/
int i2c_GetByte(unsigned char more)
{
   int byte;

   if((byte = i2c_ReadByte()) == I2C_ERROR)
      return I2C_ERROR;

   i2c_SendAcknowledge(more);

   return byte;
}

int i2c_PutString(const unsigned char *str, unsigned char length)
{
   signed char error;

   while(length)
   {
      if((error = i2c_PutByte(*str)) == I2C_ERROR)
         return -(int)length;               /* bus error */
      else
         if(error)
            return (int)length;               /* non acknowledge */
      str++;
      length--;
   }

   return FALSE;                           /* everything OK */
}

/*
*    chete kolko byte sa ot slave, zapazva gi v str i razreshava transfera
*/

unsigned char i2c_GetString(unsigned char *str, unsigned char number)
{
   int byte;

   while(number)
   {
      if((byte = i2c_GetByte(number-1)) == I2C_ERROR)
         return number;                        /* bus error */
      else
         *str = (unsigned char)byte;
      str++;
      number--;
   }

   return FALSE;                              /* everything OK */
}

/*
*    Otvaria komunikaciq s u-to na adresa. Izbira se r/w
*/

unsigned char i2c_Open(unsigned char address, unsigned char mode)
{
   i2c_Start();
   i2c_SendAddress(address, mode);
   if(i2c_ReadAcknowledge())
      return TRUE;

   return FALSE;
}



unsigned char i2c_WaitForSCL(void)
{
   /* SCL_DIR should be input here */
   if(!SCL)
   {
      __delay_us(I2C_TM_SCL_TMO);
      /* if the clock is still low -> bus error */
      if(!SCL)
         return TRUE;
   }
   return FALSE;
}

void i2c_Free()
{
   unsigned char ucI;

   SDA_DIR=I2C_INPUT;
   for(ucI=0;ucI!=9;ucI++)
   {
      SCL_HIGH();
      __delay_us(5);
      SCL_LOW();
      __delay_us(5);
   }
}

unsigned char i2c_read(unsigned char ucAdr)
{
   unsigned char ucDat;

   if (i2c_ReadFrom(ucAdr)==0)
   {
      ucDat=i2c_GetByte(I2C_MORE);
      i2c_Stop();

   }

   return(ucDat);
}


Хора, ползвайте [Code] бутона горе


Нед Яну 20, 2013 12:53 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 8 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни