Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   90 / 153
(#) Wudoou hozzászólása Feb 5, 2014 /
 
Sziasztok!
Kis segítséget kérnék PIC16f886 4x20 LCD projektben HITECH C fordító. Nem sikerül inicializálnom, gyanítom azért, mert ugyanazon a porton van a data és az en, rs is.
Szóval lábkiosztás:
LCD4-RB3
LCD5-RB2
LCD6-RB1
LCD7-RB0
LCD_RS-RB7
LCD_EN-RB6
LCD_BL-RB5
Ezek miatt módosítottam a kódomat a következőképpen:
  1. #define lcd_data PORTB
  2. #define lcd_rs RB7
  3. #define lcd_en RB6
  4. #define lcd_bl RB5     
  5.        
  6. #define lcd_enable() (NOP(), (lcd_data | = 0x40), NOP(),(lcd_data & = 0xBF), NOP())     //felső 4 bit)
  7. #define lcd_rs_ON() (lcd_data|=0x80)
  8. #define lcd_rs_OFF() (lcd_data&=0x7F)
  9. #define lcd_en_ON() (lcd_data|=0x40)
  10. #define lcd_en_OFF() (lcd_data&=0xBF)
  11. #define lcd_bl_ON() (lcd_data|=0x20)
  12. #define lcd_bl_OFF() (lcd_data&=0xDF)
  13.  
  14. void
  15. lcd_write(unsigned char w)
  16. {      
  17.      unsigned char x=0,y=0;
  18.          x =((w<<3)&0b10000000);
  19.          x|=((w<<1)&0b01000000);
  20.          x|=((w>>1)&0b00100000);
  21.          x|=((w>>3)&0b00010000);
  22.          y =((w>>3)&0b00000001);
  23.          y|=((w>>1)&0b00000010);
  24.          y|=((w<<1)&0b00000100);
  25.          y|=((w<<3)&0b00001000);       
  26.        
  27.         vWait_us(40);
  28.         lcd_data = (lcd_data & 0xF0) | (x >>4); //felső 4 bit
  29.         lcd_enable();
  30.         lcd_data = (lcd_data & 0xF0) | (y & 0x0F);      //alsó 4 bit
  31.         lcd_enable();
  32. }
  33.  
  34. void lcd_init(void){
  35. //lcd_rw=0;
  36. lcd_rs_OFF();
  37. lcd_en_OFF();
  38. vWait_ms(100);
  39. lcd_data =0x0C;
  40. lcd_enable();
  41. vWait_ms(5);
  42. lcd_enable();
  43. vWait_us(150);
  44. lcd_enable();
  45. vWait_us(150);
  46. lcd_data =0x04;
  47. lcd_enable();
  48. lcd_write(0x28);
  49. lcd_write(0x0C);
  50. lcd_write(0x06);
  51. lcd_bl_ON();
  52. }
  53.  
  54. void lcd_clear(void){
  55. lcd_rs_OFF();
  56. lcd_write(0x01);
  57. vWait_ms(2);
  58. }


De természetesen nem megy. Valaki tudna segíteni, hol rontottam el?
Amúgy a programom ettől eltekintve fut, mert van még rá írva egy MODBUS RTU is és az ragyogóan válaszolgat, csak az LCD nem megy.
(#) Hp41C válasza Wudoou hozzászólására (») Feb 5, 2014 /
 
Idézet:
LCD4-RB3 , LCD5-RB2 , LCD6-RB1 , LCD7-RB0”

Ötletes.., de a következő rengeteg helyet és kontroller futási időt szabadítana fel:
LCD4-RB0 , LCD5-RB1 , LCD6-RB2 , LCD7-RB3
A hozzászólás módosítva: Feb 5, 2014
(#) Wudoou válasza Hp41C hozzászólására (») Feb 5, 2014 /
 
Sajna már így lett elkészítve a nyák én se örülök neki, mert természetesen könnyebb lenne bitforgatások nélkül kiírni egy az egybe, de hát ez van.
(#) watt válasza Wudoou hozzászólására (») Feb 5, 2014 /
 
Szerintem nem jól inicializálod. Valahogy így szoktam:
  1. void LCD_Init(void)
  2. {
  3.         LCD_Tiltva();
  4.         LCD_Write();
  5.         LCD_Parancs();
  6.         __delay_ms(1000);                       // 1s várakozás az LCD feléledésére       
  7.         Adat_Ki_LCD(0b00000011);
  8.         __delay_ms(42);                 // 41,6ms várakozás
  9.         Adat_Ki_LCD(0b00000011);       
  10.         __delay_ms(42);                 // 41,6ms várakozás
  11.         Adat_Ki_LCD(0b00000011);
  12.         __delay_ms(42);                 // 41,6ms várakozás
  13.         Adat_Ki_LCD(0b00000010);        // PARANCS: 4BITES, 1 SOROS
  14.         __delay_ms(17);                 // 16,6ms várakozás
  15.         // Innen 4 bites működés
  16.         LCD_2x4bit_Parancs(0b00101000); // FUNC_SET  4 BITES MÓD, 2 SOROS KIJELZÉS, 5x8 PONT
  17.         LCD_2x4bit_Parancs(0b00001011); // DISPL OFF, CURSOR ON, VILLOG        
  18.         LCD_2x4bit_Parancs(0b00000001); // DISPLAY TÖRLÉS
  19.         LCD_2x4bit_Parancs(0b00000110); // KURZOR JOBBRA LÉP, SHIFT OFF
  20.         LCD_2x4bit_Parancs(0b00001100); // DISPLAY ON, CURSOR OFF
  21. }
(#) Hp41C válasza Wudoou hozzászólására (») Feb 5, 2014 /
 
.. és még az lcd_write -t is átírnám:
lcd_write(unsigned char w)
{
unsigned char x=0,y=0;
if (w & 0x80) x |= 1;
if (w & 0x40) x |= 2;
if (w & 0x20) x |= 4;
if (w & 0x10) x |= 8;

if (w & 0x08) y |= 1;
if (w & 0x04) y |= 2;
if (w & 0x02) y |= 4;
if (w & 0x01) y |= 8;

vWait_us(40);
lcd_data = (lcd_data & 0xF0) | (x); //felső 4 bit
lcd_enable();
lcd_data = (lcd_data & 0xF0) | (y); //alsó 4 bit
lcd_enable();
}
(#) Wudoou válasza watt hozzászólására (») Feb 5, 2014 /
 
Igen, de nekem Adat_Ki_LCD nem lehet annyi, amit írtál, mert biteket kell forgatni.
(#) watt válasza Wudoou hozzászólására (») Feb 5, 2014 /
 
Hogy az adat ki-ben mi van(hívhatjuk lcd_write-nak is), azt neked kell megoldanod a bitkiosztásnak megfelelően. A lényeg, az időzítések és az ismétlések az elején, hogy az inicializálás biztos legyen (lásd LCD driver adatlapja).
A hozzászólás módosítva: Feb 5, 2014
(#) Wudoou válasza watt hozzászólására (») Feb 5, 2014 /
 
A bitforgatás és inicializálásom biztos hogy jó ugyanis van egy pár ilyen panelem, ahol az lcd lábkiosztás ez volt (adatlábak) csak olyan még nem volt hogy az rs és en is azon a porton lett volna. Vagyis valószínű hogy adatírás közben megváltozik az rs, en láb állapota. Ezt kellene orvosolnom valahogy. Ezt onnan gondolom, hogy az lcd_init legvégén bekapcsolom a backlightot, de a legelső lcd parancs kiadásnál ki is kapcsol. Valahogy azt kellene megoldani hogy ne változzanak meg a bitek.
A hozzászólás módosítva: Feb 5, 2014
(#) watt válasza Wudoou hozzászólására (») Feb 5, 2014 /
 
Nem vitatom, ez lehet a fő baj(RMW gond lehet), de ettől még nem kellően gondos az inicializálás, ha a gyári ajánlásokat nézem. Próbáld másképpen maszkolni. Hp41C is adott egy más megoldást erre. Szimulációban jók a műveletek?
(#) kit6263 válasza watt hozzászólására (») Feb 6, 2014 /
 
Hi watt...sajnos rossz az MPLAB szimulátor.
10 éve gyúrom a PIC-eket. Nem egyszer használtam a timer-eket. Tudom hogyan működnek.
Most tértem át K procira, ugyanis árban nagyon nem mindegy és tudásban sem.
Ennél a ha timer1 rd16-ot beállítom egyszerűen leáll a timer az MPLAB SIM-ben. Próbáld ki !!!!
Mindez MPLABX-ben csont nélkül működik.
Azonkívül a Hi-Tec PICC18 9.65-el nem lehet a config bit-eket állítani kódból, csak az mplab-al.
Lecseréltem 9.80-ra azzal működik.
Az MPLABX-ben viszont nem tudom a project-hez állítani config-et csak, ha kódból.
Viszont a kódot legalább legenerálja...csak ellenőrizni kell, mert olykor téved.
Hp41C-nek igaza van!
Rendkívül gusztustalannak tartom amit a Microchip csinál.
2 db ICD2 van a fiókban...rosszak...+ egy harmadik amit Ők küldtek...az sosem volt jó nálam.
Amikor megvettem (irreálisan drágán) örök garanciát ígértek, most meg az MPLABX már nem is támogatja....vegyél újra ICD3-at...jó pénzért.
ARM Discovery fejlesztőpanel 2500 Ft és van rajta egy programozó debugger ami önállóan is használható....az ARM procik egyébként olcsóbbak mint a PIC-ek.
(#) cua válasza kit6263 hozzászólására (») Feb 6, 2014 /
 
Az ICD2->ICD3 csere jelképes összegért ment, ráadásul egy marék rizsért adtak hozzá PICKIT3-at is. Sok minden miatt lehet szidni őket, de ez a váltás korrekt volt.
(#) watt válasza kit6263 hozzászólására (») Feb 6, 2014 /
 
Megnézem amit mondasz!...

Sajnos az ARM felvetésed igaz és többi is fájdalmas, de igaz. A fejlesztő kártyák ára is irreális. Nézz meg egy Arduino mega klónt! háromezeröccá...
A hozzászólás módosítva: Feb 6, 2014
(#) Wudoou válasza watt hozzászólására (») Feb 6, 2014 /
 
Pontosan ezek a define-ok oldanák meg a RMW-t:

  1. #define lcd_enable() (NOP(), (lcd_data | = 0x40), NOP(),(lcd_data & = 0xBF), NOP())     //felső 4 bit)
  2.  
  3.  7.
  4. #define lcd_rs_ON() (lcd_data|=0x80)
  5.  
  6.  8.
  7. #define lcd_rs_OFF() (lcd_data&=0x7F)
  8.  
  9.  9.
  10. #define lcd_en_ON() (lcd_data|=0x40)
  11.  
  12. 10.
  13. #define lcd_en_OFF() (lcd_data&=0xBF)
  14.  
  15.  11.
  16. #define lcd_bl_ON() (lcd_data|=0x20)
  17.  
  18. 12.
  19. #define lcd_bl_OFF() (lcd_data&=0xDF)

Csak valamit mégsem jól csinálok.
A hozzászólás módosítva: Feb 6, 2014
(#) kit6263 válasza Hp41C hozzászólására (») Feb 7, 2014 /
 
"Tanulság: Nem érdemes az előre definiált makrókat és könyvtári függvényeket használni..."
Ezt megerősítem :
Most a Hi-Tech 9.80-ast kezdtem használni...mit ad isten az EEPROM makrók és függvények nem mennek. Nem nagy gond, mert a plib-ben benne vannak korrektül eltekintve az olyan dolgoktól, hogy 256 byte-os EEPROM esetén is a címet 16 biten adja át. Van memória bőven, majd veszünk nagyobb pic-et.
Visszatérve a fenti timer RD16 bit-re. A fordító mindenképpen byte-san olvas és ír. Futó timer esetén, amikor mehet az akár Tosc-ról, a PC meg Tosc/4...több mint gáz. A plib sem foglakozik ilyesmivel... jó az úgy ahogy van....használd és szívj, mert néha hibázik egy időzítő.
Legutoljára a Nuvoton kínai cég szoftverében találtam ilyen borzasztóan bosszantó hibákat...
Egy barátom reklamált a kínai beszállítónál.
Válasz : Maga nem tudta, hogy kínai árut vesz? Miért nem vett németet, ha minőséget akar !
De ez amerikai...ők fújják a passzát szelet!
Ez nem politikai, hanem szakmai vélemény !
(#) kit6263 válasza HerrTopi hozzászólására (») Feb 7, 2014 /
 
A proc órajelet nem írtad !
Az 50 Hz (20msec) általában elég alacsonynak számít !
Kérdés milyen felbontást akarsz ?
Ha 1 ms körül elég ajánlom a következő módszert.
Gondold át mennyit fog a program ISR-ben tölteni !
Állíts be valamelyik timert, hogy 1 ms-enként adjon egy interrupt-ot.
Ebben az ISR rutinban, növelj egy számlálót.
Figyeld a számlálót és ennek megfeleően kapcsold a pin-t.
Ehhez hasonlóan :
  1. void low_priority interrupt ISR_LOW( void )
  2. {
  3.      if( TMR0IF )
  4.     {
  5.                 //-------------------------------------
  6.                 // 1 msec
  7.                 //WRITETIMER0( 0xffff - 3997 );                 // Mérd meg StopWatch-al !
  8.  
  9.                 // PWM
  10.                 if( pwm == 0 )
  11.                         PWM_OFF();
  12.                 else if( pwm == 100 )
  13.                         PWM_ON();
  14.                 else
  15.                 {
  16.                         if( pwm_ct < pwm )
  17.                                 PWM_ON();
  18.                         else
  19.                                 PWM_OFF();
  20.                         if( pwm_ct < 99 )
  21.                                 pwm_ct++;
  22.                         else
  23.                                 pwm_ct = 0;
  24.                 }
  25.                 TMR0IF = 0;
  26.     } // Timer0
  27. } // ISR
(#) potyo válasza kit6263 hozzászólására (») Feb 7, 2014 /
 
Idézet:
„De ez amerikai...ők fújják a passzát szelet!”


Nekünk van egy folyamatban levő fejlesztésünk a Unicoi cégtől származó InstaVoip modullal. Hát az is egy szemétdomb, ami stack-eket adnak hozzá, ahhoz képest, hogy pénzt kérnek érte, ráadásul nemis keveset. Plusz a support is fizetős, szintén nem olcsó, viszont sajnos szükség is van rá, mert a dokumentációjuk sok helyen hibás, igencsak hiányos, alapvető dolgokra nincsen bennük példa, stb. Hozzávaló VisualDSP++ IDE néha gondol egyet, hibás kódot fordít, vagy épp kihagy kódrészletet, aztán meg pislogunk, hogy miért nem megy valami, amikor az előbb még ment. Elejében azt hittem, én csinálok valamit rosszul, de később rájöttem, hogy nem. Bezárás-megnyitás, debugger lehúzás-visszadugás, és ismét normális lesz egy darabig. Ehhez képest a Microchip dolgai még egész jól működnek.
(#) kit6263 válasza kit6263 hozzászólására (») Feb 7, 2014 /
 
Közben ránéztem a szervókra.
A timer ISR biztosan jó lesz ! Kell egy időzítés a be időre és a ki időre. Ezeket felváltva állítgasd ISR -ben.
  1. if( isON() )
  2. {
  3.  OFF();
  4.  WRITETIMER0( 0xffff - TIME_OFF );  
  5. }
  6. else
  7. {
  8.  ON();
  9.  WRITETIMER0( 0xffff - TIME_ON );
  10. }
(#) kit6263 hozzászólása Feb 13, 2014 /
 
Óriási BUG a 9.80 hi-tech (már Microchip-et ír ki ) plib softwer spi funkcióban !

MODE1 MODE2 esetén :

  1. #ifndef _OMNI_CODE_
  2.                 STATUSbits.C = 0;       // Set the carry bit according to
  3.                 if(SW_DIN_PIN)          // the Din pin
  4.                         STATUSbits.C = 1;
  5.                 SW_SCK_PIN = 0;         // Clear the SCK pin
  6.                 _asm
  7.                 rlcf  input,1,1
  8.                 _endasm                         // Rotate the carry into the data byte
  9. #else
  10.                 if (SW_DIN_PIN)
  11.                         input = (input << 1) | 0x1;
  12.                 else
  13.                         input = input << 1;
  14.                 SW_SCK_PIN = 1;         // Set the SCK pin
  15. #endif


Akkor most az SW_SCK_PIN clear vagy set ?
Náluk attól függ optamlizál-e a fordító ?

Ez se semmi :
  1. SW_DOUT_PIN = 0;        // Set the Dout pin according to
  2. if(input&0x80)          // the MSB of data
  3.        SW_DOUT_PIN = 1;

Egy kicsi glitch softveresen sosem árt !


Miért nem lepődök meg ?
A hozzászólás módosítva: Feb 13, 2014
(#) potyo válasza kit6263 hozzászólására (») Feb 13, 2014 /
 
Egyre inkább úgy érzem, hogy nem rossz dolog, hogy nem használom a beépített függvényeket, makrókat. Elég a fordító hibáival szívni, nem hiányzik még ezekkel is...
(#) watt válasza potyo hozzászólására (») Feb 13, 2014 /
 
Maximálisan egyetértek. Már az elején kiakadtam, milyen szerencsétleg függvényeket írnak perifériákhoz. Persze ehhez az kell, hogy assemblerben tanulja meg az ember a műfajt és utána váltson C-re...
(#) cassis hozzászólása Feb 14, 2014 /
 
Hogyan lehet c ben egy float változónak közvetlenül a szám 4 byte -os hexadecimális reprezentációját megadni? Milyen szintaktika kell hozzá?
(#) p_istvan válasza cassis hozzászólására (») Feb 15, 2014 /
 
union segítségével.
(#) pipi válasza cassis hozzászólására (») Feb 15, 2014 /
 
Vagy csinálsz egy a float-ra mutató unsigned char pointert...
(#) potyo válasza cassis hozzászólására (») Feb 15, 2014 /
 
float x;
((unsigned char *)&x)[0]=0x12;
((unsigned char *)&x)[1]=0x34;
((unsigned char *)&x)[2]=0x56;
((unsigned char *)&x)[3]=0x78;
(#) AZoli hozzászólása Feb 16, 2014 /
 
Sziasztok!
MPLAB 8.92 C30
Sosem voltam jó fejszámolásban, de ez mintha pont a kétszerese lenne mint kéne.. elég nehéz volt megtalálni hogy miért nem azt csinálja a függvényem amit szeretnék, de már teljesen elvesztetten a fonalat. Én csinálok rosszul valamit?

C30.jpg
    
(#) AZoli válasza AZoli hozzászólására (») Feb 16, 2014 /
 
Ennyit találtam:
http://www.microchip.com/forums/m653902.aspx
Kipróbáltam egy másik projectemben, ahol 24HJ van, ott rendben van.
De a fenti 24EP512GU814 esetén mindig ez az eredmény... EErata-ban sem találok erről semmit..
Valaki kipróbálná ezzel a kontollerrel MPLAB X- ben?
(#) kit6263 hozzászólása Feb 18, 2014 /
 
Muszáj a volatile ?
double a float helyett ?

Estleg variáld :
(float) c = (float) a * (float) b;
c = 1.0 * a * 1.0 * b;

Még sok jó ötletem lenne....

Sajnos ( vagy inkább szerencsére pont ilyen szívások miatt ) megálltam a PIC18-nál.
Most barátkozom az ARM procikkal.

A 9.65 és 9.80 fordítóban a 18f45k80 ill. 18f46k80 procinál mostohagyerek az RB0 és RB1.
Kifelejtették !
A világ csak az RB2-től kezdődik !!!
(#) Wudoou hozzászólása Feb 20, 2014 /
 
Sziasztok!

Én éppen most Hitech-c 9.83 PRO móddal szívok, mert egyszerűen nem értem miért, de nem fordít jól.
Van egy függvényem, melynek visszatérési értéke float.
Ha átírom int-re, akkor egyszerűen nem működik, de hibátlanul lefordul. Ha megnézem a fordítás után a memóriát, akkor azt veszem észre, hogy le sem foglalja.
Mitől lehet?
íme a függvény:
  1. float read_alldev(BYTE pin,BYTE device){
  2.         //GIE=0;
  3.         BYTE lyuk=0;
  4.         for(BYTE xcv=0;xcv<8;xcv++){
  5.                 if(eeprom_read(device*0x08+xcv)==0x00){
  6.                         lyuk++;
  7.                 }
  8.         }
  9.         if(lyuk>7){
  10.                 return(-127);
  11.         }
  12.         BYTE reg[10];
  13.         BYTE temp1, temp2;
  14.     int temp3;
  15.     float result;
  16.  
  17.     OW_reset(pin);
  18.         Send_MatchRom(pin, device);                                     //Eszköz kijelölése
  19.     OW_write_byte(pin, READ_SCRATCHPAD);         //Read scratchpad
  20.     for(BYTE i=0;i<9;i++){
  21.                 reg[i]=OW_read_byte(pin);
  22.         }
  23.         if(crc_calc(&reg[0],8)==reg[8]){
  24.                 temp1=reg[0];
  25.                 temp2=reg[1];
  26.  
  27.             temp3 = temp2;
  28.             temp3 = temp3 << 8;
  29.             temp3 = temp3 | temp1;
  30.                 result = (int) temp3 / 16;              //Calculation for DS18B20
  31.             return(result);
  32.         }
  33.         else{
  34.                 return (-128);
  35.         }
  36. }
(#) Wudoou válasza Wudoou hozzászólására (») Feb 20, 2014 /
 
Már megnéztem ezt a változatot is:
  1. bank2 unsigned char valtozo=20;

Erre a fordítás után a bank2 üres, mindegy mekkora változót deklarálok. Most mi van?
(#) pipi válasza Wudoou hozzászólására (») Feb 20, 2014 /
 
Próbáld ki üres függvényként mi történik ha csak 1 db return van.
Következő: »»   90 / 153
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem