<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=4&amp;t=13959&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-12-28T14:02:45+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=13959&amp;mode</id>
<entry>
<author><name><![CDATA[Arek1111111111]]></name></author>
<updated>2015-12-28T14:02:45+01:00</updated>
<published>2015-12-28T14:02:45+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=149018#p149018</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=149018#p149018"/>
<title type="html"><![CDATA[Re: USI jako Slave TWI]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=149018#p149018"><![CDATA[
Już działa wysyłanie i odbieranie pojedyńczych bajtów. Jednak nie mam pojęcia jak wysyłać kilka różnych bajtów lub jak wstawić opóźnienie do pętli głównej.<br />[syntax=c]uint8_t spi_byte(uint8_t dane)<br />{<br /><br />if(CS_DOWN)<br />{<br />uint8_t i=8;<br />if(dane &amp; 0x80) DO_OFF;<br />else DO_ON;<br />dane|=(DI_DOWN)?0:1;   //sprawdz warunek, jesli prawdziwy przyjmij 1 jezeli nie przyjmij 0<br />do<br />{<br />if(GIFR &amp; (1&lt;&lt;INTF0))<br />{<br />if(CS_DOWN)<br />{<br />GIFR =(1&lt;&lt;INTF0);<br />dane&lt;&lt;=1;<br />i--;<br />if(dane &amp; 0x80) DO_OFF;<br />else DO_ON;<br />dane|=(DI_DOWN)?0:1;   //sprawdz warunek, jesli prawdziwy przyjmij 1 jezeli nie przyjmij 0<br />}<br />}<br />}while(i);<br />}return dane;<br />}[/syntax]<br /><br />Domyślam się że należy sprawdzać stan linii CS jednak mimo to gdy w pętli głównej dam opóźnianie 10ms to dostaje 0.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3349">Arek1111111111</a> — 28 gru 2015, o 14:02</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Arek1111111111]]></name></author>
<updated>2015-12-27T22:48:56+01:00</updated>
<published>2015-12-27T22:48:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148986#p148986</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148986#p148986"/>
<title type="html"><![CDATA[Re: USI jako Slave TWI]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148986#p148986"><![CDATA[
Koledzy pomóżcie. Próbuje wysyłać dane po SPI programowo w trybie SLAVE. SCK od mastera podłączyłęm do wejścia INT0 w medze32. w pętli głównej chcę wysyłać jakąś liczbę a master ma ją odczytać i wyświetlić na LCD. Z tego co nabazgrałem wyświetla albo tylko 0 albo tylko 255. <br />Tak wygląda funkcja wysyłająca zmienną po spi w pętli głównej:<br /><br />[syntax=c]dane=127;<br />    i=8;<br />    do<br />    {<br />    if(GIFR &amp; (1&lt;&lt;INTF0))<br />    {<br />    GIFR =(1&lt;&lt;INTF0);<br />    if(dane&amp;0x80)<br />DO_ON;<br />else<br />DO_OFF;<br />dane=dane&lt;&lt;1;<br />    }<br />}while(--i);[/syntax]<br /><br />Sygnał SCK odczytuje sprawdzając flagę przerwania i to działa. Połączenia są na 100% pewne, może ma ktoś jakieś sugestie w czym leży problem?<br /><br /><br />Po przerobieniu kodu otrzymuje komunikacje i przy wartości 0,1,255 jest ok, ale przy innych wartościach dostaje połowę wartości czyli np wysyłam 128 otrzymuje 64 itp.<br />Sygnał SCK sprawdzam zboczem narastającym, może w tym jest problem?<br /><br />[syntax=c]dane=128;<br />    i=8;<br /><br />    do<br />    {<br />    if(GIFR &amp; (1&lt;&lt;INTF0))<br />{<br />GIFR =(1&lt;&lt;INTF0);<br /><br />i--;<br />if(dane &amp; 0x80) DO_OFF;<br />else DO_ON;<br />dane&lt;&lt;=1;<br />}<br />    }while(i);[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3349">Arek1111111111</a> — 27 gru 2015, o 22:48</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Arek1111111111]]></name></author>
<updated>2015-12-23T22:21:21+01:00</updated>
<published>2015-12-23T22:21:21+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148785#p148785</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148785#p148785"/>
<title type="html"><![CDATA[Re: USI jako Slave TWI]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148785#p148785"><![CDATA[
Witam, po nie udanych próbach postanowiłem zmienić komunikacje na SPI bo wydaje mi się prostsza.  Napisałem prostą funkcjie transpisji SPI w trybie MASTER korzystająć z USI w attiny2313 która działa. Czy ktoś mógłby mnie naprowadzić jak zmienić bity w rejestrach aby USI pracował w trybie SLAVE a nie MASTER?<br /><br />kod mastera:<br />[syntax=c]void spi_init()<br />{<br />  DDR_SPI &amp;= ~(1 &lt;&lt; USI_DI)|(1 &lt;&lt; USI_SCK)|(1 &lt;&lt; USI_CS);<br />  PORT_SPI |= 1 &lt;&lt; USI_DO;<br />  PORTB|= 1 &lt;&lt; USI_CS;<br />  // Define the following pins as output<br /> // DDR_SPI |= ((1 &lt;&lt; USI_DI)|(1 &lt;&lt; USI_SCK));<br />}<br /><br /><br />uint8_t spi_readWrite(uint8_t data)<br />{<br /><br />  USIDR = data;<br />  USISR |= 1 &lt;&lt; USIOIF;<br /><br />  while ((USISR &amp; (1 &lt;&lt; USIOIF)) == 0 ) {<br /> USICR = (1 &lt;&lt; USIWM0)|(1 &lt;&lt; USICS1)|(1 &lt;&lt; USICLK)|(1 &lt;&lt; USITC);//tryb SPI, tryb sck , wyjscie na sck<br />  }<br />  return USIDR;<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3349">Arek1111111111</a> — 23 gru 2015, o 22:21</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Arek1111111111]]></name></author>
<updated>2015-12-21T22:17:52+01:00</updated>
<published>2015-12-21T22:17:52+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148666#p148666</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148666#p148666"/>
<title type="html"><![CDATA[USI jako Slave TWI]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13959&amp;p=148666#p148666"><![CDATA[
Witam wszystkich forumowiczów. Nie mogę poradzić sobie z komunikacją TWI między mega32 a attiny2313. w medze sprzetowy TWI i biblioteka z BB a w attinym USI. Chciałem użyć gotowej biblioteki do slave jednak nie potrafię tego uruchomić. Bardzo Proszę o pomoc.<br />Testuje to na płytkach testowych. Master z mega32 na płytce ATB a Slave z attiny2313 na AVT3500. Podłączenia to +5V, GND, C0 atmegi z B7 attiny, C1 atmegi z B5 attiny. Zasilanie z programatora 5V.<br />Slave wysyła w pętli co 3ms bajt o stałej wartości i master powinien tą liczbę odebrać i wyświetlić na lcd jednak nic nie wyświetla.<br /><br />kod sleva attiny:<br />main.c:<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 18 gru 2015<br /> *      Author: Arkadiusz<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;TWI_SLAVE_USI/twi_slave_usi.h&quot;<br /><br /><br /><br />#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))<br />#define cbi(sfr, bit) (_SFR_BYTE(sfr) &amp;= ~_BV(bit))<br /><br />uint16_t value;<br />uint16_t analog;<br /><br />enum { DATA1, DATA2, RAW };<br /><br />int main(void)<br />{<br />  unsigned char slaveAddress;<br /><br />//  unsigned char slaveAddress, temp=0;<br />  sei();<br />cbi(DDRB, DDB5);        // pb1 set up as input<br /> cbi(DDRB, DDB7);        // pb3 set up as input<br />sbi(PORTB, PB5);// Set pb1 internal pullup<br />sbi(PORTB, PB7);// Set pb3 internal pullup<br />  slaveAddress = 0x25;// This can be change to your own address<br />  usiTwiSlaveInit(slaveAddress);<br /><br />  while(1)<br />  {<br /><br />     usiTwiSlaveInit(0x10);<br />     usiTwiTransmitByte(115);<br />      usiTwiDataInReceiveBuffer();<br />     usiTwiReceiveByte();<br /><br /> _delay_ms(3);<br />  }<br />}[/syntax]<br /><br /><br />TWI.c:<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &quot;twi_slave_usi.h&quot;<br /><br /><br /><br />/********************************************************************************<br /><br />                            device dependent defines<br /><br />********************************************************************************/<br /><br />#if defined( __AVR_ATtiny2313__ )<br />#  define DDR_USI             DDRB<br />#  define PORT_USI            PORTB<br />#  define PIN_USI             PINB<br />#  define PORT_USI_SDA        PB5<br />#  define PORT_USI_SCL        PB7<br />#  define PIN_USI_SDA         PINB5<br />#  define PIN_USI_SCL         PINB7<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_START_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect<br />#endif<br /><br />#if defined( __AVR_ATtiny25__ ) | \<br />     defined( __AVR_ATtiny45__ ) | \<br />     defined( __AVR_ATtiny85__ )<br />#  define DDR_USI             DDRB<br />#  define PORT_USI            PORTB<br />#  define PIN_USI             PINB<br />#  define PORT_USI_SDA        PB0<br />#  define PORT_USI_SCL        PB2<br />#  define PIN_USI_SDA         PINB0<br />#  define PIN_USI_SCL         PINB2<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_START_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVF_vect<br />#endif<br /><br />#if defined( __AVR_ATtiny26__ )<br />#  define DDR_USI             DDRB<br />#  define PORT_USI            PORTB<br />#  define PIN_USI             PINB<br />#  define PORT_USI_SDA        PB0<br />#  define PORT_USI_SCL        PB2<br />#  define PIN_USI_SDA         PINB0<br />#  define PIN_USI_SCL         PINB2<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_STRT_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVF_vect<br />#endif<br /><br />#if defined( __AVR_ATtiny261__ ) | \<br />     defined( __AVR_ATtiny461__ ) | \<br />     defined( __AVR_ATtiny861__ )<br />#  define DDR_USI             DDRB<br />#  define PORT_USI            PORTB<br />#  define PIN_USI             PINB<br />#  define PORT_USI_SDA        PB0<br />#  define PORT_USI_SCL        PB2<br />#  define PIN_USI_SDA         PINB0<br />#  define PIN_USI_SCL         PINB2<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_START_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVF_vect<br />#endif<br /><br />#if defined( __AVR_ATmega165__ ) | \<br />     defined( __AVR_ATmega325__ ) | \<br />     defined( __AVR_ATmega3250__ ) | \<br />     defined( __AVR_ATmega645__ ) | \<br />     defined( __AVR_ATmega6450__ ) | \<br />     defined( __AVR_ATmega329__ ) | \<br />     defined( __AVR_ATmega3290__ )<br />#  define DDR_USI             DDRE<br />#  define PORT_USI            PORTE<br />#  define PIN_USI             PINE<br />#  define PORT_USI_SDA        PE5<br />#  define PORT_USI_SCL        PE4<br />#  define PIN_USI_SDA         PINE5<br />#  define PIN_USI_SCL         PINE4<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_START_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect<br />#endif<br /><br />#if defined( __AVR_ATmega169__ )<br />#  define DDR_USI             DDRE<br />#  define PORT_USI            PORTE<br />#  define PIN_USI             PINE<br />#  define PORT_USI_SDA        PE5<br />#  define PORT_USI_SCL        PE4<br />#  define PIN_USI_SDA         PINE5<br />#  define PIN_USI_SCL         PINE4<br />#  define USI_START_COND_INT  USISIF<br />#  define USI_START_VECTOR    USI_START_vect<br />#  define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect<br />#endif<br /><br /><br /><br />/********************************************************************************<br /><br />                        functions implemented as macros<br /><br />********************************************************************************/<br /><br />#define SET_USI_TO_SEND_ACK( ) \<br />{ \<br />  /* prepare ACK */ \<br />  USIDR = 0; \<br />  /* set SDA as output */ \<br />  DDR_USI |= ( 1 &lt;&lt; PORT_USI_SDA ); \<br />  /* clear all interrupt flags, except Start Cond */ \<br />  USISR = \<br />       ( 0 &lt;&lt; USI_START_COND_INT ) | \<br />       ( 1 &lt;&lt; USIOIF ) | ( 1 &lt;&lt; USIPF ) | \<br />       ( 1 &lt;&lt; USIDC )| \<br />       /* set USI counter to shift 1 bit */ \<br />       ( 0x0E &lt;&lt; USICNT0 ); \<br />}<br /><br />#define SET_USI_TO_READ_ACK( ) \<br />{ \<br />  /* set SDA as input */ \<br />  DDR_USI &amp;= ~( 1 &lt;&lt; PORT_USI_SDA ); \<br />  /* prepare ACK */ \<br />  USIDR = 0; \<br />  /* clear all interrupt flags, except Start Cond */ \<br />  USISR = \<br />       ( 0 &lt;&lt; USI_START_COND_INT ) | \<br />       ( 1 &lt;&lt; USIOIF ) | \<br />       ( 1 &lt;&lt; USIPF ) | \<br />       ( 1 &lt;&lt; USIDC ) | \<br />       /* set USI counter to shift 1 bit */ \<br />       ( 0x0E &lt;&lt; USICNT0 ); \<br />}<br /><br />#define SET_USI_TO_TWI_START_CONDITION_MODE( ) \<br />{ \<br />  USICR = \<br />       /* enable Start Condition Interrupt, disable Overflow Interrupt */ \<br />       ( 1 &lt;&lt; USISIE ) | ( 0 &lt;&lt; USIOIE ) | \<br />       /* set USI in Two-wire mode, no USI Counter overflow hold */ \<br />       ( 1 &lt;&lt; USIWM1 ) | ( 0 &lt;&lt; USIWM0 ) | \<br />       /* Shift Register Clock Source = External, positive edge */ \<br />       /* 4-Bit Counter Source = external, both edges */ \<br />       ( 1 &lt;&lt; USICS1 ) | ( 0 &lt;&lt; USICS0 ) | ( 0 &lt;&lt; USICLK ) | \<br />       /* no toggle clock-port pin */ \<br />       ( 0 &lt;&lt; USITC ); \<br />  USISR = \<br />        /* clear all interrupt flags, except Start Cond */ \<br />        ( 0 &lt;&lt; USI_START_COND_INT ) | ( 1 &lt;&lt; USIOIF ) | ( 1 &lt;&lt; USIPF ) | \<br />        ( 1 &lt;&lt; USIDC ) | ( 0x0 &lt;&lt; USICNT0 ); \<br />}<br /><br />#define SET_USI_TO_SEND_DATA( ) \<br />{ \<br />  /* set SDA as output */ \<br />  DDR_USI |=  ( 1 &lt;&lt; PORT_USI_SDA ); \<br />  /* clear all interrupt flags, except Start Cond */ \<br />  USISR    =  \<br />       ( 0 &lt;&lt; USI_START_COND_INT ) | ( 1 &lt;&lt; USIOIF ) | ( 1 &lt;&lt; USIPF ) | \<br />       ( 1 &lt;&lt; USIDC) | \<br />       /* set USI to shift out 8 bits */ \<br />       ( 0x0 &lt;&lt; USICNT0 ); \<br />}<br /><br />#define SET_USI_TO_READ_DATA( ) \<br />{ \<br />  /* set SDA as input */ \<br />  DDR_USI &amp;= ~( 1 &lt;&lt; PORT_USI_SDA ); \<br />  /* clear all interrupt flags, except Start Cond */ \<br />  USISR    = \<br />       ( 0 &lt;&lt; USI_START_COND_INT ) | ( 1 &lt;&lt; USIOIF ) | \<br />       ( 1 &lt;&lt; USIPF ) | ( 1 &lt;&lt; USIDC ) | \<br />       /* set USI to shift out 8 bits */ \<br />       ( 0x0 &lt;&lt; USICNT0 ); \<br />}<br /><br /><br /><br />/********************************************************************************<br /><br />                                   typedef's<br /><br />********************************************************************************/<br /><br />typedef enum<br />{<br />  USI_SLAVE_CHECK_ADDRESS                = 0x00,<br />  USI_SLAVE_SEND_DATA                    = 0x01,<br />  USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02,<br />  USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA   = 0x03,<br />  USI_SLAVE_REQUEST_DATA                 = 0x04,<br />  USI_SLAVE_GET_DATA_AND_SEND_ACK        = 0x05<br />} overflowState_t;<br /><br /><br /><br />/********************************************************************************<br /><br />                                local variables<br /><br />********************************************************************************/<br /><br />static uint8_t                  slaveAddress;<br />static volatile overflowState_t overflowState;<br /><br /><br />static uint8_t          rxBuf&#91; TWI_RX_BUFFER_SIZE &#93;;<br />static volatile uint8_t rxHead;<br />static volatile uint8_t rxTail;<br /><br />static uint8_t          txBuf&#91; TWI_TX_BUFFER_SIZE &#93;;<br />static volatile uint8_t txHead;<br />static volatile uint8_t txTail;<br /><br /><br /><br />/********************************************************************************<br /><br />                                local functions<br /><br />********************************************************************************/<br /><br /><br /><br />// flushes the TWI buffers<br /><br />static void flushTwiBuffers(void)<br />{<br />  rxTail = 0;<br />  rxHead = 0;<br />  txTail = 0;<br />  txHead = 0;<br />} // end flushTwiBuffers<br /><br /><br /><br />/********************************************************************************<br /><br />                                public functions<br /><br />********************************************************************************/<br /><br /><br /><br />// initialise USI for TWI slave mode<br /><br />void usiTwiSlaveInit( uint8_t ownAddress )<br />{<br /><br />  flushTwiBuffers();<br /><br />  slaveAddress = ownAddress;<br /><br />  // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL<br />  // low when a start condition is detected or a counter overflow (only<br />  // for USIWM1, USIWM0 = 11).  This inserts a wait state.  SCL is released<br />  // by the ISRs (USI_START_vect and USI_OVERFLOW_vect).<br /><br />  // Set SCL and SDA as output<br />  DDR_USI |= ( 1 &lt;&lt; PORT_USI_SCL ) | ( 1 &lt;&lt; PORT_USI_SDA );<br /><br />  // set SCL high<br />  PORT_USI |= ( 1 &lt;&lt; PORT_USI_SCL );<br /><br />  // set SDA high<br />  PORT_USI |= ( 1 &lt;&lt; PORT_USI_SDA );<br /><br />  // Set SDA as input<br />  DDR_USI &amp;= ~( 1 &lt;&lt; PORT_USI_SDA );<br /><br />  USICR =<br />       // enable Start Condition Interrupt<br />       ( 1 &lt;&lt; USISIE ) |<br />       // disable Overflow Interrupt<br />       ( 0 &lt;&lt; USIOIE ) |<br />       // set USI in Two-wire mode, no USI Counter overflow hold<br />       ( 1 &lt;&lt; USIWM1 ) | ( 0 &lt;&lt; USIWM0 ) |<br />       // Shift Register Clock Source = external, positive edge<br />       // 4-Bit Counter Source = external, both edges<br />       ( 1 &lt;&lt; USICS1 ) | ( 0 &lt;&lt; USICS0 ) | ( 0 &lt;&lt; USICLK ) |<br />       // no toggle clock-port pin<br />       ( 0 &lt;&lt; USITC );<br /><br />  // clear all interrupt flags and reset overflow counter<br /><br />  USISR = ( 1 &lt;&lt; USI_START_COND_INT ) | ( 1 &lt;&lt; USIOIF ) | ( 1 &lt;&lt; USIPF ) | ( 1 &lt;&lt; USIDC );<br /><br />} // end usiTwiSlaveInit<br /><br /><br /><br />// put data in the transmission buffer, wait if buffer is full<br /><br />void usiTwiTransmitByte( uint8_t data )<br />{<br /><br />  uint8_t tmphead;<br /><br />  // calculate buffer index<br />  tmphead = ( txHead + 1 ) &amp; TWI_TX_BUFFER_MASK;<br /><br />  // wait for free space in buffer<br />  while ( tmphead == txTail );<br /><br />  // store data in buffer<br />  txBuf&#91; tmphead &#93; = data;<br /><br />  // store new index<br />  txHead = tmphead;<br /><br />} // end usiTwiTransmitByte<br /><br /><br /><br />// return a byte from the receive buffer, wait if buffer is empty<br /><br />uint8_t usiTwiReceiveByte(void)<br />{<br /><br />  // wait for Rx data<br />  while ( rxHead == rxTail );<br /><br />  // calculate buffer index<br />  rxTail = ( rxTail + 1 ) &amp; TWI_RX_BUFFER_MASK;<br /><br />  // return data from the buffer.<br />  return rxBuf&#91; rxTail &#93;;<br /><br />} // end usiTwiReceiveByte<br /><br /><br /><br />// check if there is data in the receive buffer<br /><br />uint8_t usiTwiDataInReceiveBuffer(void)<br />{<br /><br />  // return 0 (false) if the receive buffer is empty<br />  return rxHead != rxTail;<br /><br />} // end usiTwiDataInReceiveBuffer<br /><br /><br /><br />/********************************************************************************<br /><br />                            USI Start Condition ISR<br /><br />********************************************************************************/<br /><br />ISR( USI_START_VECTOR )<br />{<br /><br />  // set default starting conditions for new TWI package<br />  overflowState = USI_SLAVE_CHECK_ADDRESS;<br /><br />  // set SDA as input<br />  DDR_USI &amp;= ~( 1 &lt;&lt; PORT_USI_SDA );<br /><br />  // wait for SCL to go low to ensure the Start Condition has completed (the<br />  // start detector will hold SCL low ) - if a Stop Condition arises then leave<br />  // the interrupt to prevent waiting forever - don't use USISR to test for Stop<br />  // Condition as in Application Note AVR312 because the Stop Condition Flag is<br />  // going to be set from the last TWI sequence<br />  while (<br />       // SCL his high<br />       ( PIN_USI &amp; ( 1 &lt;&lt; PIN_USI_SCL ) ) &amp;&amp;<br />       // and SDA is low<br />       !( ( PIN_USI &amp; ( 1 &lt;&lt; PIN_USI_SDA ) ) )<br />  );<br /><br /><br />  if ( !( PIN_USI &amp; ( 1 &lt;&lt; PIN_USI_SDA ) ) )<br />  {<br /><br />    // a Stop Condition did not occur<br /><br />    USICR =<br />         // keep Start Condition Interrupt enabled to detect RESTART<br />         ( 1 &lt;&lt; USISIE ) |<br />         // enable Overflow Interrupt<br />         ( 1 &lt;&lt; USIOIE ) |<br />         // set USI in Two-wire mode, hold SCL low on USI Counter overflow<br />         ( 1 &lt;&lt; USIWM1 ) | ( 1 &lt;&lt; USIWM0 ) |<br />         // Shift Register Clock Source = External, positive edge<br />         // 4-Bit Counter Source = external, both edges<br />         ( 1 &lt;&lt; USICS1 ) | ( 0 &lt;&lt; USICS0 ) | ( 0 &lt;&lt; USICLK ) |<br />         // no toggle clock-port pin<br />         ( 0 &lt;&lt; USITC );<br /><br />  }<br />  else<br />  {<br /><br />    // a Stop Condition did occur<br />    USICR =<br />         // enable Start Condition Interrupt<br />         ( 1 &lt;&lt; USISIE ) |<br />         // disable Overflow Interrupt<br />         ( 0 &lt;&lt; USIOIE ) |<br />         // set USI in Two-wire mode, no USI Counter overflow hold<br />         ( 1 &lt;&lt; USIWM1 ) | ( 0 &lt;&lt; USIWM0 ) |<br />         // Shift Register Clock Source = external, positive edge<br />         // 4-Bit Counter Source = external, both edges<br />         ( 1 &lt;&lt; USICS1 ) | ( 0 &lt;&lt; USICS0 ) | ( 0 &lt;&lt; USICLK ) |<br />         // no toggle clock-port pin<br />         ( 0 &lt;&lt; USITC );<br /><br />  } // end if<br /><br />  USISR =<br />       // clear interrupt flags - resetting the Start Condition Flag will<br />       // release SCL<br />       ( 1 &lt;&lt; USI_START_COND_INT ) | ( 1 &lt;&lt; USIOIF ) |<br />       ( 1 &lt;&lt; USIPF ) |( 1 &lt;&lt; USIDC ) |<br />       // set USI to sample 8 bits (count 16 external SCL pin toggles)<br />       ( 0x0 &lt;&lt; USICNT0);<br /><br />} // end ISR( USI_START_VECTOR )<br /><br /><br /><br />/********************************************************************************<br /><br />                                USI Overflow ISR<br /><br />Handles all the communication.<br /><br />Only disabled when waiting for a new Start Condition.<br /><br />********************************************************************************/<br /><br />ISR( USI_OVERFLOW_VECTOR )<br />{<br /><br />  switch ( overflowState )<br />  {<br /><br />    // Address mode: check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK,<br />    // else reset USI<br />    case USI_SLAVE_CHECK_ADDRESS:<br />      if ( ( USIDR == 0 ) || ( ( USIDR &gt;&gt; 1 ) == slaveAddress) )<br />      {<br />          if ( USIDR &amp; 0x01 )<br />        {<br />          overflowState = USI_SLAVE_SEND_DATA;<br />        }<br />        else<br />        {<br />          overflowState = USI_SLAVE_REQUEST_DATA;<br />        } // end if<br />        SET_USI_TO_SEND_ACK( );<br />      }<br />      else<br />      {<br />        SET_USI_TO_TWI_START_CONDITION_MODE( );<br />      }<br />      break;<br /><br />    // Master write data mode: check reply and goto USI_SLAVE_SEND_DATA if OK,<br />    // else reset USI<br />    case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:<br /><br />    //TO NIE DZIALA!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<br />//      if ( USIDR )<br />//      {<br />//        // if NACK, the master does not want more data<br />//        SET_USI_TO_TWI_START_CONDITION_MODE( );<br />//        return;<br />//      }!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<br /><br /><br /><br />      // from here we just drop straight into USI_SLAVE_SEND_DATA if the<br />      // master sent an ACK<br /><br />    // copy data from buffer to USIDR and set USI to shift byte<br />    // next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA<br />    case USI_SLAVE_SEND_DATA:<br />      // Get data from Buffer<br />      if ( txHead != txTail )<br />      {<br />        txTail = ( txTail + 1 ) &amp; TWI_TX_BUFFER_MASK;<br />        USIDR = txBuf&#91; txTail &#93;;<br />      }<br />      else<br />      {<br />        // the buffer is empty<br />        SET_USI_TO_TWI_START_CONDITION_MODE( );<br />        return;<br />      } // end if<br />      overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;<br />      SET_USI_TO_SEND_DATA( );<br />      break;<br /><br />    // set USI to sample reply from master<br />    // next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA<br />    case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:<br />      overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;<br />      SET_USI_TO_READ_ACK( );<br />      break;<br /><br />    // Master read data mode: set USI to sample data from master, next<br />    // USI_SLAVE_GET_DATA_AND_SEND_ACK<br />    case USI_SLAVE_REQUEST_DATA:<br />      overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK;<br />      SET_USI_TO_READ_DATA( );<br />      break;<br /><br />    // copy data from USIDR and send ACK<br />    // next USI_SLAVE_REQUEST_DATA<br />    case USI_SLAVE_GET_DATA_AND_SEND_ACK:<br />      // put data into buffer<br />      // Not necessary, but prevents warnings<br />      rxHead = ( rxHead + 1 ) &amp; TWI_RX_BUFFER_MASK;<br />      rxBuf&#91; rxHead &#93; = USIDR;<br />      // next USI_SLAVE_REQUEST_DATA<br />      overflowState = USI_SLAVE_REQUEST_DATA;<br />      SET_USI_TO_SEND_ACK( );<br />      break;<br /><br />  } // end switch<br /><br />} // end ISR( USI_OVERFLOW_VECTOR )[/syntax]<br /><br />TWI.h:<br />[syntax=c]#ifndef TWI_SLAVE_USI_TWI_SLAVE_USI_H_<br />#define TWI_SLAVE_USI_TWI_SLAVE_USI_H_<br /><br />/********************************************************************************<br /><br />Header file for the USI TWI Slave driver.<br /><br />Created by Donald R. Blake<br />donblake at worldnet.att.net<br /><br />---------------------------------------------------------------------------------<br /><br />Created from Atmel source files for Application Note AVR312: Using the USI Module<br />as an I2C slave.<br /><br />This program is free software; you can redistribute it and/or modify it under the<br />terms of the GNU General Public License as published by the Free Software<br />Foundation; either version 2 of the License, or (at your option) any later<br />version.<br /><br />This program is distributed in the hope that it will be useful, but WITHOUT ANY<br />WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A<br />PARTICULAR PURPOSE.  See the GNU General Public License for more details.<br /><br />---------------------------------------------------------------------------------<br /><br />Change Activity:<br /><br />    Date       Description<br />   ------      -------------<br />  15 Mar 2007  Created.<br /><br />********************************************************************************/<br /><br /><br /><br />#ifndef _USI_TWI_SLAVE_H_<br />#define _USI_TWI_SLAVE_H_<br /><br /><br /><br />/********************************************************************************<br /><br />                                    includes<br /><br />********************************************************************************/<br /><br />//#include &lt;stdbool.h&gt;<br /><br /><br /><br />/********************************************************************************<br /><br />                                   prototypes<br /><br />********************************************************************************/<br /><br />void    usiTwiSlaveInit( uint8_t );<br />void    usiTwiTransmitByte( uint8_t );<br />uint8_t usiTwiReceiveByte( void );<br />uint8_t    usiTwiDataInReceiveBuffer( void );<br /><br /><br /><br />/********************************************************************************<br /><br />                           driver buffer definitions<br /><br />********************************************************************************/<br /><br />// permitted RX buffer sizes: 1, 2, 4, 8, 16, 32, 64, 128 or 256<br /><br />#define TWI_RX_BUFFER_SIZE  ( 16 )<br />#define TWI_RX_BUFFER_MASK  ( TWI_RX_BUFFER_SIZE - 1 )<br /><br />#if ( TWI_RX_BUFFER_SIZE &amp; TWI_RX_BUFFER_MASK )<br />#  error TWI RX buffer size is not a power of 2<br />#endif<br /><br />// permitted TX buffer sizes: 1, 2, 4, 8, 16, 32, 64, 128 or 256<br /><br />#define TWI_TX_BUFFER_SIZE ( 16 )<br />#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )<br /><br />#if ( TWI_TX_BUFFER_SIZE &amp; TWI_TX_BUFFER_MASK )<br />#  error TWI TX buffer size is not a power of 2<br />#endif<br /><br /><br /><br />#endif  // ifndef _USI_TWI_SLAVE_H_<br /><br /><br />#endif /* TWI_SLAVE_USI_TWI_SLAVE_USI_H_ */[/syntax]<br /><br /><br />a oto kod z pliku main .c TWI z BB.<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;util/delay.h&gt;<br /><br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;I2C_TWI/i2c_twi.h&quot;<br /><br />// **** UWAGA - wybierz właciwy adres jak niżej **************<br />//#define PCF8583_ADDR 0xA0// gdy A1 --&gt; GND<br />#define PCF8583_ADDR 0x25// gdy A1 --&gt; VCC<br /><br />#define _24C04_ADDR 0x25<br /><br />// utworzenie typu u08, odpowiednika uint8_t aby kod był bardziej czytelny<br />typedef unsigned char  u08;<br />typedef unsigned short u16;<br /><br /><br /><br />uint8_t tekst&#91;&#93; = &quot;EEPROM&quot;;<br /><br />uint8_t bo&#91; sizeof(tekst)+1 &#93;; // bufor pomocniczy na odczyt z EEPROM<br /><br />volatile uint8_t int0_flag=1;// flaga zmieniana w przerwaniu i sprawdzana w pętli głównej<br /><br />// konwersja liczby dziesiętnej na BCD<br />uint8_t dec2bcd(uint8_t dec);<br />// konwersja liczby BCD na dziesiętną<br />uint8_t bcd2dec(uint8_t bcd);<br /><br />// odczyt danych z pamięci EEPROM<br />void EI2C_read_buf(u08 device, u16 subAddr, u16 len, u08 *buf);<br />// zapis danych do pamięci EEPROM<br />void EI2C_write_buf(u08 device, u16 subAddr, u16 len, u08 *buf);<br /><br />int main(void) {<br /><br />DDRA |= (1&lt;&lt;PA7);// ustawiamy kierunek linii podświetlenia LCD jako WYJŚCIE<br />PORTA |= (1&lt;&lt;PA7);// załączamy podświetlenie LCD - stan wysoki<br /><br /><br />// definiujemy sobie dla polepszenia czytelności programu typ wyliczeniowy<br />// wskazujący nam później na odpowiednie indeksy w tablicy (buforze)<br />enum {ss=1, mm, hh};<br />uint8_t bufor&#91;4&#93;;// rezerwacja bufora 4 bajty<br />uint8_t sekundy, minuty, godziny;<br /><br /><br />lcd_init();<br /><br />i2cSetBitrate( 100 ); // USTAWIAMY prędkość 100 kHz na magistrali I2C<br /><br />sei();<br /><br />lcd_str_P(PSTR(&quot;start...&quot;));<br />_delay_ms(1000);<br />lcd_cls();<br /><br /><br /><br />while(1) {<br /><br /><br />//odczyt 4 bajtów do bufora od adresu 0x01 z pamięci RAM naszego RTC<br />TWI_read_buf( PCF8583_ADDR, 0x01, 4, bufor );<br /><br />sekundy = bcd2dec( bufor&#91;ss&#93; );<br />minuty = bcd2dec( bufor&#91;mm&#93; );<br />godziny = bcd2dec( bufor&#91;hh&#93; );<br /><br />// wyświetlenie czasu na LCD<br />lcd_locate(0,0);<br />lcd_int(godziny);<br />lcd_locate(1,5);<br />lcd_int(minuty);<br />lcd_locate(0,10);<br />lcd_int(sekundy);<br />_delay_ms(1000);<br /><br /><br /><br />}<br />}[/syntax]<br /><br /><br />Załączam orginalną bibliotekę:<br /><br /><br /><br />Dodam że próbowałem najpierw napisać kod obsługi SPI według noty jednak bezskutecznie, dlatego postanowiłem znaleźć gotowca tylko na TWI a nie SPI bo takie znalazłem. Był bym bardzo wdzięczny za pomoc w uruchomieniu tej komunikacji.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3349">Arek1111111111</a> — 21 gru 2015, o 22:17</p><hr />
]]></content>
</entry>
</feed>