# ATMEL mikrokontrolleri >  Haotiska atmel uzvedība

## cobalt

Problēmas darbībā neesmu sīki iedziļinājies, bet vēders saka, ka to izsauc slikta barošana, nepareizs vadu novietojums un filtru trūkums.
Izpausmes arī neesmu smalki pētījis, bet pēc uzvedības varētu spriest, ka tā izpaužās kā paša mikrokontroliera pārstartēšanās un takts ģeneratora problēmas.

Uzvedība tāda, ka principa pēc ieprogrammēšanas vispār nestrādā.. pēc gaismas diodes kontrolei darbības varētu domāt, ka nepārtraukti restartējas.
Pagrābstoties gar pašu kontrolieri, vai restart rezistoru sāk strādāt.. bet haotiski. Jāvada ir servo motors.. viņu pieslēdzot vainu bez apstājas rotē vienā virzienā (tā var gadīties, ja viņu visu laiku "ieslēdz".. vai nepadod laikā vadības impulsus). Pagramstoties citur grozās dažādos virzienos/raustās.. tātad mainās impulsu garumi servo.

Vēršos pie jums ar sekojošiem jautājumiem. 

Vai ņemot vērā to, ka barošanai tiek lietots datora USB ports, attēloto shēmu, haotisko maketplati un darba frekvenci, varētu būt šādas darbības problēmas, vai tomēr cēlonis jāmeklē citur.
Programmas testēšanas nolūkos, ko šādā prototipa situācijā varētu ieteikt stabilākas darbības nodrošināšanai uz maketplates (filtru kondensatori, cita barošana utml).
Kā ieteiktu papildināt shēmu lai pilnībā izslēgtu šādas problēmas kad tiks izveidota gatava plate.

Diez vai kāds gribēs iedziļināties, bet katram gadījumam kods:


```
#include <inttypes.h>
#include "avr/io.h"
#include "avr/iom8.h"
#include "avr/interrupt.h"
#include "avr/wdt.h"

#define msmax 250 //2. taimera vertiba, pie izveleta dalitaja, sasniedzot 2 ms.
#define msmin 125 //0%
#define msmid msmin+63  //~50%

unsigned char t=0,D=msmid; //D=63 ~ 1/2 

ISR(TIMER0_OVF_vect)
{
	PORTB|=(1<<PB0);
	OCR2=D;
	SFIOR|=(1<<PSR2); //T2 prescaler reset
	TCCR2=(1<<WGM21)|(1<<CS21)|(1<<CS20); //T2 on + clk/32
	D++;
	if(D==msmax){D=msmin;}
	PORTB|=(1<<PB1);
}

ISR(TIMER2_COMP_vect)
{
	
	PORTB^=~(1<<PB0);
	TCCR2=0x00;
	/*PORTB|=(1<<PB1);
	t++;
	switch(t) 
		{
		case 1:
			OCR2=D;
			break;
		case 2:
			OCR2=msmax-D;
			PORTB^=~(1<<PB0);
			break;
		case 3:
			OCR2=msmax;
			break;
		case 16:
			PORTB|=(1<<PB0);
			t=0;
			D++;
			if(D==125)
				{
				D=0;
				}
			break;
		default:
			break;
		} */
}

int main(void)
{
	wdt_disable(); //izsledzam watchdog taimeri.
	//Saslēdzam izejas	
	DDRB|=(1<<PB0)|(1<<PB1);	//P1,P2=output
	PORTB^=~(1<<PB1);			//ledon (0=on)
	PORTB^=~(1<<PB0);			//motor off
	
	//Nokonfigurejam taimerus
	//TCCR2=(1<<WGM21)|(1<<CS21)|(1<<CS20); //bus jaiesledz pec pirma T0
	TIMSK|=(1<<OCIE2)|(1<<TOIE0); //T2 Output CMP IntEnbl.+ T1 OvrFlw IntEn.
	TCCR0=(1<<CS02); // '1,0,0' = clk/256 -> Iesledzam T1.
	sei(); //iesl. int.
	for(;;){}
}

//4 Mhz XTAL: CKSEL3..0=1111
```

 Patreiz bez lielām ekstrām, pats nepieciešamākais darbības testēšanai. Vēlāk plānots modificēt 4..6 servo vadībai un citu funkciju nodrošināšanai.

