www.elektronik.si
Začetniški problem v C-ju pri AVR-ju
Pojdi na stran Prejšnja  1, 2, 3 ... , 25, 26, 27  Naslednja  :||:
www.elektronik.si -> Osnove programiranja AVR-jev

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sob Nov 26, 2016 9:12 am    Naslov sporočila:  
----------------------------------------------------------------------------
To je copy/paste iz mojega programa:
Koda:
#include <avr\io.h>
#include <avr\interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdio.h>
#include "lcd_lib.c"
#include "twi.c"
#include "definicije.h"
//#include "nrf24l01.c"
//#include "spi.c"


Tisti z <> so datoteke nekje v Atmelovem oz. WinAvr jevih direktorijih, tisti z " " pa so v mapi, kjer imam trenutni projekt.
Pa poskusi pisat datoteke brez dvojnih pik : lcd.lib.c ampak malo drugače, npr lcd_lib.c (ali pa s končnico .h)

Avtor: integrercKraj: Novo mesto PrispevekObjavljeno: Sob Nov 26, 2016 11:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Bom upošteval napisano lojzek.
Vprašal bi še, kakšen programator naj uporabim?
Do sedaj sem uporabljal Proggy od Svet elektronike, vendar pa mi v AVR studio 6 ne deluje.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Feb 25, 2020 9:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni,

Sedaj se mučim z eno težavico, ki jo sicer znam rešiti z nekaj if () stavki, ampak mislim da se da to lepše rešiti z XOR, vendar mi rešitev noče v glavo.

Torej, v enem bajtu imam dva bita, za katera me zanima, če sta enaka (oba 0 ali oba 1 - vrne recimo 1) ali različna - vrne recimo 0.

primeri- vsaka vrstica me zanima primerjava z "x" označenih bitov:
Koda:


   xx 
00011000 == 1
00000000 == 1
00010000 == 0
00001000 ==0


Gre se pa za priklop malega enkoderja, da bi ugotovil smer.

moj primer, ki me muči:
Koda:
SIGNAL (INT1_vect)
{   
//bitno preverjanje bitov enkoderja
   //Enaka == ena smer, različna == druga smer

if (PIND & (1 << PD3) ^ PIND & (1 << PD4))
   ++Gor;
   else ++Dol;
}

Avtor: SilvoKraj: Koroška-okolica Dravograda PrispevekObjavljeno: Tor Feb 25, 2020 9:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Citiram:
Gre se pa za priklop malega enkoderja, da bi ugotovil smer.


V C-ju ti ne znam pomagat. V assemblerju jaz naredim tako da "eno sled" enkoderja dam na pin zunanje prekinitve. Recimo, da se prekinitev sproži ob padajoči fronti. V prekinitveni rutini pa preverjam stanje drugega vhoda. Visoko stanje ena smer nizko stanje druga smer.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Tor Feb 25, 2020 10:21 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja, saj tako sem imel pri prejšnjem enkoderju.
Je bil očitno drugačen - ker je vgrajen in v uporabi, pa ne morem preverit. In njegov "program" je lepo deloval.

Ta pa ima pri zasuku enkoderja za en zob levo najprej spremembo izhoda A na 1, ki ji sledi B na 1. Pri drugem zobu vrtenja v levo pa se A spremeni na 0 in ji sledi B na 0.
Tako jih moram preverjat pri "enkah" ki jim sledijo enke, in "nulah" ki jim sledijo nule. Drugače moraš za spremembo dveh številk zavrteti za 4 zobce.

Mislil sem na XOR, kajti obe enaki vrednosti bitov pomenita eno smer, različni pa drugo.

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Tor Feb 25, 2020 11:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Naredi nasko ki ima oba bita na 1 in potem rezultat registra primerjaj z masko.

If ((register & maska) == maska)

Nastavi masko na oba bita 1 in boš vedel kdaj sta oba na 1.

Avtor: SilvoKraj: Koroška-okolica Dravograda PrispevekObjavljeno: Tor Feb 25, 2020 11:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Vsi enkoderji - tudi industrijski (vsaj tiste, ki jih poznam) imajo sled A in B zamaknjeno za 90° industrijski imajo običajno še sled "Z" ter vse signale tudi negirane.
Za določetev smeri vrtenja pač vzameš eno sled in jo primerjaš z drugo v trenutku, ko se ta spremeni torej če je pri dvigajoči fronti stanje visoko pri padajoči pa nizko se je zavrtelo za en "zob" v eno stran, če je stanje pri dvigajoči enako padajoči se je ostalo na istem mestu enako gre za drugo stran.
Tukaj je lepa simulacija.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 11:47 am    Naslov sporočila:  
----------------------------------------------------------------------------
@tilzor: to bom pa poskusil, ker tak primer mislim da je večkrat uporaben. Vse take uporabne stvari si po preizkusu zapišem in kasneje laže najdem. Take enostavne rešitve včasih človek niti ne opazi.

@Silvo, tisto simulacijo na Wikiju sem že videl. In moj tudi dela tako, če ga preizkusim z lučkami.

Nekako sem pa tudi slutil, da me malo debouncing heca. Sem ga hotel kasneje reševati.
Zato sem se pa lotil "kopanja" po načrtih naprave, kjer do sedaj uporabljam prvi in edini enkoder Ter videl, da imam hardverski debouncing (R+C). Ta ploščica, ki sem jo kupil ima pa samo pullup upore. Torej najprej hardver urediti, nato pa naprej. Mogoče bo že preizkušena rešitev delovala.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 11:57 am    Naslov sporočila:  
----------------------------------------------------------------------------
Evo, tule je delujoča koda in delujoča shema. Samo ne vem, katero verzijo sem (že) uporabil.... Think
Koda:
//prekinitev - vrtenje enkoderja
SIGNAL (INT1_vect)
{
if (PIND & (1 << PD4))
   ++Gor;
   else ++Dol;
Neaktiv = 0;
}

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Sre Feb 26, 2020 2:33 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Rešitev... Najprej hardverski debounce, potem je koda prejšnjega posta začela delat. Sprememba števca na vsak drugi zobec (res imam prejšnji enkoder drugačen Think )
Zanjo je bila prekinitev INT1 nastavljena na padajoči rob signala...


Tole je pa nova delujoča koda:

Koda:
//prekinitev - vrtenje enkoderja
SIGNAL (INT1_vect)
{   
if (!(PIND & (1 << PD3)) && PIND & (1 << PD4) || PIND & (1 << PD3) && !(PIND & (1 << PD4)))
   ++Gor;
   else  ++Dol;
Neaktiv = 0;
}


Zanjo je treba pa nastaviti PinChange interupt na INT1

Samo nisem imel 10n kondijev, pa sem dal 100n. in ne moreš vrteti prehitro Smile debounce premočan... bom to uredil

Hvala za debato in pomoč.

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Dec 07, 2020 9:31 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljeni,

Ni sicer začetniški problem, je pa C problem.

Imam ta izsek kode:
Koda:
int Read_Temp_Sub (uint16_t adresa, int16_t OldTemp)
{
unsigned char i,j, counter = 0;
int b = 0;
unsigned char scratchpad [9];
unsigned char shift,tip, fb, crc = 0;

if (DS_init ())
{
do   {      // temperatura
   DS_init ();
   DS_write_byte (DS_MatchRom);
   for (uint8_t a=0; a < 8; a++)
      {
      DS_write_byte (EEPROM_Read_char (adresa + a));
      }
   DS_write_byte (DS_ReadScratchpad);   //read scratshpad

//for (uint8_t s = 0; s < 9 s++)
//{   scratchpad [s] = DS_read_byte ();   } //preberi cel scratchpad

   scratchpad[0] = DS_read_byte ();   //Preberi LSB
   scratchpad[1] = DS_read_byte ();   //Preberi MSB
   scratchpad[2] = DS_read_byte ();   //Preberi MSB
   scratchpad[3] = DS_read_byte ();   //Preberi MSB
   scratchpad[4] = DS_read_byte ();   //Preberi MSB
   scratchpad[5] = DS_read_byte ();   //Preberi MSB
   scratchpad[6] = DS_read_byte ();   //Preberi MSB
   scratchpad[7] = DS_read_byte ();   //Preberi MSB
   scratchpad[8] = DS_read_byte ();   //Preberi MSB


Problem je v tistem, kar je komentirano (for zanka + 8 krat branje byta it DS semzorja)
Taka koda v cca 18 - 21 sekundah pripelje do ponovnega zagona programa (reset).

Če pa uporabim kodo, ki v vsaki vrstici prebere en podatek, pa ne pride do reseta. Tisti del, ki je prikazan pod for zanko.

Kaj je torej tista razlika, kaj sem spregledal Think . Dodatno lahko še rečem, da takšna for zanka v drugem programu dela b.p.

Pa še toliko, sicer imam Watchdog reset nastavljen na 4 sekunde, Ta (najverjetneje) ni vzrok, ker mi čas na LCD lepo izpisuje vsako sekundo...

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Dec 07, 2020 9:40 am    Naslov sporočila:  
----------------------------------------------------------------------------
Razen tega, da ti manjka podpičje za pogojem pri for zanki, ne vidim druge težave.

Nazadnje urejal/a tilz0R Pon Dec 07, 2020 1:44 pm; skupaj popravljeno 1 krat

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Dec 07, 2020 12:59 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Za pogojem oz. za for zanko se ne da podpičja...

Avtor: tilz0RKraj: Črnomelj PrispevekObjavljeno: Pon Dec 07, 2020 1:43 pm    Naslov sporočila:  
----------------------------------------------------------------------------
lojzek je napisal/a:
Za pogojem oz. za for zanko se ne da podpičja...


Brez zamere, a si vstrelil mimo.
Tvoja koda se sploh ne sme prevesti.

Koda:

for (uint8_t s = 0; s < 9; ++s) {
     scratchpad [s] = DS_read_byte ();
}

Avtor: lojzekKraj: Koroška Bela PrispevekObjavljeno: Pon Dec 07, 2020 3:05 pm    Naslov sporočila:  
----------------------------------------------------------------------------
UUUU vidim, podpičje v oklepaju manjka.... Typo. Jaz sem domneval, da hočeš podpičje za navadnim zaklepajem for zanke...

Ampak ne moreš verjeti, prevede se, pa dela tudi (nekaj časa Smile )

Saj je kompiler verjetno pojamral (Warning), ampak sem spregledal. Ponavadi mi veliko warningov vrže ven pri izpisu na LCD. To bo naslednje vprašanje, ko ga pripravim. Da se jih rešim, se vlečejo že od začetka mojega programiranja. Tako pa sedaj lahko tudi kaj pomembnega spregledaš.

Stran 26 od 27

Powered by phpBB © 2001,2002 phpBB Group