Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
 
Témaindító: histu1985, idő: Feb 11, 2006
Témakörök:
Lapozás: OK   143 / 143
(#) Jani_80 válasza superuser hozzászólására (») Jan 31, 2019 /
 
Szia, csatolom a ccs c leírását. Köszi előre is!
(#) superuser válasza Jani_80 hozzászólására (») Jan 31, 2019 / 1
 
a #DEVICE ADC=10 sornak közvetlenül a # include sor alatt kell szerepelnie.
https://ccsinfo.com/forum/viewtopic.php?t=51744
(#) Jani_80 válasza superuser hozzászólására (») Jan 31, 2019 /
 
Köszönöm úgy néz ki, hogy működni fog így !
(#) Jani_80 hozzászólása Feb 1, 2019 /
 
Sziasztok, ismét a segítségetekre szorulnék ! PIC16F877-es PIC CCS-C compilerrel és MPLAB8.90-el dolgozva , úgy tűnik, hogy tele lett a memória... A fordításkor keletkezett hibaüzenetett csatolom.
Így még nem igazán jártam, lehet hogy csak az egyik lap lett tele és nem az egész pic memóriája? mit javasoltok , hogyan tovább? (Pl.: két pic-re bontsam szét a "feladatot"?)
Köszi !

kép1.jpg
    
(#) Hp41C válasza Jani_80 hozzászólására (») Feb 1, 2019 / 1
 
A 16F877 -nek 4 program memória lapja van: 0x0000-0x07FF, 0x0800 - 0x0FFF, 0x1000 - 0x17FF és 0x1800 - 0x1FFF
A kiírás szerint:
0. lap 0x0000 - 0x07FF lapon összesen 459 üres hely maradt
1. lap 0x0800 - 0x0FFF lapon összesen 6
2. lap 0x1000 - 0x17FF lapon összesen 800 üres hely maradt -- azaz ez a lap teljesen üres
3. lap 0x1800 - 0x1FFF lapon összesen 700 üres hely maradt.
A fordító egy 0x83D (decimálisan 2109) egységnek nem talál helyet.
Az az érzésem, hogy van egy olyan nagy eljárás, ami nem fér el egy lapon. Fel kellene darabolni több kisebb eljárásra, ami beférne a 2. és a 3. lapon levő szabad helyre.
A hozzászólás módosítva: Feb 1, 2019
(#) superuser válasza Jani_80 hozzászólására (») Feb 1, 2019 / 1
 
Én a 16F877-es projektjeimet átraktam 18F45k22-re.
Pin-pin kompatibilis. Kicsit kell csak változtatni a kódon, ha a fordító támogatja.
A 877 tíz évvel ezelőtt jó volt, ma már kicsit olyan, mint ha moszkviccsal mennél nyaralni.
Ezzel együtt persze be lehet rajta fejezni amit elkezdtél, de mint a mellékelt ábra mutatja, akkor neked kell ügyeskedned az erőforrások kiosztásával.
(#) Jani_80 válasza Hp41C hozzászólására (») Feb 1, 2019 /
 
Köszönöm!
(#) Jani_80 válasza superuser hozzászólására (») Feb 1, 2019 /
 
Köszi! Lalószínűleg ezen projektem után leteszem a moszkvicsot , kipróbálom majd azt a 18F45k22-őt, pedig a 16F-es olyan mint egy F16-os , de mára már az F16-osok is kifutó repülőgép típusok
(#) Hp41C válasza superuser hozzászólására (») Feb 1, 2019 /
 
Minek kellene átrakni, amikor a 16F877 több, mint fele (4953) üres?
(#) pipi válasza Jani_80 hozzászólására (») Feb 1, 2019 / 1
 
Hali!
Hp41C-t kiegészítve, lehet akár nagy tömböd is, aminek kezdőértéket adsz...
A konkrét progi ismerete nélkül nehéz megmondani.
És még egy, azt a sok warning-ot én megoldanám, nem szeretem ha akár egy is van....
(#) superuser válasza Hp41C hozzászólására (») Feb 2, 2019 / 1
 
Kizárólag kényelmi okokból. Írtam, hogy megvalósítható ezen is. Viszont mint a mellékelt ábra mutatja, megoldást kell találni az architektúrából adódó korlátokra.
(#) Lamprologus válasza Jani_80 hozzászólására (») Feb 4, 2019 /
 
Fordításkor létre jön egy sta kiterjesztésű fájl. Azt érdemes kicsit átnézni. Látszik melyik függvény mekkora helyet foglal ... ha valamelyik túl nagy, azt fel lehet bontani rész feladatokra, és akkor be tudja tenni a maradék üres helyre...
(#) bbatka hozzászólása Szo, 19:24 /
 
Legyetek szívesek segítsetek. Legyetek elnézők velem szemben mert elég kezdő vagyok C-ben.
A lényeg hogy egy MikroC-re írt kétvezetékes karakteres LCD vezérlő driverét szeretném használni CCSC alatt. Sok a különbség a két nyelv között sajnos. Már 75 hibát sikerült elhárítanom, de ez most megfogott.
A hibaüzenet: Attempt to create a pointer to a constant (próbáljon mutatót állítani a konstansra)

A problémás függvény:
  1. void I2C_LCD_Out(char row, char col, char *text) {
  2.     while(*text)
  3.          I2C_LCD_Chr(row, col++, *text++);
  4. }
  5. //
  6. void I2C_LCD_Out_Cp(char *text) {
  7.     while(*text)
  8.          I2C_LCD_Chr_Cp(*text++);
  9. }


Ezt a függvényt hívja meg:
  1. void I2C_LCD_Chr(char row, char column, char out_char)
  2. {
  3. //
  4.     unsigned char bbyte, lcddata;
  5. //
  6.     switch(row){
  7. //
  8.         case 1:
  9.         I2C_LCD_Cmd(0x80 + (column - 1));
  10.         break;
  11.         case 2:
  12.         I2C_LCD_Cmd(0xC0 + (column - 1));
  13.         break;
  14.         case 3:
  15.         I2C_LCD_Cmd(0x94 + (column - 1));
  16.         break;
  17.         case 4:
  18.         I2C_LCD_Cmd(0xD4 + (column - 1));
  19.         break;
  20.     }
  21. //
  22. //
  23.   lcddata = (out_char & 0xF0)| LCD_RS |LCD_BL;
  24.   I2C_PCF8574_Write(LCD_ADDR,lcddata | LCD_EN);
  25.   delay_us(3);
  26.   I2C_PCF8574_Write(LCD_ADDR,lcddata & ~LCD_EN);
  27.   delay_us(3);
  28. //
  29.   lcddata = ((out_char << 4) & 0xF0) |LCD_RS |LCD_BL;
  30.   I2C_PCF8574_Write(LCD_ADDR,lcddata | LCD_EN);
  31.   delay_us(3);
  32.   I2C_PCF8574_Write(LCD_ADDR,lcddata & ~LCD_EN);
  33.   I2C_PCF8574_Write(LCD_ADDR,lcddata & ~LCD_RS);
  34.   delay_us(3);
  35. //

A fő programból így hívtam meg MikroC-ből korábban.
  1. I2C_LCD_Out(1, 1, "Time? Slot1");


Becsatolom a drivert is. Softveres I2C-ről hardveresre átalakítva használtam MikroC alatt.
Még annyit hogy a hard_i2c_lcd.c -t beolvasztottam a saját programomba, tehát nem #include-al használom mert az alábbi függvénnyel is problémája volt a CCS fordítónak:
  1. void I2C_PCF8574_Write(unsigned char Adr,unsigned char value){
  2.  i2c_start();
  3.  i2c_write(LCD_ADDR);
  4.  i2c_write(value);
  5.  i2c_stop();
  6. }
(#) bbatka válasza bbatka hozzászólására (») Szo, 20:10 /
 
Egy külföldi fórumon találtam ezt a beállítást.

#device PASS_STRINGS = IN_RAM

A hibaüzenetek száma lecsökkent egyre, erre a sorra vonatkozóan.

Can not set this option this far into the code. (ezt az opciót nem lehet használni a kódban)
(#) benjami válasza bbatka hozzászólására (») Szo, 21:07 /
 
Nem használtam még sem MikroC-t, sem CCSC-t, de ha 8 bites PIC-ről szól a történet (azt azért leírhatnád milyen típusú PIC-re írod) a fordítónak teljesen más kódot kell fordítania a RAM illetve ROM területen levő karaktertömb használatához. Írj külön ROM karaktertömb kezelő függvényeket hozzá. Pl.:
  1. void I2C_LCD_Out_ROM(char row, char col, const char *text) {
  2.     while(*text)
  3.          I2C_LCD_Chr(row, col++, *text++);
  4. }
  5.  
  6. void I2C_LCD_Out_Cp_ROM(const char *text) {
  7.     while(*text)
  8.          I2C_LCD_Chr_Cp(*text++);
  9. }

Lehet, hogy nem jó szintaktikával írtam, de kiindulási alapnak talán használható.
(#) bbatka válasza benjami hozzászólására (») Vas, 8:43 /
 
A PIC típusa 18F4520.
Gondolkodom azon amit javasolsz. A RAM-ban szeretném tárolni a karaktertömböket.
Ezen a fórumon találtam a legutóbbi módosításomhoz az ötletet.
A hozzászólás módosítva: Vas, 8:46
(#) bbatka válasza benjami hozzászólására (») Vas, 10:40 /
 
A probléma megoldódni látszik. A mutató RAM-ba elhelyezésére utaló fordító utasítást előbbre hoztam a kódban. Eredetileg ott volt ahol most az üres hely van.

  1. #include<18F4520.h>
  2. #device PASS_STRINGS = IN_RAM
  3. #include<hard_i2c_lcd.h>
  4. #include<keypad.c>
  5. //#include<hard_i2c_lcd.c>
  6. #include<stdio.h>
  7. #fuses HS, NOLVP, NOWDT, NOPROTECT
  8. #use delay(clock=20000000)
  9. #define XTAL_FREQUENCY  20000000
  10.  
  11. #use i2c(master, sda=PIN_C4, scl=PIN_C3, Slow, FORCE_HW)
(#) bbatka válasza bbatka hozzászólására (») Vas, 10:53 /
 
Be is égettem a programot a PIC-be. Egyelőre a megjelenített karakterek némelyike nem egyezik azzal, amit szeretnék látni. Szerintem túl gyors az I2C beállításom vagy az időzítéseket kell a driverben növelni. Legalább már nincs hibaüzenet
(#) benjami válasza bbatka hozzászólására (») Vas, 17:08 /
 
Lehet hogy RAM-ban szeretnéd tárolni, de a példasorod
  1. I2C_LCD_Out(1, 1, "Time? Slot1");
az ROM pointert küld. Ha sok a kiírni való, akkor célszerűbb inkább a ROM-ban tárolni, mert a szűkös RAM-ból nem olyan nehéz kifogyni.
(#) bbatka válasza benjami hozzászólására (») Vas, 17:37 /
 
Nem igazán vagyok még tisztában a mutatókkal. Szerencsére a RAM 14%-át használtam el eddig csak.
Jó lett az LCD-re történő kiíratás. Az időzítéseket növeltem 3us-ról 30us-re.
Köszi a javaslatod, még végig kell gondolnom.
(#) AZoli hozzászólása Kedd, 9:42 /
 
Sziasztok!
UART - DMA problémám van 33EP256MU806 PIC -en.
DMA nélkül rendben megy a kommunikáció, a csomagok 95%-át hibátlanul megkapom, abban az 5%-ban van Receive Buffer Overrun, ilyenkor elveszik néhány csomag, ez így ok.

Megpróbáltam DMA -hoz kötni a vételt, de valamit nagyon benéztem, mert alig jön értékelhető csomag.
Mivel DMA nélkül jó, (csak nem marad másra ideje a PIC -nek) ezért gondolom az UART beállítások rendben vannak. A main-ben megpróbáltam FIFO elven kiolvasni a UART_ReceivedBuf[] -t, feltételezem itt rontok el valamit, de nem találom mit.

  1. void InitUART (uLong Baud)
  2. {
  3.     DMA3CON = 0b0001000000000000; //Initiate interrupt when half of the data has been moved + Register Indirect with Post-Increment mode + Continuous, Ping-Pong modes are disabled
  4.     DMA3PAD = 0x0226;   // 0x0226 (U1RXREG)
  5.     DMA3CNT = 31; //32 -1
  6.     DMA3REQ = 0x000B;   //00001011 -> UART1RX – UART1 Receiver
  7.     DMA3STAL =  __builtin_dmaoffset(UART_ReceivedBuf)//Az átvitel során a cím módosul (mindig az aktuális mutató  értékét olvashatjuk ki belőle)
  8.     DMA3STAH = 0x0000;
  9.     DMA3CONbits.CHEN = 1;
  10.     IEC2bits.DMA3IE = 0; // receiver DMA-interrupt ki-be
  11.    
  12.     U1MODE = 0;
  13.     U1STA = 0;
  14.    
  15.     U1MODEbits.STSEL = 0; // 1-STOP BIT
  16.     U1MODEbits.PDSEL = 0; // NO PARITY, 8-BIT DATA
  17.     U1MODEbits.ABAUD = 0; // AUTO-BAUD DISABLED
  18.  
  19.     U1MODEbits.BRGH = 1; // High-Speed Mode
  20.     U1BRG = ((FCY/Baud)/4)-1; // Baudrate: 115200 -> 129   (115384,6) Error: 0,1599%
  21.  
  22.     U1STAbits.URXISEL = 0; // interrupt after one char. received
  23.     U1MODEbits.UARTEN = 1; // Enable UART
  24.     U1STAbits.UTXEN = 1; // Enable UART TX
  25. }
  26.  
  27. ...
  28.  
  29. __eds__ uInt  __attribute__((eds,space(dma),aligned(64)))   UART_ReceivedBuf[32];
  30. uInt URB_P = 0// ...ahol éppen tartunk a FIFO kiolvasással
  31. uInt DMA_Data = 0; //... ahova érkezett az utolsó adat
  32.  
  33. ...
  34.  
  35. //main-ben:
  36.  
  37.         DMA_Data = (DMA3STAL - (uInt)&UART_ReceivedBuf) / 2; // DMA3STAL a RAM címre mutat, hova érkezett az utolsó adat
  38.          
  39.         for (; URB_P != DMA_Data; URB_P++) // DMA_Data 0-31 mutatja, hova érkezett az utolsó adat
  40.         {
  41.             GetUART (UART_ReceivedBuf[URB_P] & 0x00FF);
  42.  
  43.             if (URB_P >= 31) URB_P = 0;                     
  44.         }
(#) Hp41C válasza AZoli hozzászólására (») Kedd, 12:00 /
 
  1. for (; DMA_Data>0; URB_P++)
  2.         {
  3.             GetUART (UART_ReceivedBuf[URB_P] & 0x00FF);
  4.              if (URB_P >= 31) URB_P = 0;                     
  5.             DMA_Data--;
  6.         }
(#) AZoli válasza Hp41C hozzászólására (») Kedd, 13:16 /
 
Miért kéne csökkentenem DMA_Data -t?
A 37. sorban DMA periféria által beállítjuk oda, ahová az utolsó adat érkezett.

A for ciklusba pedig URB_P -vel addig körözünk a FIFO -ban, amíg ezt meg nem találjuk. (És mindig onnan kezdjük a körözést, ahol legutóbb abbahagytuk.

A DMA elvileg folyamatosan pakolja az érkezett byte-okat UART_ReceivedBuf[32] -be. Ha elérte a 31. elemet, akkor felülírja a 0-at. Legalábbis ez volt a célom DMA beállítással. Lehet hogy itt nem stimmel valami?

Mod.:
Ja bocsánat, most látom, a for ciklus feje is más...
A hozzászólás módosítva: Kedd, 13:17
(#) AZoli válasza Hp41C hozzászólására (») Kedd, 13:29 /
 
Ezzel a verzióval az lesz a probléma, hogy - mivel nem tudom értesíteni DMA-t arról, hogy kiolvastam x adatot UART_ReceivedBuf[] ből- a DMA UART_ReceivedBuf[] írását ugyan ott fogja folytatni (DMA3STAL) ahol abbahagyta.
DMA3STAL -t FRM szerint nem tanácsos módosítani.

Köszönöm hogy foglalkozol a problémával!
(#) Hp41C válasza AZoli hozzászólására (») Kedd, 17:05 /
 
Azt a problémát próbáltam meg kijavítani, hogy "szemetet" olvas ki a DMA pufferből. Legyen a vett adatok száma 6, az első adat pl. a 28. helyen. Az eredeti megoldás szerint elkezdjük kiolvasni a 28., 29., 30., 31. helyről az adatot. Ezek után 0 -t írunk az URB_P -be. A for ciklus pedig addig megy, amíg URB_P != DMA_Data azaz 6 -ig. Összesen 10 adatot olvas ki a 6 helyett.
(#) AZoli válasza Hp41C hozzászólására (») Kedd, 17:12 /
 
Idézet:
„Legyen a vett adatok száma 6, az első adat pl. a 28. helyen.”

Ekkor DMA_Data -ban 1 lesz.
Idézet:
„// DMA_Data 0-31 mutatja, hova érkezett az utolsó adat”

Ha jól értelek...
A hozzászólás módosítva: Kedd, 17:12
Következő: »»   143 / 143
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu