Fórum témák
- • Klíma szervizelés, javítás
- • Autóelektronika
- • Westen 240 Fi gázkazán hiba
- • Audiofil, High End Audio
- • Lopásgátló építés
- • ESP32-S3-Zero BOARD
- • Felajánlás, azaz ingyen elvihető
- • Ráz a kültéri medence vize
- • TDA7294 végerősítő
- • Gitár Pickup
- • Klíma beszerelése, fűtés-hűtés házilag
- • Kapcsolási rajzot keresek
- • Elektromos kerékpár, robogó házilag
- • Villanyszerelés
- • Aggregátor feszültség szabályzó
- • Kondenzátor feltöltés
- • Folyamatábrás mikrokontroller programozás Flowcode-dal
- • Vásárlás, hol kapható?
- • Számítógép hiba, de mi a probléma?
- • Rádió építés a kezdetektől a világvevőig
- • Mikrohullámú sütő javítás, magnetron csere, stb.
- • VF3 - 6 végerősítő
- • Villanypásztor
- • Mosógép vezérlők és általános problémáik
- • Villanymotor
- • Quad 405-ös erősítő tapasztalatok és hibák
- • LM1875, LM3875, LM3886, stb. TI végerősítők
- • RFID Miértek és hogyanok
- • Li-Po - Li-ion akkumulátor és töltője
- • Alternativ HE találkozó(k)
- • PLC alapismeretek
- • PIC - Miértek, hogyanok haladóknak
- • Páratartalom érzékelő
- • Kondenzátor
- • Inverteres hegesztőtrafó
- • Erősítő mindig és mindig
- • TV hiba, mi a megoldás?
- • Elektromos fűnyíró probléma
- • Li-Ion saját akkucsomag készítése
- • Ki hol gyártatja a NYÁK-ot ?
- • Flip-Flop? Bistabil? Buffer?
- • Egyfázisú motor forgásirány váltása mágneskapcsolóval
- • Indukciós főzőlap javítása
- • Espressif mikrokontrollerek
- • Hörmann kapuk
- • Műveleti erősítő
- • Kombikazán működési hiba
- • Codefon kaputelefon
- • Porszívó javítás
- • Rádióamatőrök topikja
- • Muzeális készülékek-alkatrészek restaurálása
- • Analóg oszcilloszkóp javítása
- • Elektromos távirányítós kapunyitó
- • Érdekességek
- • Sütő javítás
» Több friss téma
|
Fórum » PIC programozása C nyelven, C-Compiler
Talán így:
void main()
{
TRISB = 0; // PORTB all output to LED
PORTB = 0;
do
{
PORTB.F7 = 1;
delay_ms(100);
PORTB.F6 = 1;
delay_ms(100);
PORTB.F5 = 1;
delay_ms(100);
PORTB.F4 = 1;
delay_ms(100);
PORTB.F3 = 1;
delay_ms(100);
PORTB.F2 = 1;
delay_ms(100);
PORTB.F1 = 1;
delay_ms(100);
PORTD.F7 = 1;
delay_ms(100);
PORTD.F6 = 1;
delay_ms(100);
PORTC.F2 = 1;
delay_ms(100);
PORTC.F1 = 1;
delay_ms(100);
PORTC.F0 = 1;
} while (1);
}
Idézet: „Egyszer kell amúgy lefutnia a program elején.” Ez így nem az !
Idézet: „De hiába a while parancs ugyanúgy rossz” Így talán nem annyira rossz.
Ez igaz  !
Sziasztok!
Egy kis segítségre lenne szükségem. Szeretnék egy többcsatornás mérőpanelt készíteni PIC+ ds18b20-as eszközökkel. LCD kijelzés+soros portos adatátvitel...
Az lenne a gondom, hogy 24 érzékelőt kellene mérjek, de az előző fórumozások alapján arra a végeredményre jutottunk/ jutottam, hogy 3 különböző lábon lenne 8-8 eszköz.
Na most, hogy a kód ne legyen túl nagy, szeretném átírni a ds-hez tartozó függvényeimet úgy, hogy kapna még egy argumentumot, és az alapján lenne eldöntve, hogy melyik lábon kell mérni.
Csakhogy nekem van egy 1wire.h fájlom, amiben define paranccsal adom meg az OW láb "helyzetét" és ezt hogyan tudom feltételes fordítássá tenni? Mármint hogy bármikor módosulhasson a meghívott argumentum függvényében?
#ifndef _1WIRE_H_
#define _1WIRE_H_
#include "types.h"
#define OW_TRIS TRISC4
#define OW_DATA RC4
#define OW_HIZ() (OW_TRIS = INPUT)
#define OW_HI() (OW_DATA = 1, OW_TRIS = OUTPUT) /* ez a 'strong pullup' */
#define OW_LO() (OW_DATA = 0, OW_TRIS = OUTPUT)
BYTE OW_reset(void);
void OW_write_bit(BYTE val);
void OW_write_byte(BYTE val);
BYTE OW_read_bit(void);
BYTE OW_read_byte(void);
#endif
Először valami ilyesmire gondoltam:
void Change_PIN(unsigned char pin)
{
switch(pin)
{
0: //
1: //
2: //
}
}
És a meghíváskor:
void start_allds1820(void){
unsigned char pin_variable;
for(pin_variable=0;pin_variable<3;pin_variable++){
Change_PIN(pin_variable);
OW_reset(); //onewire reset
OW_write_byte(SKIP_ROM);
OW_write_byte(START_CONVERSION);
}
}
Csak így nem jó.
Idézet: „Csakhogy nekem van egy 1wire.h fájlom”
Koncepcionális hiba van az elképzelésedben. A .h fájlhoz tartozik valahol egy .c fájl, amiben a .h-ban felsorolt függvények beltartalma van megadva (a .h csak a függvények meghívását mutatja, de a konkrét implementáció máshol van). Nem elég a .h fájlt módosítani, a függvények implementációjához is hozzá kell nyúlni.
Az tiszta sor. Csak azt szerettem volna tudni, hogy van-e rá valamilyen eljárás, hogy ezt a két sort #define OW_TRIS TRISC4
#define OW_DATA RC4
megtudjam változtatni valahol máshol.
Mivel ezt nem tudom, így kénytelen vagyok megírni a :
void OW_write_bit1(BYTE val);
void OW_write_bit2(BYTE val);
void OW_write_ bit3(BYTE val );
és így tovább.....
És persze ezeket is:
#define OW_HIZ1() (OW_TRIS1 = INPUT)
#define OW_HI1() (OW_DATA1 = 1, OW_TRIS1 = OUTPUT) /* ez a 'strong pullup' */
#define OW_LO1() (OW_DATA1 = 0, OW_TRIS1 = OUTPUT)
#define OW_HIZ2() (OW_TRIS2 = INPUT)
#define OW_HI2() (OW_DATA2 = 1, OW_TRIS2 = OUTPUT) /* ez a 'strong pullup' */
#define OW_LO2() (OW_DATA2 = 0, OW_TRIS2 = OUTPUT)
#define OW_HIZ3() (OW_TRIS3 = INPUT)
#define OW_HI3() (OW_DATA3 = 1, OW_TRIS3 = OUTPUT) /* ez a 'strong pullup' */
#define OW_LO3() (OW_DATA3 = 0, OW_TRIS3 = OUTPUT)
A hozzászólás módosítva: Szept 28, 2013
Idézet: „hogy ezt a két sort megtudjam változtatni valahol máshol.”
Nem azt a két sort kell megváltoztatni, hanem azokat a sorokat, ahol ezeket a makrókat felhasználod. Persze megoldás lehet az is, hogy legyen 3 verzió mindegyik függvényből. Annak fényében, hogy 8-bites PIC-ről beszélünk, érdemes megnézni azt is, hogy a függvények kibővítése egy plusz paraméterrel mennyivel bonyolultabb kódot fog eredményezni assemblyben. Ha nagyon, akkor simán lehet, hogy nem éri meg az, hogy ne legyen 3 verzió mindegyik függvényből. A hozzászólás módosítva: Szept 28, 2013
Idézet: „simán lehet, hogy nem éri meg”
Igen, ezt szerettem volna elkerülni azzal, hogy megváltoztatom a lábat, így csak arról kell gondoskodjak, hogy akkor tudjam, hogy csatornaváltás történt.
Szóval Idézet: „Nem azt a két sort kell megváltoztatni, hanem azokat a sorokat, ahol ezeket a makrókat felhasználod.” :
pl. van egy ilyen függvényem:
void OW_write_bit(unsigned char val)
{
DisableAllInterrupts();
OW_HIZ();
OW_LO();
vWait_us(5);
if (val)
OW_HIZ();
vWait_us(60);
OW_HI();
vWait_us(2);
ResumeAllInterrupts();
}
Akkor itt mit kellene átírnom?
helyett pl.
switch (pin) {
case 0:
OW_HIZ0();
OW_LO0();
break;
case 1:
OW_HIZ1();
OW_LO1();
break;
case 2:
OW_HIZ2();
OW_LO2();
break;
}
nyilván az OW.. makrókból kell csinálni három készletet.
Egy ilyen megoldás is működik:
#define OUTPIN(tris, port) {tris = 0; port = 1;}
#define INPIN(tris, port) {tris = 1; val = port;}
void W(void)
{
OUTPIN(TRISCbits.TRISC7, PORTCbits.RC7);
}
Na ez sokkal jobban tetszik!
Nekem a legtöbb infót ez a megoldás adja:
#define mInitPORTA() LATA &= 0b00000000; TRISA &= 0b00011111; //
#define mInitPORTB() LATB &= 0b00000000; TRISB &= 0b11111001; //
Egy kapcsolási razhoz beállítani így a legkönnyebb szerintem. Minden más megoldás, számomra csak áttekinthetetlenné teszi a kiosztást.
Kinek a pap.... A hozzászólás módosítva: Szept 28, 2013
Nem inicializálásról, hanem egy kiterjedt 1-Wire (a számosság miatt több vezetékre kötött) érzékelő rendszer kezeléséről volt szó. Ahhoz kerestem ötletet, hogy ne kelljen annyiszor elkészíteni, leírni a 1-Wire kezelő függvényeket.,,
Értem, elnézést a félreértésért!
Sziasztok!
Feladtam a jó kis langyos CCS-t és elkezdtem C18-al foglalkozni, de az őrületbe kerget a warningjaival.
Hogyan lehetne ezektől megszabadulni? (Természetesen nem a warningok kikapcsolására gondoltam)
// definició
rom const char * cmd_commands[] = {
"LEDS"
};
const rom char strVersion[] = "Version 1.0";
...
char cmd[ 5 ];
int i = 0;
...
if( strncmpram2pgm( *commands[i], (char*)&cmd, 4 ) == 0 )
erre Warning [2066] type qualifier mismatch in assignment
strcpypgm2ram( (char*)&outdata[5], &strVersion );
erre pedig Warning [2054] suspicious pointer conversion
az uotdata egy egyszerű char[64]
és az strncmpram2pgm hívásra mindenhol ugyan ezt adja, akár mit teszek vele....
Segítsen valaki!
C18-nál a ROM és a RAM memóriához különböző típusú mutatókat használunk. Nem tudom, hogy az MPLAB-ban a memória címzésmód változtatásával lehet-e ezen segíteni.
Szerintem hadilábon állsz a tömbök/pointerek használatával, és erre próbál finoman rávezetni a fordító. Azt kell megjegyezni, hogy a tömb neve magában leírva egy pointer, ami pont az első elemre mutat. Ennek a pointernek nincs címe (úgy nevezett jobb-érték), ezért a "&cmd" kifejezést a fordító csak nagy duzzogva eszi meg, és értékeli ki ugyanarra a kifejezésre, amit "cmd" magában is jelent. Ugyanezért a "&strVersion" helyett is "strVersion" kéne magában.
Továbbá ha az outdata egy char tömb, akkor a "(char*)&outdata[5]" pont ugyanazt csinálja, mint az "&outdata[5]", csak nem sumákolja el egy casttal, hogy most akkor stimmel-e a típus (ha később megváltoztatod az outdata típusát, akkor cast nélkül a fordító ordítani fog, míg a casttal ezt felülbírálod, hogy "jól van, tudom mit csinálok, ne küldjél warningot" ). Ezen felül az "&outdata[5]" helyett lehet írni, hogy "outdata + 5", ami jobban tükrözi a pointeres szemléletet. A hozzászólás módosítva: Okt 5, 2013
Igazad van, vannak bizonytalanságok/hiányosságok a tudásomban.
Sajnos amit leírtál az nem vitt előrébb, sőt..... megsokasodtak a warningok 
Lehet hogy valami apróság, még sportolok rajta, de ahogy kiveszem a típuskényszerítéseket egyre jobban hisztizik a fordító. Azért próbálkozom. Köszi az oktatást, ez a jobb-érték dolog valóban az újdonság erejével hatott.
Üdv. Sikerült találnom egy hibátlan fordulasztámmérő programot. Mindössze a timer2 leosztását nem tudom átállítani hogy azt az értéket jelezze ki amit kellene mert gyorsabban jár ez a processzor mint amire írták eredetileg a programot. Előtte egy 16f887-en 8mhz-en ketyegett a program most 18f4550-ön menne 48Mhz-es pll-el és kristállyal. Bemásolom azt a kódrészletet ami nem stimmel : // setup TMR2 and enable TMR2 int
T2CON = 0b00011111; // TMR2 ON, 8MHz xtal, 16:4:1 = 31250 Hz
PR2 = 250; // TMR2 int is 31250 / 250 = 125 ints/sec
PIE1.TMR2IE = 1; // TMR2 interrupt is on
INTCON = 0b11000000; // GIE=ON, PIE=ON
// load variables ready to run
int_sec_count = 125;
Most 50Hz-nél aminek 3000-es fordulatot kéne jelentenie 480RPM-et jelez ki.
Egy kicsit több részlet kellene a programból... 48 MHz = 6 * 8 MHz, tehát nem 125 megszakítás érkezik, hanem 6 * 125 = 750. Milyen típusú az int_sec_count?
Bemásolom az egészet. Hirtelen nem tudom mire gondolsz az utolsó kérdésed alatt. /******************************************************************************
* Project name:
EP6_freq.c EasyPIC6 only, is a freq/rpm meter using the COG display
* Copyright:
Open-source - Oct 2009 - Roman Black
* Description:
I modified the EasyPIC6 COG text display example to make a simple
frequency/rpm meter. The incoming frequency to be measured must be
connected to PORTC.F0 (T1CKI) pin. Max freq measured is 65000 Hz.
Note! If you don't have a freq signal connected, you can test it
by pressing the RC0 pushbutton REALLY quickly. 
* Test configuration:
http://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf
Dev.Board: EasyPIC6
Oscillator: HS, 8.0000 MHz
Ext. Modules: - freq signal comes in on PORTC.F0
SW: mikroC PRO for PIC v2.50
******************************************************************************/
// global declarations
// Port Expander module connections
sbit SPExpanderCS at RA2_bit;
sbit SPExpanderRST at RA3_bit;
sbit SPExpanderCS_Direction at TRISA2_bit;
sbit SPExpanderRST_Direction at TRISA3_bit;
// End Port Expander module connections
unsigned char int_sec_count; // used to count ints/second
unsigned char new_second; // is set once per second
unsigned char tchar; // text char used in LCD display numbers
unsigned int freq; // 0-65000, holds freq value to display
unsigned long rpm; // holds RPM for calcs AND display
char txt[12]; // used to display number string
char sec_count;
//-----------------------------------------------------------------------------
void interrupt()
{
// this is TMR2 overflow interrupt
int_sec_count--;
if(!int_sec_count) // if reached 1 second!
{
// get the TMR1 count!
T1CON = 0; // TMR1 OFF
freq = ((TMR1H << 8) + TMR1L); // put TMR1 16bit value in freq
TMR1L = 0; // clear TMR1
TMR1H = 0;
T1CON = 0b00000011; // TMR1 back ON again
// that's everything done for this second
new_second++;
int_sec_count = 125; // load ready to generate another second
}
TMR2IF_bit = 0; // Clear TMR2IF before exit
}
//-----------------------------------------------------------------------------
void main()
{
//-------------------------------------------------------
// setup PIC 16F887 registers
ANSEL = 0; // Configure AN pins as digital
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
TRISC = 0b00000001; // PORTC.F0 = input from freq signal
//-------------------------------------------------------
// EasyPIC6 COG text LCD setup
// Port Expander Library uses SPI1 module
SPI1_Init(); // Initialize SPI module used with PortExpander
// show startup message
SPI_Lcd_Config(0); // Initialize Lcd over SPI interface
SPI_Lcd_Cmd(_LCD_CLEAR); // Clear display
SPI_Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
SPI_Lcd_Out(1,2, "EP6 Frequency"); // display startup text to Lcd
SPI_Lcd_Out(2,2, " & RPM Meter ");
Delay_1sec();
Delay_1sec();
// clear LCD again before main
SPI_Lcd_Cmd(_LCD_CLEAR);
//-------------------------------------------------------
// setup the timers for frequency counting
// setup TMR1
T1CON = 0b00000011; // TMR1 ON, external clock pulse on PORTC.F0
// setup TMR2 and enable TMR2 int
T2CON = 0b00011111; // TMR2 ON, 8MHz xtal, 16:4:1 = 31250 Hz
PR2 = 250; // TMR2 int is 31250 / 250 = 125 ints/sec
PIE1.TMR2IE = 1; // TMR2 interrupt is on
INTCON = 0b11000000; // GIE=ON, PIE=ON
// load variables ready to run
int_sec_count = 125;
//-------------------------------------------------------
// now do the main run loop
while(1)
{
// safe limit freq at 65 kHz
if(freq > 65000) freq = 65000;
// everytime we reach a second, calculate and display freq
if(new_second)
{
new_second = 0;
// display freq as "xxxxx Hz"
WordToStr(freq,txt);
SPI_Lcd_Out(1,8,txt);
SPI_Lcd_Out(1,14,"Hz");
// calc RPM from freq
rpm = (freq * 60);
// format rpm to display as "xxxxxxx RPM"
LongToStr(rpm,txt); // get the rpm as a string
SPI_Lcd_Out(2,2,txt); // and display RPM!
SPI_Lcd_Out(2,14,"RPM");
}
}
}
Az spi-s dolgokkal nem kell foglalkozni és a komparátor és analóg bemenetekhez tartozó paranccsal azt már átírtam a 18f nyelvére.
Szia!
unsigned char int_sec_count; // used to count ints/second
helyett
unsigned int int_sec_count; // used to count ints/second
és minden előfordulásánál az
helyett
Szia, köszönöm szépen módosítom ez szerint.
Hát ha szét szakadok is warningol.....
const rom char strVersion[] = "Version 1.0";
char outdata[];
....
strcpypgm2ram( &outdata[5], strVersion );
erre még mindíg Warning [2066] type qualifier mismatch in assignment
rom const char * cmd_commands[] = {
"LEDS"
};
char cmd[5];
if( strncmpram2pgm( commands[i], cmd, 4 ) == 0 )
Erre pedig Warning [2066] type qualifier mismatch in assignment
Mit nem csinálok jól?
(MPLAB C18 v3.45)
Nem ismerem a C18-at, de szerintem csak annyi a baja, hogy konstans memóriaterületre állítasz egy pointert, és szól, hogy veszélyes vizekre eveztél.
Ha erre a memóriaterületre a változó nevével közvetlenül hivatkozol, akkor nem fogod tudni felülírni a "const" miatt. De ha ugyanide pointerrel hivatkozol, akkor már felülírható. A szintaktika szempontjából pedig mindegy, hogy az egy ROM terület, és egyébként sem lehet "csak úgy" írkálni oda.
Másrészt az is lehet a baj, hogy egy konstans "változót" egy nem konstans változóba másolsz, ami innentől szabadon megváltoztatható, azaz afféle típus konverzió történik.
Akkor kapod ezt a warning-ot, ha az strcpypgm2ram()-nak nem jo tipusu erteket adsz at.
Amit kap az (char *, const rom char *)
Hogy mit var az strcpypgm2ram() azt meg kellene nezni abban a header-ben, ahol deklaraljak, ami valoszinuleg a string.h lesz. Mondjuk logikusan ezt kellene varnia.
Na, utanaolvastam a neten: A C18 leirasa irja (csak nem tudok a pdf-bol masolni), hogy elofordul, hogy ezt a warningot kapod, ha a masodik parameter 'near' mikozben a fuggveny 'far'-t var. Valoszinuleg a megoldas a problemadra:
strcpypgm2ram(outdata + 5, (const rom far char *)strVersion);
Erdemes a C18 pdf-jet elolvasni, ott irnak meg par dolgot ezzel kapcsolatban.
Udv,
Andor
Nem akarok "csak úgy írkálni", hanem a ROM területre akarom tenni a string konstansokat hogy ne a RAM-ot zabálják.
killbill: Köszi! Ez lett a megoldás  egyszerűen csak egy far kellett neki.
Üdv, valaki elmondhatná, ha van mondjuk egy nand nor stb kapu, hogyan tudok kialakítani c-ben picre?
Azért lenne érdekes, mert plc-t kéne alkalmazni az alkalmazáshoz, de nem akarok rá 10-en ezreket költeni, amúgy is csak egy uC- van ugyanúgy egy plc-ben is.
Valaki tudna-e példákat mutatni?
|
|