Úprava programu v jazyce C

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
procesor
Příspěvky: 5286
Registrován: 02 říj 2009, 00:00
Bydliště: PO

#16 Příspěvek od procesor »

:roll: Ty chceš aby to robilo niečo iné ako je v ponúkanom projekte. Bez zmeny programu sa dá modifikovať akurát tak výška a farba segmentoviek :D
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#17 Příspěvek od Michaell0071 »

No jde mi hlavně o to, aby narozdíl od zmiňovaného projektu viz. na té stránce pandatron.cz se na těch přidaných displejích zobrazovali setiny popřípadě tisíciny. Jelikož v tom původním projektu pro zobrazení při hodnotě nad 100 [mm] zbývá jen jedna sedmi-segmentovka a to je pro zobrazení desetiny milimetru. Jenže tato přesnost se nedá použít v praxi. Proto to rozšíření displeje. Ten lin. kodér AS5311 zvládne přesnost při použití A+B signálu 1,95 um. Tato přesnost by se dala využít díky těm čtyřem novým displejím. Zobrazovala by se hodnota např.: 240,00195 mm
Vy jste tím schématem pro zapojení nových čtyřech displejů pomocí 74xx138 vyřešil elektronickou (hardwarovou) stránku, správně?? Teď je ale teda potřeba upravit ten program aby dokázal ty nové displeje obsloužit. Je tomu tak??
Děkuji Vám.
Uživatelský avatar
procesor
Příspěvky: 5286
Registrován: 02 říj 2009, 00:00
Bydliště: PO

#18 Příspěvek od procesor »

Asi tak. Aj keď s použitím 28 pinových PIC by to isté by sa dalo dosiahnuť aj bez toho obvodu 74xx138, prípadne zmenou protokolu komunikácie až na rozlíšenie pod 1 mikrometer. Otázne je kde vziať taký dlhý a presný "magnetic strip" pre ten obvod.
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#19 Příspěvek od Michaell0071 »

Tak buď to nechápu nebo nevím. Ty magentické pásky lze koupit u té firmy Spezial electronic i s těmi lineárními kodéry AS5311 ustřihnou Vám tam kolik budete chtít třeba tři metry a samotná páska je pro to vyrobená, tak musí být asi přesná, taky metr stojí kolem 1000 Kč. Psal jsem i mail na ten pandatron.cz a tam mi odpověděli, že by to nebyl problém ten program upravit, ale z kapacitních důvodů takové služby neposkytují.
Jestli chápu správně je to teď jenom otázka software hardware je již vyřešeno, popřípadě by se použil větší PIC.
Nestačilo by tam jenom přidat pár řádek kódu? s tím programem se zas nemusí moc šachovat, nebo je to snad otázka předělání téměř celého toho programu??. Jak říkám programovat neumím, tak nevím co si pod tím představit.
Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 00:00
Kontaktovat uživatele:

#20 Příspěvek od piitr »

Zkusil jsem upravit dva soubory, aby to fungovalo podle procesorova zapojení. Jestli to je dobře, nevím.

displ.c:

Kód: Vybrat vše

#include "global.h"

unsigned long DisplVal;



/* ==========================================================================
   diplay init
*/
void displ_init (void) {
  DISPLC_TRIS &= ~DISPLC_MASK;
  DISPLC_PORT |= DISPLC_MASK;

  DISPLA_TRIS &= ~DISPLA_MASK;
  DISPLA_PORT |= DISPLA_MASK;
}



/* ==========================================================================
   diplay refresh
*/
void displ_refresh (void) {
  unsigned char x;
  unsigned long s;

  x = DisplVal / 10000000UL;
  if(x > 9) {
    DisplVal = 0;
    x = 0;
  }
   displ_write(x, 8, 0);

   s = DisplVal - (unsigned long)x * 10000000UL;
   x = s / 1000000UL;
   displ_write(x, 7, 0);

   s = DisplVal - (unsigned long)x * 1000000UL;
   x = s / 100000UL;
   displ_write(x, 6, 0);

   s = DisplVal - (unsigned long)x * 100000UL;
   x = s / 10000UL;
   displ_write(x, 5, 0);

   s = DisplVal - (unsigned long)x * 10000UL;
   x = s / 1000UL;
   displ_write(x, 4, 1);

   s = DisplVal - (unsigned long)x * 1000UL;
   x = s / 100UL;
   displ_write(x, 3, 0);

   s = DisplVal - (unsigned long)x * 100UL;
   x = s / 10UL;
   displ_write(x, 2, 0);

   s = DisplVal - (unsigned long)x * 10UL;
   x = s / 1UL;
   displ_write(x, 1, 0);
}



/* ==========================================================================
   diplay write
*/
void displ_write (unsigned char value, unsigned char disp, unsigned char dp) {
  DISPLC_PORT |= DISPLC_MASK;
  switch (value) {
    case 0:
      DISPLC_PORT = ~DIS0;
    break;
    case 1:
      DISPLC_PORT = ~DIS1;
    break;
    case 2:
      DISPLC_PORT = ~DIS2;
    break;
    case 3:
      DISPLC_PORT = ~DIS3;
    break;
    case 4:
      DISPLC_PORT = ~DIS4;
    break;
    case 5:
      DISPLC_PORT = ~DIS5;
    break;
    case 6:
      DISPLC_PORT = ~DIS6;
    break;
    case 7:
      DISPLC_PORT = ~DIS7;
    break;
    case 8:
      DISPLC_PORT = ~DIS8;
    break;
    case 9:
      DISPLC_PORT = ~DIS9;
    break;

  }

  switch (disp) {
    case 1:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA1_PORT &= ~DISPLA1_MASK;
      delay_dip(50);
      DISPLA1_PORT |= DISPLA1_MASK;
    break;

    case 2:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA2_PORT &= ~DISPLA2_MASK;
      delay_dip(50);
      DISPLA2_PORT |= DISPLA2_MASK;
    break;

    case 3:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA3_PORT &= ~DISPLA3_MASK;
      delay_dip(50);
      DISPLA3_PORT |= DISPLA3_MASK;
    break;

    case 4:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA4_PORT &= ~DISPLA4_MASK;
      delay_dip(50);
      DISPLA4_PORT |= DISPLA4_MASK;
    break;

    case 5:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA5_PORT &= ~DISPLA5_MASK;
      delay_dip(50);
      DISPLA5_PORT |= DISPLA5_MASK;
    break;

    case 6:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA6_PORT &= ~DISPLA6_MASK;
      delay_dip(50);
      DISPLA6_PORT |= DISPLA6_MASK;
    break;

    case 7:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA7_PORT &= ~DISPLA7_MASK;
      delay_dip(50);
      DISPLA7_PORT |= DISPLA7_MASK;
    break;

    case 8:
      if(dp) DISPLC_PORT &= ~DISDP;
      DISPLA8_PORT &= ~DISPLA8_MASK;
      delay_dip(50);
      DISPLA8_PORT |= DISPLA8_MASK;
    break;
  }
}



/* ==========================================================================
   delay
*/
void delay_dip (volatile unsigned int value) {
  while(value--);
}


displ.h:

Kód: Vybrat vše

#ifndef displH
#define displH

extern unsigned long DisplVal;

/* CONSTANT */
#define DISPLC_TRIS TRISB
#define DISPLC_PORT PORTB
#define DISPLC_MASK 0xFF

#define DISPLA_TRIS TRISA
#define DISPLA_PORT PORTA
#define DISPLA_MASK 0xC3

#define DISPLA1_PORT PORTA
#define DISPLA1_MASK 0xC3

#define DISPLA2_PORT PORTA
#define DISPLA2_MASK 0xC2

#define DISPLA3_PORT PORTA
#define DISPLA3_MASK 0xC1

#define DISPLA4_PORT PORTA
#define DISPLA4_MASK 0xC0

#define DISPLA5_PORT PORTA
#define DISPLA5_MASK 0x83

#define DISPLA6_PORT PORTA
#define DISPLA6_MASK 0x82

#define DISPLA7_PORT PORTA
#define DISPLA7_MASK 0x81

#define DISPLA8_PORT PORTA
#define DISPLA8_MASK 0x80

#define DISPLCA_PORT PORTB
#define DISPLCA_MASK 0x40

#define DISPLCB_PORT PORTB
#define DISPLCB_MASK 0x80

#define DISPLCC_PORT PORTB
#define DISPLCC_MASK 0x02

#define DISPLCD_PORT PORTB
#define DISPLCD_MASK 0x04

#define DISPLCE_PORT PORTB
#define DISPLCE_MASK 0x08

#define DISPLCF_PORT PORTB
#define DISPLCF_MASK 0x20

#define DISPLCG_PORT PORTB
#define DISPLCG_MASK 0x10


#define TLACL_PORT PORTA                              /* CLEAR button */
#define TLACL_MASK 0x20

#define TLAHL_PORT PORTA                              /* HOLD button */
#define TLAHL_MASK 0x10


#define DIS0 0xFA
#define DIS1 0x82
#define DIS2 0xB9
#define DIS3 0xAB
#define DIS4 0xC3
#define DIS5 0x6B
#define DIS6 0x7B
#define DIS7 0xA2
#define DIS8 0xFB
#define DIS9 0xEB
#define DISDP 0x04


// FUNCTION
void displ_init (void);
void displ_refresh (void);

void displ_write (unsigned char value, unsigned char disp, unsigned char dp);
void delay_dip (volatile unsigned int value);


#endif
Uživatelský avatar
mtajovsky
Příspěvky: 3728
Registrován: 19 zář 2007, 00:00
Bydliště: Praha

#21 Příspěvek od mtajovsky »

Co tu displ_write() napsat takto:

Kód: Vybrat vše

void displ_write(unsigned char value, unsigned char disp, unsigned char dp)
{
static unsigned char dis[10] =
{~DIS0, ~DIS1, ~DIS2, ~DIS3, ~DIS4,
  ~DIS5, ~DIS6, ~DIS7, ~DIS8, ~DIS9};

  DISPLC_PORT |= DISPLC_MASK;
  DISPLC_PORT = dis[value];

.
.
.
}


a z druhého switche "vytknout před závorku"

Kód: Vybrat vše

if(dp) DISPLC_PORT &= ~DISDP;


a pak s ním provést to samé co s prvním?
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#22 Příspěvek od Michaell0071 »

Rád bych k tomu něco dodal, ale mně to nic něříká, budu to muset nechat na odbornících co tomu rozumí. :)
Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 00:00
Kontaktovat uživatele:

#23 Příspěvek od piitr »

No, já vím. Nějak tak by se to dalo určitě přepsat. Mě z toho taky bolí oči. Jenže nemám ten překladač ani nic, abych to mohl ladit, takže jsem se do toho nepouštěl. A přijde mi to skoro škoda práce. Ono je to celé psané poněkud idiotsky, to by se to muselo předělat z gruntu.

Jinak, asi tam vypadl ampersand, že jo?

Kód: Vybrat vše

DISPLC_PORT &= dis[value];

Ale asi by to fungovalo i bez něj.
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#24 Příspěvek od Michaell0071 »

pittr, procesor: DĚKUJI VÁM moc za snahu mi pomoci. Takto přepsaný software by měl zobrazovat naměřené hodnoty jak jsem se výše ptal??
Uživatelský avatar
procesor
Příspěvky: 5286
Registrován: 02 říj 2009, 00:00
Bydliště: PO

#25 Příspěvek od procesor »

A zmeniť konštantu ONEPULSEUS z 25 na 1/512.

Možno sa mi to len zdá, ale počas HOLD sa asi budú strácať inkrementy...neviem.

Zobrazovanie bude také, neviem či v tých zmenách od piitr je rozsvietenie desatinnej bodky, ale to nie je určite problé.
Naposledy upravil(a) procesor dne 31 kvě 2012, 21:48, celkem upraveno 1 x.
Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 00:00
Kontaktovat uživatele:

#26 Příspěvek od piitr »

No, já jsem jen předělal tu funkci pro displej, takže by snad mohla zobrazovat větší čísla přesněji pomocí toho upraveného zapojení.
Na zbytek programu jsem nekoukal, takže tam možná může být ještě nějaký jiný zádrhel. Taky jsem neřešil tu záměnu snímačů. Prostě zkus a uvidíš. Mně se to nechce moc detailně studovat.
Uživatelský avatar
procesor
Příspěvky: 5286
Registrován: 02 říj 2009, 00:00
Bydliště: PO

#27 Příspěvek od procesor »

V pôvodnom programe sa inkrementuje +/- o 25 um. Ten novší má tú hodnotu 1,953125 um. Tá hodnota je definovaná v AS5304.h

Bodka je v tom "displ_write(hodnota, pozícia, dotp), ale to sú detaily. Ten program je ľahko modifikovateľný ..takto je na 9999.9999 a jenoducho sa dá zmeniť na 999.99999
Len aby to do toho PICu vošlo.

Mohol by to niekto skusmo preložiť, či sa to do 16F628A vojde, riešením by bolo to potom napchať do 16F648A ..ten je rovnaký iba s väčšou pamäťou iba neviem či je bežne dostupný. 628 je "populárny. :)
Naposledy upravil(a) procesor dne 31 kvě 2012, 22:28, celkem upraveno 1 x.
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#28 Příspěvek od Michaell0071 »

Mohl bych se taky přidat k prosbě, jestli by to někdo zkusil přeložit jestli se to do toho PIC-ku vleze?? Ta změna z 25um na 1,95 um se něco řešilo i tu: http://www.mojehobby.cz/diskuze/strom2.php?idforum=17&potec=1236928 Tam stačí změnit 25 na 1,95 nebo napsat celé číslo tedy 1,953125 ? Děkuji VÁM
Uživatelský avatar
procesor
Příspěvky: 5286
Registrován: 02 říj 2009, 00:00
Bydliště: PO

#29 Příspěvek od procesor »

Musí to byť 1,953125. Inak skutočný 1m by mal 1001,6mm.
Problém bude so zápisom tej konštanty, lebo to nie je celé číslo. Takže treba zmeniť niečo, aby sa používala hodnota 1953125 a patrične zmeniť konštanty delenia pri výpočte číslic displaya.
Keďže nie som céčkar neviem či na to číslo bude k dispozícii taká "dlhá definícia" 64bitov. Potom sa mi nepáči, že zobrazovaná hodnota je bez znamienka (unsigned)
Naposledy upravil(a) procesor dne 31 kvě 2012, 22:59, celkem upraveno 1 x.
Uživatelský avatar
Michaell0071
Příspěvky: 132
Registrován: 09 říj 2010, 00:00

#30 Příspěvek od Michaell0071 »

Šel by ten upravený program zkusit na nějakém simulátoru?? Jestli by to fungovalo?.
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“