arxeiss

APPS - I2C

Oct 14th, 2013
775
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.53 KB | None | 0 0
  1. // ***********************************************************************
  2. //
  3. // Demo program pro vyuku predmetu APPS (09/2012)
  4. // Petr Olivka, katedra informatiky, FEI, VSB-TU Ostrava
  5. //
  6. // Priklad pouzit vyvojoveho nastroje AVR-KIT:
  7. // ovladani sbernice I2C
  8. //
  9. // ***********************************************************************
  10.  
  11.  
  12. int main()
  13. {
  14.   // inicializace prostredi
  15.   avrkit_init();
  16.  
  17.   printf( "AVR-KIT ready...\n\n" );
  18.  
  19.   // uvedeni sbernice do klidoveho stavu
  20.   I2C_Init();
  21.  
  22.   // zacatek komunikace
  23.      
  24.     char adress = 0b10110000 | 0b1110;
  25.      
  26.     //nastvení kontinuálního měření
  27.     I2C_Start();
  28.     char ACK = !I2C_Vystup( adress | 0 );
  29.     if (!ACK)
  30.         return 0;
  31.      
  32.     ACK = !I2C_Vystup(0xAC);
  33.     if (!ACK)
  34.         return 0;
  35.          
  36.     ACK = !I2C_Vystup(0);
  37.     if (!ACK)
  38.         return 0;  
  39.     I2C_Stop();
  40.      
  41.     //Nastavení horní meze termostatu
  42.     I2C_Start();
  43.     ACK = !I2C_Vystup( adress | 0 );
  44.     if (!ACK)
  45.         return 0;
  46.      
  47.     ACK = !I2C_Vystup(0xA1);
  48.     if (!ACK)
  49.         return 0;
  50.      
  51.     ACK = !I2C_Vystup(25);
  52.     if (!ACK)
  53.         return 0;
  54.          
  55.     ACK = !I2C_Vystup(128); //25,5°C
  56.     if (!ACK)
  57.         return 0;
  58.     I2C_Stop();
  59.      
  60.     //Nastavení spodní meze termostatu
  61.     I2C_Start();
  62.     ACK = !I2C_Vystup( adress | 0 );
  63.     if (!ACK)
  64.         return 0;
  65.          
  66.     ACK = !I2C_Vystup(0xA2);
  67.     if (!ACK)
  68.         return 0;
  69.      
  70.     ACK = !I2C_Vystup(27);
  71.     if (!ACK)
  72.         return 0;
  73.      
  74.     ACK = !I2C_Vystup(0); //27°C
  75.     if (!ACK)
  76.         return 0;
  77.     I2C_Stop();
  78.      
  79.      
  80.     //nastartování měření teploty
  81.     I2C_Start();    
  82.     ACK = !I2C_Vystup( adress | 0 );
  83.     if (!ACK)
  84.         return 0;
  85.      
  86.     ACK = !I2C_Vystup(0xEE);
  87.     if (!ACK)
  88.         return 0;
  89.     I2C_Stop();
  90.      
  91.     //čtneí teploty
  92.     while(1){
  93.         I2C_Start();
  94.         ACK = !I2C_Vystup( adress | 0 );
  95.         if (!ACK)
  96.             return 0;
  97.      
  98.         ACK = !I2C_Vystup( 0xAA );
  99.         if (!ACK)
  100.             return 0;
  101.      
  102.         I2C_Start();
  103.         ACK = !I2C_Vystup( adress | 1 );
  104.         if (!ACK)
  105.             return 0;
  106.      
  107.         char receive = I2C_Vstup();
  108.         I2C_Ack();
  109.          
  110.         char receiveHalf = I2C_Vstup();
  111.         I2C_NAck();
  112.          
  113.         printf("%d,%d\n\n",receive,(receiveHalf > 0 ) ? 5 : 0 );        
  114.         I2C_Stop();
  115.          
  116.         delay_ms(500);
  117.     }
  118.  
  119. }
  120.  
  121. void puvodni_obsah_mainu() {
  122. //zápis čísla na expandér což se zobrazí na LEDkách a následné přečtení
  123.   if(ACK){
  124.      char run = 1;
  125.      while(run != 0){
  126.          if(I2C_Vystup(run))
  127.             break;
  128.          run <<= 1;
  129.          delay_ms(10);
  130.      }
  131.      ACK = !I2C_Vystup(67);
  132.   }
  133.   if (!ACK)
  134.       return 0;
  135.        
  136.   I2C_Start();
  137.   ACK = !I2C_Vystup( 0b01000000 | 0b0000 | 0b1);
  138.   if(ACK){
  139.      char receive = I2C_Vstup();
  140.      I2C_Ack();
  141.      printf("%d",receive);
  142.   }
  143.  }
  144.  
  145. //************************************************************************
  146. //************************************************************************
  147. // sbernice I2C (low level) - ovladani signalu SDA a SCL
  148.  
  149. void I2C_delay() { delay_ms( 1 ); }
  150.  
  151. // nastaveni signalu SDA
  152. void I2C_SDA( char value )
  153. {
  154.   if ( value ) I2C_PORT |= ( 1 << SDA_PIN );
  155.   else         I2C_PORT &= ~( 1 << SDA_PIN );
  156.   I2C_delay();
  157. }
  158.  
  159. // cteni signalu SDA
  160. char I2C_getSDA( void )
  161. {
  162.   char r = ( I2C_PIN & ( 1 << SDA_PIN ) ) != 0;
  163.   I2C_delay();
  164.   return r;
  165. }
  166.  
  167. // nastaveni signalu SCL
  168. void I2C_SCL( char value )
  169. {
  170.   if ( value ) I2C_PORT |= ( 1 << SCL_PIN );
  171.   else         I2C_PORT &= ~( 1 << SCL_PIN );
  172.   I2C_delay();
  173. }
  174.  
  175. //************************************************************************
  176. // Principy komunikace na sbernici I2C jsou popsany v technickych listech
  177. // u kazdeho zarizeni pro toto rozhrani.
  178.  
  179. // inicializace sbernice
  180. void I2C_Init()
  181. {
  182.   I2C_DDR |= ( 1 << SDA_PIN ) | ( 1 << SCL_PIN );
  183.   I2C_SCL( 1 );
  184.   I2C_SDA( 1 );
  185. }
  186.  
  187. // oznameni zacatku komunikace
  188. void I2C_Start()
  189. {
  190.   I2C_SDA( 1 );
  191.   I2C_SCL( 1 );
  192.   I2C_SDA( 0 );
  193.   I2C_SCL( 0 );
  194. }
  195.  
  196. // oznameni ukonceni komunikace
  197. void I2C_Stop()
  198. {
  199.   I2C_SCL( 0 );
  200.   I2C_SDA( 0 );
  201.   I2C_SCL( 1 );
  202.   I2C_SDA( 1 );
  203. }
  204.  
  205. // odeslani potvrzovaci bitu ACK
  206. void I2C_Ack()
  207. {
  208.   I2C_SCL( 0 );
  209.   I2C_SDA( 0 );
  210.   I2C_SCL( 1 );
  211.   I2C_SCL( 0 );
  212. }
  213.  
  214. // odeslani potvrzovaciho bitu NACK
  215. void I2C_NAck()
  216. {
  217.   I2C_SCL( 0 );
  218.   I2C_SDA( 1 );
  219.   I2C_SCL( 1 );
  220.   I2C_SCL( 0 );
  221. }
  222.  
  223. char I2C_getACK()
  224. {
  225.   I2C_SDA( 1 );
  226.   // nastavit SDA_PIN jako vstupni
  227.   I2C_DDR &= ~( 1 << SDA_PIN );
  228.   I2C_SCL( 1 );
  229.  
  230.   char ret = I2C_getSDA();
  231.   I2C_SCL( 0 );
  232.   I2C_DDR |= ( 1 << SDA_PIN );
  233.   return ret;
  234. }
  235.  
  236. // odeslani 8 bitove hodnoty
  237. char I2C_Vystup( unsigned char value )
  238. {
  239.   char mask = 0x80;
  240.   // odeslani bitu, MSB jako prvni
  241.   for ( int i = 0; i < 8; i++ )
  242.   {
  243.       I2C_SDA( value & mask );
  244.       mask >>= 1;
  245.       I2C_SCL( 1 );
  246.       I2C_SCL( 0 );
  247.   }
  248.   return I2C_getACK();
  249. }
  250.  
  251. // precteni 8 bitove hodnoty
  252. unsigned char I2C_Vstup()
  253. {
  254.   unsigned char value = 0;
  255.   // klidovy stav na lince
  256.   I2C_SDA( 1 );
  257.    
  258.   // nastavit SDA_PIN jako vstupni
  259.   I2C_DDR &= ~( 1 << SDA_PIN );
  260.  
  261.   // prijem bitu, MSB jako prvni
  262.   for ( int i = 0; i < 8; i++ )
  263.   {
  264.       value <<= 1;
  265.       I2C_SCL( 1 );
  266.       if ( I2C_getSDA() ) value |= 1;
  267.       I2C_SCL( 0 );
  268.   }
  269.    
  270.   // nastavit SDA_PIN zpet jako vystupni
  271.   I2C_DDR |= ( 1 << SDA_PIN );  
  272.   return value;
  273. }
Advertisement
Add Comment
Please, Sign In to add comment