P.S. Shēmu centos veidot aptuveni tikpat haotisku kāda ir "plate". Dažas lietas uz maket plates nemaz taisnāk nesanāk savilkt.

----------


## Colibris

Vai kvarcam otra kaaja ir pievienota mikrokontrolierim? Peec sheemas nav!

----------


## cobalt

Ir.. aizmirsu shēmā pievilkt.

----------


## next

Ja aizdomas uz hardvari tad izmet pagaidaam visu to gudriibu, atstaaj tikai LED spiidinaashanu un paskaties kaa tas notiek.
Oscilograafs ir?

----------


## cobalt

Oscilis ir, lidz 1 Mhz (pie 500 kHz knapi sinhronizejas) un mazs ekrāns.. t.i. nekādus laikus vai spriegumus mērīt nav iespējams tikai stipri aptuveni.
Japačeko leds..

Principā kodā arī ir viena kļūda, kurai gan nevajadzētu traucēt:
PORTB^=~(1<<PBx); vietā jābūt PORTB&=~(1<<PBx); vietā jābūt  (izslēgt bitu/pinu PBx);

----------


## Epis

vis biežāk vainīgi gļukos ir slikti kontakti, un arī švaka barošana.
pamēģini pielikt papildus kādu lielāku kondensātoru ~ 470uF  moš tas kautko līdzēs, ja nekas nelīdz tad mēģini to visu uzlodēt uz maketplates, jo iespējams kontakti sūdīgi tam breadbordam.

----------


## tvdx

kvarcu sprauzot breadbordaa neesi sabojaajis? kvarca kaajas nedriikst lociit...(to vai kvrcs vesels var pateikt peec taa kaadaa kraasaa ir tie "rimbuļi" kur kaajas ieiet korpusaa

----------


## cobalt

Vispār varētu gadīties. Mazliet palocīju gan.

Saliku kaudzi kondieru uz barošanu un motoram vairs tik haotiski neuzvedas, bet liekas ka problēma tiešām ap kvarcu lokalizējusies.. t.i. pie viņa bakstoties citreiz strādā/citreiz nē.

Dīvaini gan, ka tests ar mirgojošus led'u pēc _delay_ms(100)  gāja, bet viņš nav tika taming'a (kā būtu latviski) jūtīgs.

Kādā krāsā tur jābūt tiem rimbuļiem ap kvarca izvadiem, manējie ir stipri tumši, melni teiktu?

----------


## SnacK

Man viens Atmega32 projektiņš, kas pieslēgts pie kompja barošanas bloka 12V līnijas caur 7805 stabilizatoru, restartējas, kad virtuvē ieslēdzas vai IZSLĒDZAS leduskapis!  :: 
Stāv divi elektrolīti  - viens pirms stabilizatora, otrs, neliels pēc, plus vēl 100nF keramiskais kondensatoriņš. Kompis darbojas bez problēmām. Neesmu gan īpaši meklējis, kapēc tāda problēma, bet šķiet visai dīvaini...

----------


## jeecha

Kaadreiz bija man viens leets kjiiniezeru breadboards un tas tika norakstiits veestures meeslainee deelj mistiskiem gljukiem kuri nekad neparaadiijaas salodeejot visu uz maketplates. Varbuut shajaa gadiijumaa arii breadboards oscilatoru chakaree ar piemeeram paaraak lielu kapacitaati?

----------


## Epis

Palaid kodu no iekšējā atmegas Oscilatora, ja viss sāks iet bez gļukiem tad skaidrs vaina ārējā oscilā. bet ja gļuki turpinās tad vaina breadbordā.

----------


## cobalt

Taks.. pagaidām pārslēdzos uz 4Mhz iekšējo raustītāju. Principā tāda pati uzvedība.
Sāku sliekties uz vainu kodā.

Pagaidām jams šāds:


```
#include <inttypes.h>
#include "avr/io.h"
#include "avr/iom8.h"
#include "avr/interrupt.h"
#include "avr/wdt.h"

#define msmax 250 //2. taimera vertiba, pie izveleta dalitaja, sasniedzot 2 ms.
#define msmin 125 //0%
#define msmid msmin+63  //~50%

unsigned char D=msmid; //D=63 ~ 1/2 

ISR(TIMER0_OVF_vect)
{
	PORTB|=(1<<PB0);
	OCR2=D;
	SFIOR|=(1<<PSR2); //T2 prescaler reset
	TIMSK|=(1<<OCIE2);
	TCCR2|=(1<<WGM21)|(1<<CS21)|(1<<CS20); //T2 on + clk/32
	D++;
	if(D==msmax)
		{
		D=msmin;
		PORTB^=~(1<<PB1);
		}
}

ISR(TIMER2_COMP_vect)
{
	PORTB&=~(1<<PB0);
	TCCR2=0x00;
	TIMSK&=~(1<<OCIE2);
}

int main(void)
{
	wdt_disable(); //izsledzam watchdog taimeri.
	//Saslēdzam izejas	
	DDRB|=(1<<PB0)|(1<<PB1);	//P1,P2=output
	PORTB&=~(1<<PB1);			//ledon (0=on)
	PORTB&=~(1<<PB0);			//motor off
	
	TIMSK=(1<<OCIE2)|(1<<TOIE0); //T2 Output CMP IntEnbl.+ T1 OvrFlw IntEn.
	TCCR0=(1<<CS02); // '1,0,0' = clk/256 -> Iesledzam T1.
	sei(); //iesl. int.
	for(;;){}
}
//4 Mhz internal RC: CKSEL3..0=0011
```

 AVR Studio Simulatorā viss šķiet, iet kā vajag (tikai baigi lēnu - 2 sekunžu darbība izpildās kādu minūti vaivairāk), bet ja skatās Stop Watch taiming'u tur viss klusē).
Jāpamēģina oscilis līdz kompim kautkā dabūt...

----------


## tvdx

ja tumshi tad vel ok... kad buus balti/zalji vai citaadi gaishi tad gan kvarcs buus saplaisaajis

----------


## ansius

a kur tev stack inicializaacija? es pats uz taa uzraavos, pats gan asm njemos, un avr uz shitaa uzraavos, vis bija ok kaa nesaaku apakshprogrammas lietot.

----------


## cobalt

Es pieņemu ka iekš C stack inicializāciju nevajag, vismaz uz teksas instruments uC. Jo tādā gadījumā arī varētu prasīt kur tiek push'oti un popoti visi reģistri un organizēta atgriešanās no interaptiem.

A vispār viņiem takš nevajag nekādu return?  ::

----------


## Epis

> Es pieņemu ka iekš C stack inicializāciju nevajag,


 kautkur jau jābūt kautkādām C kodam,(jo rakstot softu asmā stacku Ram adresi vaig uzstādīt), vienīgi vai tas ir iekodēts kādā C, asm biblotekas failā vai pašm jākodē kā kodējot asmā.
kodējot  cortex-m3  ar c es nekādus stack neinicializēju.

----------


## cobalt

Principā bakstoties ar iebūvēto oscilatoru dabūju diezgan pieņemamu darbošanos, un liekas ka vairs nevienu no iepriekšējām problēmām nenovēroju.
Ar ārējo arī normāli iet. 

Liekas ka visa problēma bija defektīvā servo, un nepareizā LED vadības rindiņā, kas pietiekami veiksmīgi jauca tālāko problēmas meklēšanu.
Tā iet ar lētajiem ķīniešiem. Plastmasas krustiņš kas grozīja atgriezeniskās saites poci vairs īpaši labi nesaķērās ar metāla asi uz kuras tas bija, līdz ar to motors plecu grieza nepārtraukti cenšoties potenciometru dabūt vajadzīgajā pozīcijā.
Ar otru servo viss smuki strādāja.

Kāda jums vispār pieredze ar servomotoriem? Kādus iesakat.

Nesvarīgās operācijas pārnesu otrajā interupt'ā, lai nebojātu timing'u.


```
#include <inttypes.h>
#include "avr/io.h"
#include "avr/iom8.h"
#include "avr/interrupt.h"
#include "avr/wdt.h"

#define msmax 250 //2. taimera vertiba, pie izveleta dalitaja, sasniedzot 2 ms.
#define msmin 125 //0%
#define msmid msmin+63  //~50%

unsigned char D=msmid; //D=63 ~ 1/2 
char dir=1;

ISR(TIMER0_OVF_vect)
{
	PORTB|=(1<<PB0);
	OCR2=D;
	SFIOR|=(1<<PSR2); //T2 prescaler reset
	TIMSK|=(1<<OCIE2);
	TCCR2|=(1<<WGM21)|(1<<CS21)|(1<<CS20); //T2 on + clk/32
}

ISR(TIMER2_COMP_vect)
{
	
	PORTB&=~(1<<PB0);
	TCCR2=0x00;
	TIMSK&=~(1<<OCIE2);
	D=D+dir;
	if(D==msmax||D==msmin) {dir=-dir; PORTB^=(1<<PB1);}
}

int main(void)
{
	wdt_disable(); //izsledzam watchdog taimeri.
	//Saslēdzam izejas	
	DDRB|=(1<<PB0)|(1<<PB1);	//P1,P2=output
	PORTB&=~(1<<PB1);			//ledon (0=on)
	PORTB&=~(1<<PB0);			//motor off
	
	TIMSK=(1<<TOIE0); // T1 OvrFlw IntEn.
	TCCR0=(1<<CS02); // '1,0,0' = clk/256 -> Iesledzam T1.
	sei(); //iesl. int.
	for(;;){}
}
```

 Paldies, par vērtīgajiem padomiem.

----------


## ansius

> Es pieņemu ka iekš C stack inicializāciju nevajag, vismaz uz teksas instruments uC. Jo tādā gadījumā arī varētu prasīt kur tiek push'oti un popoti visi reģistri un organizēta atgriešanās no interaptiem.
> A vispār viņiem takš nevajag nekādu return?


 runa ir par AVR (Atmel) nevis TI un  stack vajag inicalizeet, ja vien pats kaut kadaa veidaa nenodarbojies ar taa menedzeeshanu, taa ir visi tik grib augstaaka limenja prgrameshanas valodas programeet a dzdelzi taa kartiigi neiepaziist un tad briinaas ka gljuko.

----------


## Velko

Nu vispār jau AVR-Libc (tas pats, kas nāk iekš WinAVR) steku inicializē pats. Koda sākumā smuki linkojas crtm8.o failiņš kurš izdara visu melno darbu, pirms izsaukt main().

----------


## cobalt

> Es pieņemu ka iekš C stack inicializāciju nevajag, vismaz uz teksas instruments uC. Jo tādā gadījumā arī varētu prasīt kur tiek push'oti un popoti visi reģistri un organizēta atgriešanās no interaptiem.
> A vispār viņiem takš nevajag nekādu return? 
> 
> 
>  runa ir par AVR (Atmel) nevis TI un  stack vajag inicalizeet, ja vien pats kaut kadaa veidaa nenodarbojies ar taa menedzeeshanu, taa ir visi tik grib augstaaka limenja prgrameshanas valodas programeet a dzdelzi taa kartiigi neiepaziist un tad briinaas ka gljuko.


 Kā C valodā tu to steku inicializē?
Iekš ASM'a es atceros, ka viņu inicializēt vajadzēja. Tur gan tas arī diezgan loģiski iekļāvās pārējā kodā, pretēji C kur daudz kas notiek savādāk.
Bet principā jau teicu kur bija vaina. Liekas arī ka šim te AVR WatchDog nevajag izslēgt (jau ir izslēgts pēc noklusējuma).

P.S. Es nejaucu T.I. un AVR, pirmo es minēju, kā piemēru kam arī rakstot C valodā tiešām nekādu steka inicializāciju nevajadzēja.

----------

