Fórum témák
- • Radiosonde
- • Leválasztó transzformátor
- • Nyomtató probléma
- • Indukciós főzőlap javítása
- • Mosogatógép hiba
- • HESTORE.hu
- • Audiofil, High End Audio
- • Autórádió (fejegység) problémák, kérdések, válaszok
- • Klíma szervizelés, javítás
- • Elektromos sütő
- • PC táp javítása
- • Kenyérpirító nem kapcsol ki időben
- • Felajánlás, azaz ingyen elvihető
- • Kapcsolóüzemű táp 230V-ról
- • Jókívánság
- • Kerámialapos tűzhely
- • DC motor/lámpa PWM szabályzása
- • Labortápegység készítése
- • Karácsonyi fényfüzérek
- • Szilárdtest relé
- • Elfogadnám, ha ingyen elvihető
- • NYÁK terv ellenőrzése
- • IGBT VEZÉRLÉSE
- • DCF77 óra Nixie-csövekkel
- • Kombikazán működési hiba
- • Villanyszerelés
- • Arduino
- • STK erősítők javítások
- • Hegesztő inverter javítás
- • MyElecParts alkatrész kereső és készlet nyilvántartó
- • Okosotthon relé vezérlő IO board arduino és MCP23017 alapon
- • Elektromos távirányítós kapunyitó
- • Hűtőgép probléma
- • WiFi / WLAN alapkérdések
- • Tápegységgel kapcsolatos kérdések
- • Erősítő mindig és mindig
- • Készülékek kapcsolási rajzai
- • Forrasztópákák - melyik miért jó
- • Vaillant kazán Arduino vezérlése
- • LED-es villogó fényfüzér
- • Elektromos roller
- • LCD TV probléma
- • Akkumulátor töltő
- • Számítógép hiba, de mi a probléma?
- • Varrógép elektronika
- • Videoton EA 6383 s (tuning)
- • ZC-18 kazán
- • Gázkazán vezérlő hibák
- • IPTV, azaz, TV-zés internet szolgáltatón keresztül
- • Szobatermosztát bekötése
- • Vicces - mókás történetek
- • Sprint-Layout NYÁK-tervező
- • Hibrid erősítő
- • Lemezjátszó beállítása, javítása
- • ESP32 bootloader
» Több friss téma
|
Fórum » PIC programozása C nyelven, C-Compiler
Több szem többet lát. Egyből meglátsz ilyen lehetőségeket. ÉN MEG NEM! :@
Köszönöm nagyon a hozzászólást! Javítottam is.
Találtam egy ilyet:
int szamlalo = 0;
void megszakitas(){
if(INTCON.INTF == 1 ){
szamlalo++;
INTCON.INTF = 0;
}
}
Az INTF-et aláhúzza a fordító... Na gondolom, hogy az én PIC18F252-nek megfelelő interrupt kellene, igaz? Ezt az adatlapjában találom, azaz nem találom...
Na most akkor szükségem lenne olyan késleltető rutinra amit ms-onként tudok beállítani. 32MHz-es kvarccal megy egyébként a PIC így ehhez kellene. Nézegettem a neten de nem találok. Ami érdekes mert assembly kódot fél perc alatt találtam mikor anno az kellett.
A C18 nem szereti a hosszú és kacifántos elérési utakat.
Idézet: „D:\Elektronika\Projektek\Projektek-2013\PIC-es panelmero III - C\PIC-es panelmero III - C.mcp”
Majdnem biztosan kiakadáshoz fog vezetni...
Nem akarlak nadyon lelombozni:
- C18 nem támogatja a 32 bitnél hosszabb számábrázolást, kínszenvedés lesz megcsináni. Még szerencse, hogy az if (STATUSbits.C) működik...
- Amit Potyo írt a függvények paraméterezéséről, visszatérési értékeiről, az szép és egyszerűen leírható, de a kontroller ugyan azt fogja csinálni, amit az assembly megoldás: Átmeneti globális (ACCESS RAM) változókba fogja másolni vagy software stack -re teszi a paraméreteket és a visszatérési értékeket - hosszabb, lassabb kódot eredményezhet. Ha egy utasítás "túl" bonyolult megint csak átmeneti változólat fog használni.
LATCbits.LATC5 = PORTAbits.RA2 sokkal hoszzabb, mint az
if (PORTAbits.RA2) LATCbits.LATC5 = 1;
if (!PORTAbits.RA2) LATCbits.LATC5 = 0;
ami csak 4 utasítás...
- "Ha átváltasz assemblyre, akkor ott minden úgy fog történni, ahogy assemblyben megszoktad." Ha egy C függvényben a fordító meglát egy _asm -mel kezdődő sort, a függvényben nem optimalizál. Ha ez egy jó hosszú példány (main, isr, stb.) volt, akkor nagy marad a kód.
Egyszóval igencsak előfordulhat, hogy nem fog beférni C -ben megírva az összes funkció, ha az assembly megoldás kitöltötte a kontroller harmadát - felét. Jobb ezt előre tudni, és egyből nagyobb kontrollerre kezdeni. Ha nincs nagyobb memóriájú kompatibilis kontroller... marad az assembly. A hozzászólás módosítva: Szept 19, 2013
#define Fosc 32000000L // 32MHz
#include <delays.h>
_delay_ms(3); A hozzászólás módosítva: Szept 19, 2013
Idézet: „Error - could not find definition of symbol '_delay_ms' in file './PIC-es panelmero III - C.o'.”
Ez szép és jó lenne, ha a Mc konzekvens lenne a fordítóiban..
Most nézem, hogy a C18 -ban más delay megoldások vannak:
#ifndef __DELAYS_H
#define __DELAYS_H
/* PIC18 cycle-count delay routines.
*
* Functions:
* Delay1TCY()
* Delay10TCY() // 17Cxx only
* Delay10TCYx()
* Delay100TCYx()
* Delay1KTCYx()
* Delay10KTCYx()
*/
/* For definition of Nop() */
#include <p18cxxx.h>
/* Delay of exactly 1 Tcy */
#define Delay1TCY() Nop()
#define PARAM_SCLASS auto
/* Delay of exactly 10 Tcy */
#define Delay10TCY() Delay10TCYx(1)
/* Delay10TCYx
* Delay multiples of 10 Tcy
* Passing 0 (zero) results in a delay of 2560 cycles.
* The 18Cxxx version of this function supports the full range [0,255]
* The 17Cxxx version supports [2,255] and 0.
*/
void Delay10TCYx(PARAM_SCLASS unsigned char);
/* Delay100TCYx
* Delay multiples of 100 Tcy
* Passing 0 (zero) results in a delay of 25,600 cycles.
* The full range of [0,255] is supported.
*/
void Delay100TCYx(PARAM_SCLASS unsigned char);
/* Delay1KTCYx
* Delay multiples of 1000 Tcy
* Passing 0 (zero) results in a delay of 256,000 cycles.
* The full range of [0,255] is supported.
*/
void Delay1KTCYx(PARAM_SCLASS unsigned char);
/* Delay10KTCYx
* Delay multiples of 10,000 Tcy
* Passing 0 (zero) results in a delay of 2,560,000 cycles.
* The full range of [0,255] is supported.
*/
void Delay10KTCYx(PARAM_SCLASS unsigned char);
#endif
A hozzászólás módosítva: Szept 19, 2013
Idézet: „C18 nem támogatja a 32 bitnél hosszabb számábrázolást, kínszenvedés lesz megcsináni.”
Az assembly-nél mindenképp jobb lesz az biztos. De egyébként van másik C fordító ami 18F-es PIC-ekhez jó és támogatja 32 bitnél nagyobb számábrázolást? Mert még szinte sehol nem tartok, úgyhogy ha van jobb akkor legyen az!
Idézet: „Egyszóval igencsak előfordulhat, hogy nem fog beférni C -ben megírva az összes funkció, ha az assembly megoldás kitöltötte a kontroller harmadát - felét.”
Hát, a DC-t mérő panelmérőm asm programja a 18F25K80 programmemóriáját kb harmadában lefoglalja (5755/16384). De úgy gondoltam hogy a kritikus részeket asm-ben írnám úgyis. Csak az hogy nem kell bájtonként összeadnom, kivonnom, szoroznom, összehasonlítanom, hatalmas segítség lenne. És nem is az egyszerűbb programozás miatt mert megírok én asm-ben szinte bármit, csak nagyon nehezen átlátható a végeredmény. Igazából az átláthatósága miatt érdekel a C.
Idézet: „A C18 nem szereti a hosszú és kacifántos elérési utakat.”
Hát az ő kedvéért nem fogom átírni a számítógépemen a könyvtárszerkezetet. Az assembly-nél is mindig mikor bemásoltam ide a fórumba kódrészleteket akkor mindenki rögtön lekiabálta a fejemet hogy ne írjak áéöőüűú betűket a címkéknek meg a regisztereknek, de SOHA nem okozott ez problémát.
A fájlnevet átírom majd rövidebbre és szóközmentesre azért. Az első alkalomkor amikor kiderül hogy ez okoz hibát akkor megkövetlek benneteket és létrehozok egy külön mappát a C programjaimnak ami rövid lesz és nem lesz benne speciális karakter. Az assembly-nél ugyan így voltam az ékezetes karakterekkel, aztán azóta is várom az alkalmat (hogy hibát okozzon).
(#) |
Attila86 válasza (Felhasználó 15355) hozzászólására (») |
Szept 19, 2013 |
|
/ |
|
|
Idézet: „Error - could not find definition of symbol 'Delay_ms' in file './PIC-es panelmero III - C.o'.”
Elfogadom, hogy nem hiszel a tanácsomnak...
Ajánlom, hogy alaposan olvasgasd az alábbi linken levő topikot:
Microchip forum C18 topic
Különös tekintettel az alábbira:
Source file path exceeds 62 characters
D:\Elektronika\Projektek\Projektek-2013\PIC-es panelmero III - C\PIC-es panelmero III - C:
A path 65, a file névével együtt 91 karakter.
Idézet: „Hát az ő kedvéért nem fogom átírni a számítógépemen a könyvtárszerkezetet.”
Egyszer kelljen átvinned az ilyen könyvtáerszerkezetet más operációs rendszerre. Kipróbáltam ... nem egy élvezet. A hozzászólás módosítva: Szept 19, 2013
Sajnos csak az XC8 ismeri a _delay_ms -t, a C18 csak az itt látható delay -eket ismeri. A hozzászólás módosítva: Szept 19, 2013
Idézet: „van másik C fordító ami 18F-es PIC-ekhez jó és támogatja 32 bitnél nagyobb számábrázolást? Mert még szinte sehol nem tartok, úgyhogy ha van jobb akkor legyen az!”
Erre kérlek válaszoljatok mert addig inkább bele sem kezdek semmibe.
Én nem találkoztam még ilyennel...
Oké. Akkor maradjak a C18-nál? Vagy most olvasgattam erről a HI-TECH C-ről, az jobb lenne? A Kónya-könyv azt írja hogy az nem 18F-ekhez van kitalálva de a net mást mond.
Volt Hi-Tech 18F-re is, bár kevésbé volt elteredt, mert 18F-re volt gyári fordító is. Viszont a Microchip néhány éve megvette a komplett Hi-Tech céget, és elvileg a Hi-Tech fordítóból keletkezett az XC8 néven árult fordító, amivel immár az összes 8 bites kontrollerre lehet fordítani. Tehát jelen állás szerint van a C18 és az XC8 18F-re, de kb. ugyanazt tudja mindkettő.
Hi-Tech C gyakorlatilag már nincs. Felvásárolta a Microchip a céget, a termékeit beleolvasztotta a saját termékeibe (ami konkrétan a C18 volt - tehát azt se fejlesztik már ezen a néven), így most már csak XC8 van, az örökölte mindazt, amit a Microchip és a Hi-Tech összekalapált a 8-bites PIC-ekhez.
Ezen felül van még a CCS meg a mikroC, mindkettő pénzes, és megvan a maguk baja (a CCS-nek az, hogy a világon semmivel se kompatibilis, C-nek is csak erős túlzással nevezhető; a mikroC-nek meg az, hogy kevesen használják, ezért bétatesztelőnek is jelentkezik, aki használja).
Létezik még az SDCC nevű open source cucc, ami nem rossz, de messze van még attól, hogy az XC8 kihívója lehessen. Cserébe azt írsz bele a forrásába, amit kedved tartja, már persze ha az idő és a tudás hiánya nem gátol meg benne.
Ha engem kérdezel, XC8, mivel annak van értelmes jövője (C18-ból és a legutolsó Hi-Tech fordítóból már nem lesz új release). A free mode-járól már többen értekeztek, szerintem nem sok mindenre jó.
Na, akkor legyen ez az XC8 és akkor ígérem létrehozok neki egy barátságosabb elérési utat!
És akkor most jön megint az a rész amikor valaki rám ír privátban hogy honnan lehet ezt az XC8 fordítót költséghatékonyan beszerezni.
HI-TECH PIC18 teljes verzióban elég komoly... De nekem nagyon magas a használata.
Mondjuk azt, hogy programoztam már MCU-t assembly-ben, alap dolgokat átlátok, de például egy kijelző vezérlést kicsit nehézkes volt megírnom... Amikor írtam vagy 100 sort és az eredményül kiírta nekem a kijelzőre, hogy REKA, akkor már boldog voltam. De túl sokat kell dolgozni benne. Úgyhogy inkább a C nyelv.
Sajnos nem bírok vele. Valaki segítsen...
Mindig újraindul a gépezet miután kiírja a demo szöveget az LCD-re és indulna az időzítő...
Hol rontom el?
// Lcd beállítása
sbit LCD_RS at LATC7_bit;
sbit LCD_RW at LATC6_bit;
sbit LCD_EN at LATC5_bit;
sbit LCD_D4 at LATB4_bit;
sbit LCD_D5 at LATB5_bit;
sbit LCD_D6 at LATB6_bit;
sbit LCD_D7 at LATB7_bit;
sbit LCD_RS_Direction at TRISC7_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_RW_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_BCK at LATB3_bit;
sbit LCD_BCK_Direction at TRISB3_bit;
// Lcd beéllítás vége
unsigned long int ADC_Value1, ADC_Value2, Voltage, Ampere, POWER;
unsigned szamlalo, tick;
char *display_v1 = "U=00.0V";
char *display_v2 = "I=00.0A";
char *display_v3 = "POWER => 000W";
char txt2[] = " SP LCD POWER ";
char txt3[] = "ver 1.1";
void megszakitas(){
if(TMR0IF_bit){
szamlalo++;
TMR0IF_bit = 0;
TMR0L = 0;
}
}
void main() {
ADC_init();
TRISA = 0b00001011;
TRISB = 0b00000000;
TRISC = 0b00000000;
// ADCON1=0x05; // Külső referencia (Vref+) ha szükséges
LCD_RW_Direction = 0;
LCD_RW = 0;
delay_ms(50);
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
LCD_BCK_Direction = 0;
LCD_BCK = 1; // LCD háttérvilágítás bekapcsolása...
Lcd_Out(1,2,txt2); // DEMO szöveg kiiratása
Lcd_Out(2,5,txt3); // DEMO szöveg kiiratása
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
// Megszakítás és időzítő beállítása
TMR0ON_bit = 0; // TMR0 kikapcs
INTCON = 0xA0; // megszakítás engedélyezése TMR0-án
TMR0IE_bit = 1; // TMR0 Overflow Interrupt Flag bit
T08BIT_bit = 1; // TMR0 8bites
T0CS_bit = 0; // Timer0 Clock Source Select bit
PSA_bit = 0; // prescaler
// prescaler
// 111 = 1:256 Prescale value
// 110 = 1:128 Prescale value
// 101 = 1:64 Prescale value
// 100 = 1:32 Prescale value
// 011 = 1:16 Prescale value
// 010 = 1:8 Prescale value
// 001 = 1:4 Prescale value
// 000 = 1:2 Prescale value
T0PS0_bit = 1;
T0PS1_bit = 1;
T0PS2_bit = 1;
TMR0L = 0;
szamlalo = 0;
tick = 0;
TMR0ON_bit = 1; // időzítő indítása
do {
ADC_Value1 = ADC_Read(0);
Voltage = (50 * 10 * ADC_Value1) / 1023 ; // AD értékének Feszültséggé alakítása
ADC_Value2 = ADC_Read(1);
Ampere = (50 * 4 * ADC_Value2) / 1023; // AD értékének Árammá alakítása
POWER = (Voltage * Ampere) / 100; // Teljesítmény számítás
display_v1[2] = (Voltage /100) +48 ;
display_v1[3] = (Voltage /10)%10 +48;
display_v1[5] = Voltage %10 +48;
Lcd_Out(1,1,display_v1);
display_v2[2] = (Ampere /100) +48 ;
display_v2[3] = (Ampere /10)%10 +48;
display_v2[5] = Ampere %10 +48;
Lcd_Out(1,10,display_v2);
//display_v3[11] = POWER /1000 +48 ; // Ha szükséges 4 számjegyű kijelzés 1000W felett...
display_v3[12] = (POWER /100)%10 +48;
display_v3[13] = (POWER /10)%10 +48;
display_v3[14] = POWER %10 +48;
Lcd_Out(2,1,display_v3);
if (POWER >= 800){ // 800W felett a háttérvilágítás majd villogna valamitől
LCD_BCK = 0;
}
} while(1);
}
WATCHDOG ki van offolva...
De azóta már rájöttem arra, hogy ha azt írom akkor nem tetszik a fordítónak. Viszont ha angolba átmegyek és nem problémázik és sikerült is megoldani a dolgot elvileg. Most meg letöltve a PIC-re működik a program, de amikor elérem a 800 W villogás határát elkezd az AD megbolondulni és ugrál a mért érték... :S
Jelenleg így tudtam megoldani. Biztos van ettől jobb megoldás is, csak még én nem tudom.
// Lcd beállítása
sbit LCD_RS at LATC7_bit;
sbit LCD_RW at LATC6_bit;
sbit LCD_EN at LATC5_bit;
sbit LCD_D4 at LATB4_bit;
sbit LCD_D5 at LATB5_bit;
sbit LCD_D6 at LATB6_bit;
sbit LCD_D7 at LATB7_bit;
sbit LCD_RS_Direction at TRISC7_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_RW_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_BCK at LATB3_bit;
sbit LCD_BCK_Direction at TRISB3_bit;
// Lcd beéllítás vége
unsigned long int ADC_Value1, ADC_Value2, Voltage, Ampere, POWER;
unsigned szamlalo, tick;
char *display_v1 = "U=00.0V";
char *display_v2 = "I=00.0A";
char *display_v3 = "POWER => 000W";
char txt2[] = " SP LCD POWER ";
char txt3[] = "ver 1.2";
void interrupt(){
if(TMR0IF_bit){
szamlalo++;
TMR0IF_bit = 0;
TMR0L = 0;
}
}
void main() {
ADC_init();
TRISA = 0b00000011;
TRISB = 0b00000000;
TRISC = 0b00000000;
// ADCON1=0x05; // Külső referencia (Vref+) ha szükséges
LCD_RW_Direction = 0;
LCD_RW = 0;
delay_ms(50);
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
LCD_BCK_Direction = 0;
LCD_BCK = 1; // LCD háttérvilágítás bekapcsolása...
Lcd_Out(1,2,txt2); // DEMO szöveg kiiratása
Lcd_Out(2,5,txt3); // DEMO szöveg kiiratása
Delay_ms(3000);
Lcd_Cmd(_LCD_CLEAR);
// Megszakítás és időzítő beállítása
TMR0ON_bit = 0; // TMR0 kikapcs
INTCON = 0xA0; // megszakítás engedélyezése TMR0-án
TMR0IE_bit = 1; // TMR0 Overflow Interrupt Flag bit
T08BIT_bit = 1; // TMR0 8bites
T0CS_bit = 0; // Timer0 Clock Source Select bit
PSA_bit = 0; // prescaler
// prescaler
// 111 = 1:256 Prescale value
// 110 = 1:128 Prescale value
// 101 = 1:64 Prescale value
// 100 = 1:32 Prescale value
// 011 = 1:16 Prescale value
// 010 = 1:8 Prescale value
// 001 = 1:4 Prescale value
// 000 = 1:2 Prescale value
T0PS0_bit = 1;
T0PS1_bit = 1;
T0PS2_bit = 1;
TMR0L = 0;
szamlalo = 0;
tick = 0;
TMR0ON_bit = 1; // időzítő indítása
do {
ADC_Value1 = ADC_Read(0);
Voltage = (50 * 10 * ADC_Value1) / 1023 ; // AD értékének Feszültséggé alakítása
ADC_Value2 = ADC_Read(1);
Ampere = (50 * 4 * ADC_Value2) / 1023; // AD értékének Árammá alakítása
POWER = (Voltage * Ampere) / 100; // Teljesítmény számítás
display_v1[2] = (Voltage /100) +48 ;
display_v1[3] = (Voltage /10)%10 +48;
display_v1[5] = Voltage %10 +48;
Lcd_Out(1,1,display_v1);
display_v2[2] = (Ampere /100) +48 ;
display_v2[3] = (Ampere /10)%10 +48;
display_v2[5] = Ampere %10 +48;
Lcd_Out(1,10,display_v2);
//display_v3[11] = POWER /1000 +48 ; // Ha szükséges 4 számjegyű kijelzés 1000W felett...
display_v3[12] = (POWER /100)%10 +48;
display_v3[13] = (POWER /10)%10 +48;
display_v3[14] = POWER %10 +48;
Lcd_Out(2,1,display_v3);
if (szamlalo >= 9){
LCD_BCK = 1;
szamlalo=0;
}
if ((POWER >= 800)&&(szamlalo == 8)){ // 800W felett a háttérvilágítás majd villog
LCD_BCK = ~LCD_BCK;
szamlalo=0;
}
} while(1);
}
Mondjuk azt nem ártana megmondani a fordítónak, hogy a megszakítás vagy interrupt nevű függvény az a megszakítási rutin akar lenni. Milyen fordító is ez?
Ez a hú de szuper mikroC fordítója... Kénytelen vagyok ezt használni, mert van benne LCD kezelő függvény ami sokat segített, mert MPLAB C18 fordítója, meg a HI-TECH is kifogott rajtam. Találtam itt hobbielektronikán LCD drivert C18 fordítóhoz, háát... Valamit vagy nem jól csináltam, de kiírta a szöveget, viszont bevillantak ilyen extra karakterek, meg furcsán működtette a kijelzőt. Úgyhogy a mikroC mellett kellett dönteni. De ha segítséget kapok, akkor biztos átszervezném C18-ra a mostani programot. Egyébként most szépen működik minden a jelenlegi állás szerint. Annyi van, hogy rájöttem ha ilyen nagy számokat osztok be, pontosabb eredményt kapok. Ha a nullákat lefaragom akkor pontatlanabb az eredmény.
Még annyit szeretnék, hogy lehetne megoldani azt, hogy a nullák a kijelzőn ne jelenjenek meg, csak akkor amikor épp arra a helyiértékre is szükség van. Tehát ne 001W legyen kiírva, hanem csak 1W.
// Lcd beállítása
sbit LCD_RS at LATC7_bit;
sbit LCD_RW at LATC6_bit;
sbit LCD_EN at LATC5_bit;
sbit LCD_D4 at LATB4_bit;
sbit LCD_D5 at LATB5_bit;
sbit LCD_D6 at LATB6_bit;
sbit LCD_D7 at LATB7_bit;
sbit LCD_RS_Direction at TRISC7_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_RW_Direction at TRISC6_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_BCK at LATB3_bit;
sbit LCD_BCK_Direction at TRISB3_bit;
// Lcd beéllítás vége
unsigned long long ADC_Value1, ADC_Value2, Voltage, Ampere, POWER;
unsigned szamlalo, tick;
char *display_v1 = "U=00.0V";
char *display_v2 = "I=00.0A";
char *display_v3 = "POWER => 0000W";
char txt2[] = " SP LCD POWER ";
char txt3[] = "ver 1.2";
void interrupt(){
if(TMR0IF_bit){
szamlalo++;
TMR0IF_bit = 0;
TMR0L = 0;
}
}
void main() {
ADC_init();
TRISA = 0b00000011;
TRISB = 0b00000000;
TRISC = 0b00000000;
// ADCON1=0x05; // Külső referencia (Vref+) ha szükséges
LCD_RW_Direction = 0;
LCD_RW = 0;
delay_ms(50);
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
LCD_BCK_Direction = 0;
LCD_BCK = 1; // LCD háttérvilágítás bekapcsolása...
Lcd_Out(1,2,txt2); // DEMO szöveg kiiratása
Lcd_Out(2,5,txt3); // DEMO szöveg kiiratása
Delay_ms(3000);
Lcd_Cmd(_LCD_CLEAR);
// Megszakítás és időzítő beállítása
TMR0ON_bit = 0; // TMR0 kikapcs
INTCON = 0xA0; // megszakítás engedélyezése TMR0-án
TMR0IE_bit = 1; // TMR0 Overflow Interrupt Flag bit
T08BIT_bit = 1; // TMR0 8bites
T0CS_bit = 0; // Timer0 Clock Source Select bit
PSA_bit = 0; // prescaler
// prescaler
// 111 = 1:256 Prescale value
// 110 = 1:128 Prescale value
// 101 = 1:64 Prescale value
// 100 = 1:32 Prescale value
// 011 = 1:16 Prescale value
// 010 = 1:8 Prescale value
// 001 = 1:4 Prescale value
// 000 = 1:2 Prescale value
T0PS0_bit = 1;
T0PS1_bit = 1;
T0PS2_bit = 1;
TMR0L = 0;
szamlalo = 0;
tick = 0;
TMR0ON_bit = 1; // időzítő indítása
do {
ADC_Value1 = ADC_Read(0);
Voltage = (5000 * 10 * ADC_Value1) / 1023 ; // AD értékének Feszültséggé alakítása
ADC_Value2 = ADC_Read(1);
Ampere = (5000 * 4 * ADC_Value2) / 1023; // AD értékének Árammá alakítása
POWER = (Voltage * Ampere) / 1000000; // Teljesítmény számítás
display_v1[2] = (Voltage /10000) +48 ;
display_v1[3] = (Voltage /1000)%10 +48;
display_v1[5] = (Voltage /100) %10 +48;
Lcd_Out(1,1,display_v1);
display_v2[2] = (Ampere /10000) +48 ;
display_v2[3] = (Ampere /1000)%10 +48;
display_v2[5] = (Ampere /100) %10 +48;
Lcd_Out(1,10,display_v2);
// display_v3[8] = (POWER /100000)%10 +48;
// display_v3[9] = (POWER /10000) +48;
display_v3[11] = (POWER /1000) +48;
display_v3[12] = (POWER /100)%10 +48;
display_v3[13] = (POWER /10)%10 +48;
display_v3[14] = (POWER /1)%10 +48;
Lcd_Out(2,1,display_v3);
if (szamlalo >= 10){
LCD_BCK = 1;
szamlalo=0;
}
if ((POWER >= 800)&&(szamlalo == 8)){ // 800W felett a háttérvilágítás majd villog
LCD_BCK = ~LCD_BCK;
szamlalo=0;
}
} while(1);
}
Üdv. C-ben írok egy proramot amely körülbelül 15 ledet futtat végig majd vissza az első ledig és elalszik. De stack overflow üzenettel a szimulátor nem tudja működtetni a programot. Valamilyen túlcsordulás azt tudom de hogy miként kéne orvosolnom hogy ennyi lábat ki és be tudjak kapcsolni elég gyorsan azt nem tudom
Valószínű rossz a program...
Értem, bemásolom hogy próbálkoztam eddig: void main() {
TRISB = 0; // PORTB all output to LED
PORTB = 0;
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;
Ez így nem is fordul le, mert hiányzik a main lezáró kapcsos zárójel.
A másik, hogy ha azt szeretnéd, hogy valami folyamatosan működjön, akkor azt ciklusba kell szervezni, vagy ciklus magjába kell tenni. Ha csak egyszer akarod, hogy lefusson, akkor a művelet végére egy végtelen ciklust kell tenni, különben a program nem áll meg, elkóricál olyan memória területekre, ahol véletlenszerű parancsok vannak. Tehát ha csak egyszer akarod lefuttatni, akkor tegyél a 29. sorra egy while(1); -et.
Bocsi, a programom ezzel kezdődik a többit és a kapcsos zárójelet már nem másoltam be. De hiába a while parancs ugyanúgy rossz Egyszer kell amúgy lefutnia a program elején.
|
|