AVR(Atmega8)SPI Probléma

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
eddy0519
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2013. január 25. péntek, 22:00

AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: eddy0519 »

Sziasztok!

SPI-n keresztül kommunikálnék egy MCP3202 ADC ic-vel!ATmega8 használok belső 8Mhz órajellel!
Az lenne a bajom hogy az spi-n sikerül lekérdezni az eredményt UART-on kiiratom de viszont 8-10 van amikor 2-3 lekérdezés után megáll (szerintem) a kommunikáció valami olyasmi lehet hogy nem érkezik meg a megfelelő számú bit és a while ciklusban míg várom át megy végtelenbe mert elszáll a kommunikáció!

Egy külső reset vagy watchdog után szintén elküldi egy párszor és szintén megáll!

Szerintetek bár nem hiszem hogy szoftveres baj lenne esetleg valaki találkozott-e spi kommunikáció során ilyen problémával!

Köszönöm!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: kapu48 »

Mint kezdő javaslom szíves figyelmedbe!

Hogyan küldj hozzászólást?
viewtopic.php?f=1&t=827
Oldal Olvasásást!
:roll:
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

Belső órajel + sorosport : kódolt hibalehetőség. :(
Belső 8 MHz esetén max 9600 bps lehet.


Programkód? :roll:
eddy0519
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2013. január 25. péntek, 22:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: eddy0519 »

Kód: Egész kijelölése

unsigned int SPI_MCP3204_WriteRead()
{
  unsigned char adatbe_h;
  unsigned char adatbe_l;
 
  // MCP3202 SPI bekapcsolasa (CS logikai alacsony szint)
  PORTB = (0<<PB1);
  // Adattranszfer elinditasa (MOSI) Küldünk 7 db nullat és utanna konfig biteket
  SPDR = 0b00000001;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
 // Adattranszfer elinditasa (MOSI)
  SPDR = 0b10100000;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
  // Beerkezett adat;
  adatbe_h = SPDR;
 // Adattranszfer elinditasa (MOSI)
  SPDR = 0b00000000;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
  // Beerkezett adat;
  adatbe_l = SPDR;
  // MCP3202 SPI kikapcsolasa (CS logikai magas szint)
  PORTB = (1<<PB1);
  // A beerkezett adatokbol a 12_bites ADC eredmeny eloallitasa
  return (adatbe_l | (adatbe_h &= 0b00001111) << 8 );

}
Ez a függvény adja meg magát!

Nem az UART-al van bajom hanem az SPI kommunikációval!

Az SPI kommunikációnak száll el valamiért amire nem tudok rá jönni??
Szerintem hardveres probléma van!
De lehet külső kvarcot kellene használni!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

SPI független a kvarctól -> saját órajele van.

SPI inicializálása megvolt? A _teljes_ program elején?
SPI sebesség?


2-3 lekérdezés _után_ áll meg, akkor nem az SPI-nél a hiba.
A soros kommunikációt vedd vissza 1200 vagy 300 bps-re
Amikor kéred, a soroson az adatot. Gyújts ki egy LED-et. Vagy sorospon jöjjön vissza a vett adat....

"Köszönöm, hogy részkód alapján ötletbörzét tarthatok."
eddy0519
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2013. január 25. péntek, 22:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: eddy0519 »

Kód: Egész kijelölése

/*
 * SPI.c
 *
 * Created: 2013.01.14. 22:21:38
 *  Author: Nemes Imre
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

#define F_CPU 8000000UL
#define USART_BAUDRATE 9600
#define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * 16UL)) - 1) // UBRR

volatile char kilogramm_ftoa_buffer[10];
volatile float kilogramm;

volatile int null_pont;
volatile int null_alatti_adc_ertek;
volatile char null_alatti_adc_ertek_buffer[10];

volatile int adcx;
volatile char adcx_buffer[10];


volatile char buffer[250];
volatile int array_step;

void Konfig_SPI(void)
{
	// MOSI es az SCK lab beallitasa kimenetnek PB1 chip select vagy slave select
	DDRB = (1<<PB3) | (1<<PB5) | (1<<PB1);
	//Magas  szint a slave select lábra igy inaktiv!
	PORTB = (1<<PB1);
	// SPI engedelyezese, Master mod, SPI orajel beallitasa MCP3204 1.8MHZ maxium 8000000/16 = 0.5MHZ
	SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
}
unsigned int SPI_MCP3204_WriteRead()
{
  unsigned char adatbe_h;
  unsigned char adatbe_l;
 
  // MCP3202 SPI bekapcsolasa (CS logikai alacsony szint)
  PORTB = (0<<PB1);
  // Adattranszfer elinditasa (MOSI) Küldünk 7 db nullat és utanna konfig biteket
  SPDR = 0b00000110;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
 // Adattranszfer elinditasa (MOSI)
  SPDR = 0b00000000;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
  // Beerkezett adat;
  adatbe_h = SPDR;
 // Adattranszfer elinditasa (MOSI)
  SPDR = 0b00000000;
  // Varakozas amig az adattranszfer befejezodik
  while(!(SPSR & (1<<SPIF)));
  // Beerkezett adat;
  adatbe_l = SPDR;
  // MCP3202 SPI kikapcsolasa (CS logikai magas szint)
  PORTB = (1<<PB1);
  // A beerkezett adatokbol a 12_bites ADC eredmeny eloallitasa
  return (adatbe_l | (adatbe_h &= 0b00001111) << 8 );

}

void ftoa(float flt, char * str,  int m ){  
    int i, d;
    char i_str[5], d_str[5];
    i = (int) flt;                   
    flt -= i;
    if (flt < 0 ) flt = -flt;     
    for ( int n = 0; n < m; n++ ){
        flt *= 10;
    }
    d = (int) flt;
    itoa(i,i_str,10);       
    itoa(d,d_str,10);   
    strcpy (str,i_str);     
    strcat (str,".");
    for (int n = 0; n < (m - strlen(d_str)); n++){      
         strcat (str,"0");
    }
    strcat (str,d_str);
}

//ftoa(float szám,buffer,mennyi digit legyen);

void KonfigUART()  
	{
          // 9600 bps soros kommunikacio sebesseg beallitasa
          UBRRL = UBRR_ERTEK;        
          // Aszinkron mod, 8 Adat Bit, Nincs Paritas Bit, 1 Stop Bit
          UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
          //Ado es Vevo aramkorok bekapcsolasa
          UCSRB |= (1 << RXEN) | (1 << TXEN) | (1<<RXCIE); 
	}
void UARTAdatKuld(char data)
{
          while(!(UCSRA & (1<<UDRE)))  // Varakozas amig az Ado kesz nem lesz az adatkuldesre
          {
             //  Varakozas
          }
          UDR=data;
		  
}
void UARTStringKuld(char *s)
{
	while(*s != 0)
	{
		UARTAdatKuld(*s);
		s++;
	}
}	

ISR(USART_RXC_vect)
{
	array_step++;
	if (array_step > 248)
	{
		array_step = 248;
	}
	
	buffer[array_step] = UDR;
	if(buffer[array_step == 'a'])
{
wdt_enable(WDTO_60MS);
}				
}

ISR(INT0_vect)
{
	null_pont = adcx;
}

int main(void)
{
	KonfigUART();
	
	Konfig_SPI();
	
	MCUCR = (1<<ISC01);
	GICR = (1<<INT0);
	
	sei();
	 
	while(1)
	  {	
		
		itoa(SPI_MCP3204_WriteRead(),adcx_buffer,10);
		
		 adcx = atoi(adcx_buffer);
		
				if(adcx <= null_pont)
				{
					null_alatti_adc_ertek = null_pont - adcx;

					itoa(null_alatti_adc_ertek,null_alatti_adc_ertek_buffer,10);
					
					kilogramm = null_alatti_adc_ertek / 1.5683;
			
					ftoa(kilogramm,kilogramm_ftoa_buffer,3);
					
					UARTStringKuld(kilogramm_ftoa_buffer);
					UARTStringKuld(" kilogramm!");
					
					UARTStringKuld("  ADC erteke: ");
					UARTStringKuld(null_alatti_adc_ertek_buffer);
					
					null_alatti_adc_ertek_buffer[10] = '\0';
					kilogramm_ftoa_buffer[10] = '\0';
					
					UARTAdatKuld('\r');
					UARTAdatKuld('\n');
				}	  		
	}
				
}
Teljes kód!

Nem az uartal van a hiba mert ha nyomok egy 'a' betűt ujraindul a processzor!Tehét a proci nem fagy ki az uart meg müködik!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

Ez mi?

Kód: Egész kijelölése

#include <avr/wdt.h>
Minek indítod újra a chipet?
Ezt a részt vágd ki a francba!
60 msecre is inicilaizálod?????
eddy0519
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2013. január 25. péntek, 22:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: eddy0519 »

Azt azért csinálom mert kipróbáltam hogy amikor meg áll a proci akkor uart-on elküldött 'a' karakterre ujra indul-e hogy nem-e a proci ált meg!

De mivel nem jön az érték az uart-on ezért tesztelésnek kiprobáltam hogy a proci fagy-e ki de NEM!
Uart-is müködik és a proci se fagy ki!

Felejtsük el az uart-ot!
Próbáltam egy ledet ha a adcx értéke 3800 alá esik akkor egy aludjon ki külömben világítson!
Világít de nem alszik ki!

A SPI_MCP függvény szálhat el mert vár az adatra ami valami hiba folytán nem érkezik be!Csak azt nem tudom mi lehet az a hiba!
SPI órajelre gondolok mivel a proci órajeléból osztja le és lehet hogy nem stabil azért godoltam a külső Kristályra!!
Szerinted nem ez lehet????
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

Kvarc biztosan nem.
Az SPI _ÖNÁLLÓ_ órajellel fut, azaz Ő maga szinkronizál!

Ha második-harmadikra fagy le, az NEM SPI hiba!!!!!!

A CS és az SPI kommunikáció közé 1msec késleltetés.
Az elvételkor is.

Az egyes adatok amik visszajönnek jók?
Kellene valami DEbug. NEM LED!
Soroson írdd vissza , hogy mi az alsó ill a felső bited.
Vagy procidebuggal, hogy mik a tartalmak.

Mondjuk C alatt szép szívás....



Tipp: nézz meg egy Arduino lib-t hozzá, és annak alapján éptsd fel a kódodat.
És tényleg dobd ki a watchdogot!
NEM erre való.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

Az MCP-re tettél referenciafeszültséget?
Az AVR belső ADCje miért nem jó a feladathoz? :)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: kapu48 »

Szerintem rossz helyen keresgélsz!

Mert, ahogy Robert irta SPI az SCK-val szinkronizálja a Slavet.

Tehát csak ha túl magas az SCK a slavenek az lehet gond.

És a belső órajel nem ingadozik, csak a hő változás hatására elmászik.
(Vagy nem tudják olyan pontosan beállítani, mint a Qvarcot.)
Ami csak a soros adatforgalmat zavarja, mert ott nincsen Szinkronizáló órajel.
eddy0519
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2013. január 25. péntek, 22:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: eddy0519 »

Persze van ref fesz!
Az adc által küldött adatok is megfelelo és valós!

Előző hozzászólónak:
Azért nem jó mert a 10bitesnek kicsi a felbontása a 12bites lenne a megfelelő!

Nem tudom miért állhat meg!
Valakinek még valami ötlet!

Tudom hogy awatchdog nem erre való de csak kipróbáltam!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: kapu48 »

Talán lesd el innen a SPI Transfert:
http://extremeelectronics.co.in/avr-tut ... avr-micro/

:idea:
Avatar
ppeter
DrótVégénSzéndarab
Hozzászólások: 19
Csatlakozott: 2009. február 6. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: ppeter »

Sziasztok, BÚÉK !

A topik címe miatt írok ide, bár a kérdésem off lesz a topiknyitó témához képest.

Több (működő) SPI-ző kódban láttam olyat, hogy inicializáláskor nem csak az SCK és MOSI
_IRÁNYÁT_, hanem az _ÉRTÉKÉT_ (szintjét) is beállítják (és itt nem a CPOL-ra gondolok).
Ennek mi lehet az értelme ? Magyarázatot sehol nem találok erre, adatlapokban, app. note-okban sem.

Köszi előre is,
p
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: AVR(Atmega8)SPI Probléma

Hozzászólás Szerző: Robert »

Mosi-Miso a 8 bit küldésekor _helyet cserél_.
Válasz küldése