ARM YAGARTO and Eclipse Project

Cortex. ARM3, ARM5, ARM7 magok, mindenféle gyártóktól. Programozás-fejlesztés-tippek.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Gyors Port kezelés! De Hogyan?

Macsek köszi az okítást !
Ez a kiszínezés nagyon bejött! :)

Látom, nagyon vágod a C-t, meg van türelmed ilyen kiselefántokhoz!
Ezért bátorkodom új témát felhozni.

1 Port megosztott Output/Input vezérlést kellene megoldani.

Bár amivel küzdök az 16 Bites ARM Port amiből 8 Bits lenne az LCD adat vonal.
Valahol a 0 – 15 Bitek területén, ahova éppen be lehet szorítani, mert itt is több funkciója lehet 1 lábnak.

A Bitenkénti írás az menne, de 8 Bitre túl lassú módszer.

Szóval, hogyan lehetne ezt gyorsan 1 I/O művelettel megoldani, hogy a többi Biten lógó perifériákat ne zavarja?

(Tudom, első C projectnek grafikus LCD nagy Fa, csorbul a Fejsze!)

De lehet Arduinos példa is, hisz az is C.
Mondjuk:
1 Portból 4 Bits az LCD adat vonala a fennmaradó 4 Bits a Vezérlő jelek.
Az Első 4-et egybe kezelnénk <- (erre kellene valami Struktúra), a második 4-et külön-külön.

Ha valakinek van jó tippje meg köszönöm!


:)
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

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

Portállapot visszaolvasása.
A neked kellő 4 bitre egy AND maszkolás, hogy 0 legyen.
Neked kellő 4 bit beállítása.
Ennek visszaírása a kimenetre...

Példa, a felső 4 bitet bizgerálod:
1010.1110 - Beolvasott adat
1010.1110 AND 0000.1111 = 0000.1110
Beállítandó: 0101 bitsor
0101.0000 OR 0000.1110 = 0101.1110
Portkiírás:0101.1110
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Köszönöm! Alakul!

Bár a probléma ennél bonyolultabb. Ezért gabalyodtam bele!

Vagyis Nem fix hova kerül a Bit csoportunk. Ahova éppen a HW alkalmazás megengedi.
A maszkolást hogyan lehet a bekötéshez igazítani?
:?:

A Nagyok így varázsoltak:

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

/**
  * @brief General Purpose I/O
  */

typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint16_t BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  __IO uint16_t BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;


/**
  * @brief  Reads the specified GPIO input data port.
  * @param  GPIOx: where x can be (A..I) to select the GPIO peripheral.
  * @retval GPIO input data port value.
  */
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return ((uint16_t)GPIOx->IDR);
}

/**
  * @brief  Writes data to the specified GPIO data port.
  * @param  GPIOx: where x can be (A..I) to select the GPIO peripheral.
  * @param  PortVal: specifies the value to be written to the port output data register.
  * @retval None
  */
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  GPIOx->ODR = PortVal;
}

Ebből a Struct ból kellene a:

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

  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
Sorokat kiemelni és tovább bontani 8-as Bit csoportra.
:?
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Szerintetek a második sorrotálás is jó?

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

__IO uint16_t glcd_address;

	glcd_address = (glcd_address >> 8);
	glcd_address >>= 8;
:?:
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

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

kapu48 írta:Szerintetek a második sorrotálás is jó?

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

__IO uint16_t glcd_address;

	glcd_address = (glcd_address >> 8);
	glcd_address >>= 8;
:?:
sztem igen
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

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

kapu48 írta:Szerintetek a második sorrotálás is jó?

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

__IO uint16_t glcd_address;

	glcd_address = (glcd_address >> 8);
	glcd_address >>= 8;
:?:
igen, tényleg jó, itt a félhivatalos helyeslés:
http://en.wikipedia.org/wiki/C_(program ... #Operators
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

tovább bontani 8-as Bit csoportra

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

kapu48 írta: Ebből a Struct ból kellene a:

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

  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
Sorokat kiemelni és tovább bontani 8-as Bit csoportra.
:?
Nem igazán értem mit akarsz, mert ott az egyik rutin, ami egy GPIO_TypeDef pointer által mutatott struktúrán valamit ellenőriz majd visszaadja neked a 32 bites IDR értéket.
Van egy másik rutinod, ami egy ugyanilyen pointer által mutatott struktúra ODR mezejébe beírja a paraméterként megkapott értéket, szintén némi ellenőrzés után. (Mondjuk az nem világos, h mit csinál ha nem megy át a paraméter ellenőrzésen az adat.)

Ezek szépen, kultúráltan, sőt fölkommentezve megvannak.
A 32 bites érték szétszedése/összerakása a kérdés?

Ha igen, azt többféleképp megteheted:
Pl. parasztosan, típuskényszerrel:

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

unsigned char b0, b1, b2, b3;

b0 = (char *)GPIOx->IDR[0];
b1 = (char *)GPIOx->IDR[1];
b2 = (char *)GPIOx->IDR[2];
b3 = (char *)GPIOx->IDR[3];

vagy bitmaszkolással:

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

unsigned char b0, b1, b2, b3;

b0 = GPIOx->IDR & 0xff;
b1 = GPIOx->IDR>>8 & 0xff;
b2 = GPIOx->IDR>>16 & 0xff;
b3 = GPIOx->IDR>>24 & 0xff;
(Elvileg nem kell zárójelezni a (GPIOx->IDR)>>8 módon, az Operator Precedence Table szerint a pointer egyértelműen magasabb prioritású, mint a shiftelés )

Az összeszerelés egyik lehetséges megoldása:

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

unsigned char b0, b1, b2, b3;

PortVal = b3<<24 | b2<16 | b1<<8 | b0;
Ez volt a kérdés?
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Hú, ilyen sok lehetőség van a C-ben!

Ezt használom: Atollic TrueSTUDIO: http://www.atollic.com/index.php/truestudio
CPU doksi és program: STM32F40xVG: http://www.st.com/internet/mcu/product/252142.jsp

A fordító minden verziódat elfogadta!

Most már csak ki kel választanom melyik a jó nekem?

A D port 3. bitjétől olvasok 8 bitet: __IO uint8_t glcd_add = GPIOD->IDR<< 3 & 0xff;
A D port 3. bitjétől írok 8 bitet: GPIOD->ODR<< 3 & 0xff = glcd_add;
Vagy:
A D port 3. bitjétől olvasok 8 bitet: __IO uint8_t glcd_add = GPIOD->IDR<< (8+3) & 0xff;
A D port 3. bitjétől írok 8 bitet: GPIOD->ODR<< 8+3 & 0xff = glcd_add;
Melyik a jó?
A rotálás és maszkolás része még nem tiszta.
Mi kerül a változóba, vagy a portra?

És a fennmaradó Biteken a soros I/O-k vannak azokat így nem piszkáljuk?

És nagyon köszönöm a segítséget!

Dúrtam a fenti doksikat de ilyen frappáns megoldást nem találtam.

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

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

16 Bit széles I/O-ra akarok a 8 bitet 3 – 10 biteken forgalmazni úgy, hogy közben a többi Bits ne változzon!

Külön van input/output regiszter.

Részlet az adatlapból:
I / O port adatok nyilvántartása
Minden GPIO két 16-bites memória-térképezett adatnyilvántartások: input és output adatok nyilvántartása
(GPIOx_IDR és GPIOx_ODR).
GPIOx_ODR tárolja az adatokat a kimenetre, akkor az írási / olvasási hozzáférhető.

(GPIOx_IDR), Az adatbevitel keresztül az I / O tárolja az input adatok regisztrálj
(GPIOx_IDR), egy csak olvasható regiszter.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Végre találtam LCD-re mintát!

STM32F4-Discovery lcd 4*20
http://www.electro-tech-online.com/arm/ ... -20-a.html

Most már van valami elindulásnak.
:lol:
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

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

kapu48 írta:16 Bit széles I/O-ra akarok a 8 bitet 3 – 10 biteken forgalmazni úgy, hogy közben a többi Bits ne változzon!
Bocsi, de nagyon zavarja a szememet és úgy tűnik következetesen használod.
Magyarul 1 bit, 2 bit, 3 bit, 100 bit.
Olyan, h bits olyan csak angolul van.

