Fórum témák
- • Szárítógép problémák
- • Robotfűnyíró vagy fűnyíró robot
- • Rádiótechnika számok keresése
- • Lézer érzékelő
- • Erősítő mindig és mindig
- • Napelem alkalmazása a lakás energia ellátásában
- • Számítógép hiba, de mi a probléma?
- • Transzformátor készítés, méretezés
- • Porszívó javítás
- • Rendelés külföldről (eBay - Paypal)
- • Szobatermosztát bekötése
- • Arduino
- • Fejhallgató erősítő
- • Sárga Kazettás Piaci Nintendo (8bit)
- • Klíma beszerelése, fűtés-hűtés házilag
- • Hűtőgép probléma
- • Kutya macska (vad) riasztó
- • FET vezérlése
- • Muzeális készülékek-alkatrészek restaurálása
- • Oszcilloszkóp, avagy hogyan kell használni?
- • Toroid transzformátor
- • LCD TV probléma
- • Elektromos távirányítós kapunyitó
- • Videomagnó problémák
- • SMD forrasztás profin
- • Érdekességek
- • CNC építése házi alkatrészekből az alapoktól
- • Ki hol gyártatja a NYÁK-ot ?
- • Felajánlás, azaz ingyen elvihető
- • Kazettás magnó (deck) javítása
- • HESTORE.hu
- • Hibrid erősítő
- • Borhűtő vezérlő panel
- • Karácsonyi fényfüzérek
- • Mosogatógép hiba
- • PC táp átalakítás
- • LED-es világítás
- • Kombikazán működési hiba
- • Áramlökés határoló lágyindító
- • Rádió adó építése
- • Akkus lámpa javítás
- • Villanyszerelés
- • Elektromos tolókapu
- • Villanypásztor
- • Li-Po - Li-ion akkumulátor és töltője
- • Gondolkodó ház avagy házautomatizálás
- • Mikrohullámú sütő javítás, magnetron csere, stb.
- • Kapcsolási rajzot keresek
- • Műhelyünk felszerelése, szerszámai
- • Rádióamatőrök topikja
- • Villanymotor mi a hiba?
- • Eredményjelző
- • Számítógép tápegység
- • ARM CPU assembler programozás
- • Autórádió (fejegység) problémák, kérdések, válaszok
» Több friss téma
|
Fórum » AVR - Miértek hogyanok
WinAVR / GCC alapszabályok:
1. Ha ISR-ben használsz globális változót, az legyen "volatile"
2. Soha ne érjen véget a main() függvény
3. UART/USART hibák 99,9% a rossz órajel miatt van
4. Kerüld el a -O0 optimalizációs beállítást minden áron
5. Ha nem jó a _delay időzítése, akkor túllépted a 65ms-et, vagy rossz az optimalizációs beállítás
6. Ha a PORTC-n nem működik valami, kapcsold ki a JTAG-et
Bővebben: AVR-libc FAQ
Hát, itt csatolok egy kódot, ami szoftverből programozza az AVR-t.
Ha megvan a lelkesedés és van fusebit doctorod, amivel korrigálod a szoftverhibákat, akkor rajta. Kezdetben mondjuk csak a signature-t olvasd ki, azzal kisebb valószínűséggel pusztítod szét az IC-t, mintha elsőre fuse-biteket írogatnál SPI-vel.
A hozzászólás módosítva: Szept 30, 2013
Ezt hogyan tölti fel?
adamtui_93: Mindjárt megnézem a kódot.
Ez az Arduino ISP programozójának forrása. A hogyan tölti fel, az egyáltalán nem érdekes, kizárólag ha szeretsz horrorsztorikat olvasni. A lényeg viszont szépen kivehető, hogy mit küldj az SPI-n a fuse bitek megváltoztatásához.
Rendeltem időközben egy másik tiny13-at. De arra gondoltam hogyha figyelem egy másik avr-el a MISO lábát az új tinynek programozás közben és azt az adatot ráküldöm erre csak lassabb akkor elméletileg működni-e kell nem?
SPI-n nincs késleltetés. Az I2C-n tudod lassítani a kommunikációt azzal, hogy az SCK lábat alacsonyban tartod, de SPI-n nem.
SPI alatt a mester (programozó) adja az órajelet. Kiküldi, hogy mit akar, ezzel _egyidőben_ beolvassa a választ.
Magyarul a programozó kiküld 4 byte-ot, az utolsó 3 byte-ot pedig egyidőben a küldéssel olvassa.
/*
* Functions specific to ISP programming of an AVR
*/
uint16_t spi_transaction (uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
uint8_t n, m;
SPI.transfer(a);
n = SPI.transfer(b);
//if (n != a) error = -1;
m = SPI.transfer(c);
return 0xFFFFFF & ((n<<16)+(m<<8) + SPI.transfer(d));
}
byte SPIClass::transfer(byte _data) {
SPDR = _data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR;
}
A hozzászólás módosítva: Okt 1, 2013
Bár számomra továbbra sem tiszta, hogy miért nem avrdude alatt programozod fel -b19200-zal.
Letöltöd az avrdude-t, az avr8-burn-o-mat-ot és az additional options-ök közé beírod a -b19200-at.
Sziasztok. Most kezdenék komolyabban foglalkozni AVR-rekkel és nagy kérdés, hogy vegyek-e Tbird-öt (ezt használjuk egyetemen) vagy elég a Topi féle AVR dopper is. Ahogy eddig néztem Jtag előnye hogy lehet vele debugolni de az ISP-s programozó meg több avr-hez használható. Szerintetek melyiket érné meg jobban? Árban kb ugyan annyira jönnék ki ha magam építem.
Én a Dragont használom a legnagyobb megelégedés mellett. Csak ajánlani tudom.
TBIRD-et en elfelejteném.
Inkább Dragon, mert azon ott az ISP, HVPP/HVSP, JTAG és dW is...
És valami egyszerű M128-as panelt mellé...
Doper meg felejtős, az emulált USB miatt (+driver+firmware+AVRStudio 6.1 támogatásának korlátai miatt)
A Doper és a TBird azért nem egy árkategória....
Jó, kicsit túloztam. A doper kijön 2-3000ből +még egy mega128-as panel, ami tudja azt mint a Tbird és máris 8k körül van azért ez is
Ez a Dragon jól néz ki meg minden, csak hát az árát is elkérik elég rendesen
A Doper tényleg ennyire használhatatlan? Elég sokan írták hogy megépítették. A driveres problémák AVRStudio4-nél is vannak?
Esetleg egy STK500 vagy a TavIR AVRisp (ez nem ugyan az mint a doper  ) jobb lenne?
STK500 - hardware usb-soros átalakító + egy AVR chip ami _hardware_ alapon kezel mindent.
TavIR AVRisp: A klasszikus AVR910-es hardware programozó. Csak nem RS232 sorosport, hanem FT232 USB-soros átjáróchippel.
Ugyanitt van JTAGICE is...
Tanulni akarsz? Játszadozni? Suliba kell, csak drága a TBird?
Mi a cél pontosan?
Dopernél az _emulált_ USB okoz problémát. De semmi jónak nem vagyok elrontója, mindenki a saját kárán tanul (én is így jártam...  ).
Igazából mind a három a cél egyszerre. Suliba most Tbird-öt használunk de nekem nem tetszik se az ára se maga a kivitele ezekkel a szalagkábeles csatlakozókkal (már meg is van tervezve egy saját próbapanel). De szeretnék komolyabban is foglalkozni vele, nem csak amit vizsgára elvárnak.
Tipp:
TBird-et próbálj meg használtan begyűjteni - hamár a suliban alapelvárás. Sok szívástól véded meg magadat (felesleges körök).
És én debugos programozóra a Dragont tippelném - bár amennyi debug kellett az elmúlt 6 év alatt  . Sima sorosport sokszor elég + a JTAGICE (ami a TBird-en van). És persze saját áramkörök - Arduino alapon.
De az induláskor használt az egyenpanelt, amit mindenki a suliban... (javaslat).
Ha kinövöd:
1, sajátot tervezel úgyis
2, TBird-et meg elpasszolod - az ára visszajön.
Sziasztok!
ATmega168-ra kötöttem egy DS18B20-at, és egy kijelzőre szeretném kiírni az értékét. Amit kiír nekem folyamatosan +127.9375 C. Megtudja nekem valaki mondani hogy mit rontottam el?
/*
* lcdmenu.c
*
* Created: 2013.07.11. 16:03:42
* Author: Pézsma
*/
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lcd.h"
#define F_CPU 8000000UL
/* Thermometer Connections (At your choice) */
#define THERM_PORT PORTC
#define THERM_DDR DDRC
#define THERM_PIN PINC
#define THERM_DQ PC0
#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)
#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xbe
#define THERM_CMD_WSCRATCHPAD 0x4e
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xb8
#define THERM_CMD_RPWRSUPPLY 0xb4
#define THERM_CMD_SEARCHROM 0xf0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xcc
#define THERM_CMD_ALARMSEARCH 0xec
#define THERM_DECIMAL_STEPS_12BIT 625 //.0625
uint8_t therm_reset(){
uint8_t i;
//Pull line low and wait for 480uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(480);
//Release line and wait for 60uS
THERM_INPUT_MODE();
_delay_us(60);
//Store line value and wait until the completion of 480uS period
i=(THERM_PIN & (1<<THERM_DQ));
_delay_us(420);
//Return the value read from the presence pulse (0=OK, 1=WRONG)
return i;
}
void therm_write_bit(uint8_t bit){
//Pull line low for 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
//If we want to write 1, release the line (if not will keep low)
if(bit) THERM_INPUT_MODE();
//Wait for 60uS and release the line
_delay_us(60);
THERM_INPUT_MODE();
}
uint8_t therm_read_bit(void){
uint8_t bit=0;
//Pull line low for 1uS
THERM_LOW();
THERM_OUTPUT_MODE();
_delay_us(1);
//Release line and wait for 14uS
THERM_INPUT_MODE();
_delay_us(14);
//Read line value
if(THERM_PIN&(1<<THERM_DQ)) bit=1;
//Wait for 45uS to end and return read value
_delay_us(45);
return bit;
}
uint8_t therm_read_byte(void){
uint8_t i=8, n=0;
while(i--){
//Shift one position right and store read value
n>>=1;
n|=(therm_read_bit()<<7);
}
return n;
}
void therm_write_byte(uint8_t byte){
uint8_t i=8;
while(i--){
//Write actual bit and shift one position right to make the next bit ready
therm_write_bit(byte&1);
byte>>=1;
}
}
void therm_read_temperature(char *buffer){
// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
uint8_t temperature[2];
int8_t digit;
uint16_t decimal;
//Reset, skip ROM and start temperature conversion
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
//Wait until conversion is complete
while(!therm_read_bit());
//Reset, skip ROM and send command to read Scratchpad
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
//Read Scratchpad (only 2 first bytes)
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();
//Store temperature integer digits and decimal digits
digit=temperature[0]>>4;
digit|=(temperature[1]&0x7)<<4;
//Store decimal digits
decimal=temperature[0]&0xf;
decimal*=THERM_DECIMAL_STEPS_12BIT;
//Format temperature into a string [+XXX.XXXX C]
sprintf(buffer, "%+d.%04u C", digit, decimal);
}
int main(void)
{
lcd_init(); // kijelző beállítása
_delay_ms(100);
lcd_contrast(0x20); // pixel erősség beállítása
PORTD |=0b11111111; // felhúzzuk a gombokat tápra
while(1) {
char x[10] = {0};
therm_read_temperature(x);
lcd_clear();
lcd_goto_xy(1,1);
lcd_str(x);
_delay_ms(1000);
} //end while
} //end main
A hozzászólás módosítva: Okt 5, 2013
Ezzel a kóddal én is próbálkoztam: Bővebben: Link
Aztán sajátba kezdtem: Bővebben: Link
Olvasd el azt is amit írtak hozzá. Most már "jól" működik.
Köszönöm szépen, megpróbálom.
Sziasztok!
PT100-at kötnék avr ADC bemenetre egyszerű feszültség osztóval jó vagy keresek más megoldást?
Szia!
Nem lesz ilyen egyszerű.
Max csak 1mA folyhat rajta keresztül.
Ha 5V a tápod, akkor kb 5,1k ellenállást kell vele sorbakötnöd.
20°C - 107,79 Ohm sorba kötve az 5,1k ellenállással 103,5mV kimenet.
30°C - 111,67 Ohm sorba kötve az 5,1k ellenállással 107,1mV kimenet.
Azaz 10°C változásra 3,6mV változásod lesz.
Az ADC felbontása 5V referencia esetén kb. 4,9mV.
Tehát 14°C változás fog 1 ADC érték változást eredményezni.
Megoldás az, hogy ezt a feszültséget felerősíted.
Ez az emulált USB szerintem meg sem született volna soha, ha lenne DIP-es USB-s AVR IC.
Igazából én gondolkozom, hogy érdemes-e PIC-es mikrokontrollert használni USB-re, mert a Microchipnek vannak ilyen IC-i. Ha valakinek van tapasztalata velük, érdekelne.
Én vennék az AVR-hez próbapanelt és raknék rá tüskesort, és akkor az is kiépíthető. Nekem egy elektromérnök azt mondta hogy komoly eszközökben nem célszerű PIC-et használni mert szerinte nem megbízható. Az én iparágamban csak Philips vagy Atmel kontrollerekkel találkoztam. Van olyan gép hogy ha rádugod a pendrive-ot akkor az USB-s AVR újraírja a többit.
Idézet: „...komoly eszközökben nem célszerű PIC-et használni mert szerinte nem megbízható.” Nem tudom ezt honnan veszi az a mérnök, mivel az AVR is pont olyan mikrovezérlő, mint a PIC, sőt a PIC-ek még sokkal hamarabb is megjelentek mint az AVR-ek.
Szerintem pedig a PIC-ek jobbak, meg amúgy is eddig több eszközben találkoztam velük, mint AVR-el. A másik előnye a PIC-eknek, hogy sokkal nagyobb a választék a mikrovezérlők terén.
-1
Ez nettó hülyeség. Valószínű hogy az illető AVR-ekhez sem ért. Ha már ipari cucc:
868MHz-es rádió paneleket (is) gyártunk. Az adóban AVR van, a vevőben PIC.
Annyi biztos hogy az AVR sleep módban nagyon keveset eszik az elemes adóáramkörben,
míg a vevőben lévő PIC állandóan ketyeg, de nem gond mert hálózatról megy...
Egy védődiódás kérdésem lenne.
A P-csatornás MOSFET alapból úgy készül el, hogy D->S a kapcsolható rész, S->D az dióda.
( IRF9Z34, Continuous Source-Drain Diode Current -18A)
Ha mondjuk 12V-on motort kapcsolgatok (12V -> pfet -> motor -> 0V), akkor kihasználható-e az, hogy úgyis ott van a MOSFET ellentétes irányú diódája, egy kicsit megugrik a feszültség 12.7V-ra, de az mind befolyik a VDD-re.
Kell-e védődióda, ha a MOSFET-ben egyébként is benne van? (nem egy kellene, hanem 32, ezért ha lehet kihagynám) A hozzászólás módosítva: Okt 8, 2013
A motorbol a VDD fele hasznalhatod, persze. De az ellen semmi nem ved, amikor a motor minuszba megy el (akár csak egy impulzusnyi idore), azaz a FET-ed drain-jet leviszi minusz akarhany voltra. Ha azt a feszultseget hozzaadaod a VDD-hez, akkor megkapod, hogy mennyi van a D es S kozott. Annak nem kellene atlepni a 60 voltot. Szoval a motorral parhuzamosan egy forditott dioda hasznos lehet.
Kihagyhatod?
De akkor úgy tervezd meg, hogy roncsolás nélkül tudjál Feteket cserélni!
Mert az egész áramkört cserélni drága kísérlett lesz!
A kérdés H bridge-re vonatkozott, csak kissé ügyetlenül tettem fel:
A diódák eleve benne vannak a fet-ekben, akkor a külső dióda ( 1N4004) mennyi pluszt tesz hozzá az áramkörhöz? A hozzászólás módosítva: Okt 8, 2013
Az 1N4004 pár grammot, de azon kivul semmit, mert aramban kisebb es szerintem lassabb is, mint a FET body diodaja. Szoval, ha ilyen H-Bridge-ed van, akkor szerintem a kulso 1N4004 teljesen felesleges. Olyat mar lattam (digitalis vegfokokban), hogy Schottky dioda volt parhuzamosan a FET-tel, mert eleve kisebb a nyitofeszultsege, es iszonyu gyors, tehat a tuskek ellen megvedi a FET-et. A hozzászólás módosítva: Okt 8, 2013
Sziasztok!
Adott egy tbird2 ( Bővebben: Link) és a hozzá tartozó kiegészítő panel ( Bővebben: Link).
Szeretnék olyan programot írni C-ben, amely a teljes processzoridő felhasználása nélkül a 4db 7 szegmenses kijelzőkön tart bizonyos értékeket, miközben más feladat is végrehajtódhat.
Az A port ilyen formában értelmezi a bináris adatot: XYYYZZZZ, ahol X az engedélyezés, Y a 4 kijelző valamelyikének címe, a Z pedig a tényleges számadat
Jelenleg az alábbi kód végzi a dolgát:
void szegmBIN(unsigned int z)
{ int k; unsigned char x[4],i,j=25; //j-szer gyújtjuk ki mind a 4 szegmenst
//integer számjegyeit tömb elemeibe teszem.
for(i=0,k=1;i<4;i++,k=k*10) x[i]=(z/k)%10; // 4 db számjegy
//4 digit kijelzése j alkalommal (j*20 msec)
while(j--) // a kijelzés 25*5*4=500 msec
{ for(i=0;i<4;i++)
{ PORTA=128+(i<<4)+x[i]; //digitek kijelzése
_delay_ms(5);
}
}
}
int main()
{
unsigned int x=1111;
DDRA=0xFF;
while (1) szegmBIN(x); //folyamatosan kiírja: 1111
return 0;
}
A 7 szegmenses kijelzőkön olvasható adat csak alkalmanként szorulna frissítésre, addig pedig folyamatosan meg kell jelenjen.
Hogyan tudnám hatékonyabbá tenni a kódot?
edit: linkek A hozzászólás módosítva: Okt 8, 2013
Használni kell az időzítő megszakítását. Pl:
// órajel forrás frekvencia (most 16MHz)
#define TimerSrcClock (1UL*16000000)
// 200 megszakítás/sec (5msec)
#define TIMECLK 200
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
volatile unsigned char x[4]; // ez kerül a kijelzőre
ISR (TIMER1_COMPA_vect)
{
static unsigned char y = 0; // aktuális karakter (0..3)
PORTA &= ~(1 << 7); // kijelzés ki
PORTA = (y << 4) + x[y}; // karakter cím és érték ki
PORTA |= (1 << 7); // kijelzés be
y++;
if (y > 3) y = 0;
}
void timerinit(void)
{
// időzítő inicializálása
#define TIMEDIV ((TimerSrcClock+TIMECLK/2)/TIMECLK-1)
#if TIMEDIV < 65536
#define TMCLKDIV 1
#define TMCLKSEL 1
#elif TIMEDIV < (65536*8)
#define TMCLKDIV 8
#define TMCLKSEL 2
#elif TIMEDIV < (65536*64)
#define TMCLKDIV 64
#define TMCLKSEL 3
#elif TIMEDIV < (65536*256)
#define TMCLKDIV 256
#define TMCLKSEL 4
#elif TIMEDIV < (65536*1024)
#define TMCLKDIV 1024
#define TMCLKSEL 5
#endif // TIMEDIV
#define TMCOMP (((TimerSrcClock/TMCLKDIV)+TIMECLK/2)/TIMECLK-1)
OCR1AH = TMCOMP >> 8; // comparator HI
OCR1AL = (unsigned char)TMCOMP; // comparator LO
TCCR1A = (0<<WGM10); // mode4 (CTC)
TCCR1B = (1<<WGM12)|(TMCLKSEL<<CS10); // mode4, Clk = ClkIO/1..8..64..256..1024
#ifdef TIMSK1
TIMSK1 = (1<<OCIE1A);
#else // TIMSK1
TIMSK |= (1<<OCIE1A);
#endif // TIMSK1
sei();
}
int main(void)
{
int k; unsigned char i;
unsigned int z = 1111;
for(i=0,k=1;i<4;i++,k=k*10) x[i]=(z/k)%10; // 4 db számjegy
DDRA=0xFF;
timerinit();
while (1)
{
// ide mehet bármi, a megszakításból folyamatosan frissül a kijelző
}
}
A hozzászólás módosítva: Okt 8, 2013
Sziasztok!
Legalább egy napom már ráment az Atmel által publikált TWI driverek működésre bírásával.
Lassan kívülről fújom a doksit is és a kódot is. Miért nem működik? Mit nézek el?
Adó:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "TWI_Master.h"
#define TWI_GEN_CALL 0x00 // The General Call address is 0
// Sample TWI transmission commands
#define TWI_CMD_MASTER_WRITE 0x10
#define TWI_CMD_MASTER_READ 0x20
// Sample TWI transmission states, used in the main application.
#define SEND_DATA 0x01
#define REQUEST_DATA 0x02
#define READ_DATA_FROM_BUFFER 0x03
unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
{
// A failure has occurred, use TWIerrorMsg to determine the nature of the failure
// and take appropriate actions.
// Se header file for a list of possible failures messages.
// Here is a simple sample, where if received a NACK on the slave address,
// then a retransmission will be initiated.
if ( (TWIerrorMsg == TWI_MTX_ADR_NACK) | (TWIerrorMsg == TWI_MRX_ADR_NACK) )
TWI_Start_Transceiver();
return TWIerrorMsg;
}
#define SW1 !(PINB & (1<<PINB0))
void PortIrany()
{
PORTB |= (1<<PB0); //felhúzóellenállás be
}
int main(void)
{
PortIrany();
unsigned char messageBuf[TWI_BUFFER_SIZE];
unsigned char TWI_targetSlaveAddress = 0x10;
unsigned char TWI_operation=0;
TWI_Master_Initialise();
sei();
while(1)
{
if(SW1)
{
messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
messageBuf[1] = 0;
TWI_Start_Transceiver_With_Data( messageBuf, 2 );
_delay_ms(500);
messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
messageBuf[1] = 1;
TWI_Start_Transceiver_With_Data( messageBuf, 2 );
_delay_ms(500);
}
if ( ! TWI_Transceiver_Busy() )
{
// Check if the last operation was successful
if ( TWI_statusReg.lastTransOK )
{
if ( TWI_operation ) // Section for follow-up operations.
{
// Determine what action to take now
if (TWI_operation == REQUEST_DATA)
{ // Request/collect the data from the Slave
messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
TWI_Start_Transceiver_With_Data( messageBuf, 2 );
TWI_operation = READ_DATA_FROM_BUFFER; // Set next operation
}
else if (TWI_operation == READ_DATA_FROM_BUFFER)
{ // Get the received data from the transceiver buffer
TWI_Get_Data_From_Transceiver( messageBuf, 2 );
//PORTB = messageBuf[1]; // Store data on PORTB.
TWI_operation = FALSE; // Set next operation
}
}
}
else // Got an error during the last transmission
{
// Use TWI status information to detemine cause of failure and take appropriate actions.
TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info( ) );
}
}
}
}
Vevő:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "TWI_slave.h"
// Sample TWI transmission commands
#define TWI_CMD_MASTER_WRITE 0x10
#define TWI_CMD_MASTER_READ 0x20
//Led
#define LedBe PORTB |= (1<<PB0)
#define LedKi PORTB &= ~(1<<PB0)
unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
{
// A failure has occurred, use TWIerrorMsg to determine the nature of the failure
// and take appropriate actions.
// Se header file for a list of possible failures messages.
// This very simple example puts the error code on PORTB and restarts the transceiver with
// all the same data in the transmission buffers.
PORTB = TWIerrorMsg;
TWI_Start_Transceiver();
return TWIerrorMsg;
}
int main(void)
{
DDRB |= (1<<PB0); //PB0 kimenet
uint8_t TWI_slaveAddress = 0x10;
uint8_t messageBuf[1];
TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_GEN_BIT) ));//TWI indítás (slave cím megadás és általános hívás fogadásának engedélyezése)
sei();
// Start the TWI transceiver to enable reception of the first command from the TWI Master.
TWI_Start_Transceiver();
while(1)
{
if ( ! TWI_Transceiver_Busy() )
{
if ( TWI_statusReg.RxDataInBuf )
{
TWI_Get_Data_From_Transceiver(messageBuf, 1);
if(messageBuf[0]==1)
{
LedBe;
}
if(messageBuf[0]==0)
{
LedKi;
}
}
}
}
}
Mit nézek el?
kapcsolódó doksik:
AVR315: Using the TWI module as I2C master - Atmel Corporation Bővebben: Link
AVR311: Using the TWI module as I2C slave - Atmel Corporation Bővebben: Link A hozzászólás módosítva: Okt 9, 2013
|
|