Remélem nem sértettelek meg vele.
kapu48 írta: Külön van input/output regiszter.

Részlet az adatlapból:
I / O port adatok nyilvántartása
Minden GPIO két 16-bites memória-térképezett adatnyilvántartások: input és output adatok nyilvántartása
(GPIOx_IDR és GPIOx_ODR).
GPIOx_ODR tárolja az adatokat a kimenetre, akkor az írási / olvasási hozzáférhető.

(GPIOx_IDR), Az adatbevitel keresztül az I / O tárolja az input adatok regisztrálj
(GPIOx_IDR), egy csak olvasható regiszter.
Ez a furcsa magyarságú szöveg valami webes fordítóból jött? Azt hiszem többet érnénk az eredeti, angol nyelvű verzióval.

Bocsi, h most csak ilyen fikázósnak tűnő dolgokat írtam...

kapu48 írta: A fordító minden verziódat elfogadta!
Még szép :lol:
Nekem azt mondták az okosok, h legjobb ANSI C-t használni, akkor bármilyen fordítóra átválthatunk mégis működőképes lesz.
kapu48 írta: Most már csak ki kel választanom melyik a jó nekem?
Csúnya, ha azt mondom, h ezek közül egy sem?

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: A D port 3. bitjétől olvasok 8 bitet: __IO uint8_t glcd_add = GPIOD->IDR<< 3 & 0xff;
Mivel a bitenkénti és (&) magasabb precedenciájú, mint a shiftelés (<<), így először össze-és-eli a 3-mat és az FF-et, ami nem meglepő módon 3-mat ad eredményként, ennyi bittel eltolja az IDR értékét BALRA, azaz mexorozza 2^3 = 8-cal és ezt az értéket teszi bele a glcd_add nevű változódba, annak is a felső 5 bitjébe. Előtte azok a hettyenpittyek nem tudom mit csinálnak, talán szintaktikai hibát jeleznek, talán sorminták :twisted: (Azaz ide tök fölöslegesek, azok csak a változó deklarációnál kellenek.)

Esetleg ez lehet egy működő megoldás:

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

glcd_add = GPIOD->IDR & 0x7f8 >> 3;
Bár akkor már ez olvashatóbb:

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

glcd_add = (GPIOD->IDR >> 3) & 0xff;
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: A D port 3. bitjétől írok 8 bitet: GPIOD->ODR<< 3 & 0xff = glcd_add;
Ez már valamivel jobb, legalább jó irányba shiftel :)
Az & FF értelmetlen benne és szintaktikailag sem helyes.

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

GPIOD->ODR = (GPIOD->ODR & ~( 0xff << 3 )) | (glcd_add<<3);
~ bináris NOT, azaz minden bitet átfordít
0xff << 3 azt a 8 mező széles "ablakot" tolja be a helyére, tehát balra 3 bittel, ahová írni szeretnél
GPIOD->ODR & ~( 0xff << 3 ) az ODR eredeti tartalmából kitörli azt a 8 bitet, ahová írni fox, a többit maghagyja.
| bitenkéti OR, ez meg beteszi a kívánt 8 bitedet a helyére, megőrizvén az eredeti tartalmat.


*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: Vagy:
A D port 3. bitjétől olvasok 8 bitet: __IO uint8_t glcd_add = GPIOD->IDR<< (8+3) & 0xff;
Több helyen hibás. Magyarázatot és helyes verziót lásd följebb...

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: A D port 3. bitjétől írok 8 bitet: GPIOD->ODR<< 8+3 & 0xff = glcd_add;
Több helyen hibás. Magyarázatot és helyes verziót lásd följebb...

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: Melyik a jó?
Amiket én írtam :roll:
kapu48 írta: A rotálás és maszkolás része még nem tiszta.
Igazából ez nem rotálás, hanem shiftelés (bit-eltolás).
A rotálásnál a kimenő bitet visszatesszük a másik oldalra. Shiftelésnél 0-k kerülnek be (illetve attól függ, h aritmetikai vagy logikai shiftelés, mert megőrizheti az előjelbitet is, de most ezzel ne foglalkozz).

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
kapu48 írta: Mi kerül a változóba, vagy a portra?

És a fennmaradó Biteken a soros I/O-k vannak azokat így nem piszkáljuk?

És nagyon köszönöm a segítséget!

Dúrtam a fenti doksikat de ilyen frappáns megoldást nem találtam.
:D
Köszi :)

Ne izélgetésnek vedd, de SOKKAL jobban tudnál haladni ha valami C könyvön végigmennél és végig csinálnád a feladatokat.


ingyenes, online C kurzusok

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

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

Látom kiborult a bili, a buta kérdéseimtől!
De szokott ez így nálam is lenni.

1. A bits az angol többes szám > bitek.
2. Én meg az angol szövegből ne értek semmit, magamból indultam ki.
3. Mivel téged még nem ismerlek, legközelebb mellőzöm a buta fordítást!
4. Ez ARM-ra optimalizált __IO azt jelzi, hogy irható/olvasható a regiszter, változó. Mert van csak olvasható regiszter is __I
5. Szintén ARM: uint8_t 1 Bytes unsignetint. Azt hiszem ezt hivják char-nak a C-ben.

stm32f4xx.h

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

/** @addtogroup Exported_types
  * @{
  */  
/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
typedef int32_t  s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef const int32_t sc32;  /*!< Read Only */
typedef const int16_t sc16;  /*!< Read Only */
typedef const int8_t sc8;   /*!< Read Only */

typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;

typedef __I int32_t vsc32;  /*!< Read Only */
typedef __I int16_t vsc16;  /*!< Read Only */
typedef __I int8_t vsc8;   /*!< Read Only */

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef const uint32_t uc32;  /*!< Read Only */
typedef const uint16_t uc16;  /*!< Read Only */
typedef const uint8_t uc8;   /*!< Read Only */

typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;

typedef __I uint32_t vuc32;  /*!< Read Only */
typedef __I uint16_t vuc16;  /*!< Read Only */
typedef __I uint8_t vuc8;   /*!< Read Only */
........
Köszönöm azért sokat segítettél!

Könyveim vannak, de gyakorlatban hamarabb megértem.
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

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

kapu48 írta:Látom kiborult a bili, a buta kérdéseimtől!
nem erről van szó, csak tényleg úgy gondolom, h C alapozás után könnyebb dolgod lenne.
kapu48 írta: 1. A bits az angol többes szám > bitek.
Köszi, ez még megy angolul :lol:
kapu48 írta: 3. Mivel téged még nem ismerlek, legközelebb mellőzöm a buta fordítást!
persze, nem tud6tad, h értem az angol szaxöveget. Semmi gond
kapu48 írta: 4. Ez ARM-ra optimalizált __IO azt jelzi, hogy irható/olvasható a regiszter, változó. Mert van csak olvasható regiszter is __I
5. Szintén ARM: uint8_t 1 Bytes unsignetint. Azt hiszem ezt hivják char-nak a C-ben.
4. Ezzel nincs gond, (bár a konkrét jelentését nem ismertem), de az értékadásnál sztem akkor sem kellene.
5. Igen, kicsit pontosabban unsigned char-nak.
kapu48 írta: Köszönöm azért sokat segítettél!

Könyveim vannak, de gyakorlatban hamarabb megértem.
Szívesen.
A könyvek feladatait átnézve/megoldva biztos sokat lehet tanulni.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Mivel a C-ben mindent felül lehet definiálni, ezért meg is teszik.
Ha átmegyek másik cég oldalára, ugyan ezeknek a funkcióknak tök más a neve. És már semmit sem ér, amit tanultam.
Ezért van, hogy már te sem érted.

És mivel pl. 1300 oldal csak az STM32 pdf-je, ezt senki sem tanulja meg fejből.
:(
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Megtaláltam a könyvem.
C++ könyv: http://doksi.hu/get.php?lid=1051
(regisztrálni kel!)

Talán nem zavarlak több buta kérdéssel.
8)
Válasz küldése