Fórum témák
- • Alternativ HE találkozó(k)
- • Mágnes
- • Számítógép hiba, de mi a probléma?
- • Autóelektronika
- • Műterhelés építése
- • Opel Astra elektromos hibák
- • Felajánlás, azaz ingyen elvihető
- • Altium Designer
- • Lopásgátló építés
- • Kazettás magnó (deck) javítása
- • Villanyszerelés
- • Laptop javítás, tuning
- • Audiofil, High End Audio
- • Skoda Octavia elektromos probléma
- • Vásárlás, hol kapható?
- • Csirkeól ajtó automata
- • Rendelés külföldről (eBay - Paypal)
- • Weller páka (állomás)
- • Ráz a kültéri medence vize
- • TV hiba, mi a megoldás?
- • Hűtőgép probléma
- • Blaupunkt autórádió (magnó)
- • Elektronyika orosz digitális órák
- • Quad 405-ös erősítő tapasztalatok és hibák
- • Rádióamatőrök topikja
- • Muzeális készülékek-alkatrészek restaurálása
- • Elektromos kerékpár, robogó házilag
- • Műhelyünk felszerelése, szerszámai
- • Mikrohullámú sütő javítás, magnetron csere, stb.
- • Klíma szervizelés, javítás
- • Kapcsolási rajzot keresek
- • Tranzisztorok helyettesítése
- • Kondenzátor feltöltés
- • V-FET és SIT erősítő kapcsolások
- • Arduino
- • Jókívánság
- • Westen 240 Fi gázkazán hiba
- • ESP32-S3-Zero BOARD
- • TDA7294 végerősítő
- • Gitár Pickup
- • Klíma beszerelése, fűtés-hűtés házilag
- • Aggregátor feszültség szabályzó
- • Folyamatábrás mikrokontroller programozás Flowcode-dal
- • Rádió építés a kezdetektől a világvevőig
- • VF3 - 6 végerősítő
- • Villanypásztor
- • Mosógép vezérlők és általános problémáik
- • Villanymotor
- • 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
- • PLC alapismeretek
- • PIC - Miértek, hogyanok haladóknak
- • Páratartalom érzékelő
- • Kondenzátor
» Több friss téma
|
Fórum » PIC - Miértek, hogyanok haladóknak
Gondolom a terminalon latod a pontokat es az y-okat. Egyik megoldas, hogy a terminalt atallitod hex kiirasara, vagy a PICben atalakitod ASCII formatumra a szamokat es azt kuldod a terminalra. Esetleg elkuldhetned a Te altalad irt progit, es akkor biztosan tobbet lehetne mondani.
Udv Vili
Aham, terminálon irja igen a pontokat és az ipszilonokat. Termite, ezt a terminált használom.
Probálkoztam már a sprintf-es átalakitással, de ugyis csak vesszőket kaptam akárhova is érintettem az ADC bemenetet.
Itt a kód:
#include<plib.h>
#include<string.h>
#include "config.h"
#include "stdtypes.h"
#ifndef OVERRIDE_CONFIG_BITS
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
#pragma config BWP = OFF // Boot Flash Write Protect
#pragma config CP = OFF // Code Protect
#pragma config FNOSC = PRIPLL // Oscillator Selection
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable
#pragma config IESO = OFF // Internal/External Switch-over
#pragma config POSCMOD = HS // Primary Oscillator
#pragma config OSCIOFNC = OFF // CLKO Enable
#pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
#pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
#pragma config WDTPS = PS1 // Watchdog Timer Postscale
#pragma config FWDTEN = OFF // Watchdog Timer
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider
#pragma config FPLLMUL = MUL_20 // PLL Multiplier
//#pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
//#pragma config UPLLEN = OFF // USB PLL Enabled
#pragma config FPLLODIV = DIV_1 // PLL Output Divider
#pragma config PWP = OFF // Program Flash Write Protect
#pragma config DEBUG = OFF // Debugger Enable/Disable
#endif
/******* Serial parameters and variables *******/
#define DESIRED_BAUDRATE (57600) // The desired BaudRate
#define SYSTEM_FREQUENCY (80000000L) // defining the system's running frequency
#define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
#define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR
unsigned short int channel4; // conversion result as read from result buffer
unsigned int offset;
volatile unsigned char data;
int ADCValue;
void Wait_ms(WORD ms);
int main(void)
{
AD1PCFG = 0xFFFB;
AD1CON1 = 0x0000;
AD1CHS = 0x00020000;
AD1CSSL = 0;
AD1CON3 = 0x0002;
AD1CON2 = 0;
AD1CON1SET = 0x8000;
// SYSTEMConfig(SYSTEM_FREQUENCY, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
// configure and enable the ADC
// CloseADC10(); // ensure the ADC is off before setting the configuration
// define setup parameters for OpenADC10
// Turn module on | ouput in integer | trigger mode auto | enable autosample
// #define PARAM1 ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
// define setup parameters for OpenADC10
// ADC ref external | disable offset test | disable scan mode | perform 2 samples | use dual buffers | use alternate mode
// #define PARAM2 ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_2 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON
// define setup parameters for OpenADC10
// use ADC internal clock | set sample time
// #define PARAM3 ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15
// define setup parameters for OpenADC10
// set AN4 and AN5 as analog inputs
// #define PARAM4 ENABLE_AN4_ANA | ENABLE_AN5_ANA
// define setup parameters for OpenADC10
// do not assign channels to scan
// #define PARAM5 SKIP_SCAN_ALL
// use ground as neg ref for A | use AN4 for input A | use ground as neg ref for A | use AN5 for input B
// configure to sample AN4 & AN5
// SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEA_AN4 | ADC_CH0_NEG_SAMPLEB_NVREF | ADC_CH0_POS_SAMPLEB_AN5); // configure to sample AN4 & AN5
// OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4, PARAM5 ); // configure ADC using the parameters defined above
// EnableADC10(); // Enable the ADC
// Configure the proper PB frequency and the number of wait states
int pbClk;
pbClk = SYSTEMConfigPerformance(SYSTEM_FREQUENCY);
// Open UART2 with config1 and config2
OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value.
// Configure UART2 RX Interrupt with priority 2
ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
// Must enable glocal interrupts - in this case, we are using multi-vector mode
INTEnableSystemMultiVectoredInt();
// this will store the values sent over RS232
char RS232_Out_Buffer [64];
putsUART2("*** Hello From the Mechatronics Lab ***\r\n");
// start the infinite loop
while(1)
{
AD1CON1SET = 0x0002;
Wait_ms(100);
AD1CON1CLR = 0x0002;
while (!(AD1CON1 & 0x0001));
ADCValue = ADC1BUF0;
putcUART2(ADCValue);
// wait for the first conversion to complete so there will be valid data in ADC result registers
// while ( ! mAD1GetIntFlag() ) { }
// read the ADC
// offset = 8 * ((~ReadActiveBufferADC10() & 0x01)); // determine which buffer is idle and create an offset
// channel4 = ReadADC10(offset); // read the result of channel 4 conversion from the idle buffer
// sprintf(RS232_Out_Buffer, "Analog Input %d\r\n", channel4); // make the string
// putcUART2(RS232_Out_Buffer);
//Wait_ms(1500);
// mAD1ClearIntFlag();
} // end while(1)
} // end main
void Wait_ms(WORD delay) {
WORD i;
while(delay > 0){
for( i = 0; i < 8000; i ++){
;;
}
delay--;
}
}
Két fajta módszerrel is próbálkoztam, az egyik ki van commentálva.
Ez csak egy bájtot fog elküldeni.
Helyette ilyesmi kéne:
putcUART2(ADCValue);
putcUART2(ADCValue >> 8);
(Már régen progiztam C-ben, remélem jól írtam a >>-t  )
A terminálban csak a hex kódokat fogod látni, ahhoz, hogy ott szám legyen a PIC-ben ASCII kódokká kell konvertálnod a mért értéket és azokat elküldeni sorban.
Máskor, ha ilyen hosszú a kód, inkább txt-be másold és azt csatold.
Nem tudom milyen forditot hasznalsz es nem ismerem a Te putcUART2() fuggvenyedet, de pl normal printf () fvenynel ezt igy lehet megcsinalni: Aholis maga a printf fv. atalakitja decimalissa a szamot egyszeruen es fajdalommentesen.
Udv Vili
Na jó, de egy 16bites számot hiába alakít decimálissá, vagy ez ASCII kódokká alakítja helyiértékenkén és úgy küldi ki sorban?
A "fajdalom mentes" kifejezes amugy relativ -- printf eleg sok program memoriat fel tud emeszteni. Neha jobb az itoa hasznalata...
Igen, karakterekként írja ki, mintha pl. egy konzolra írnál ki egy számot. A printf az adott nyelvi környezettől függően valamilyen karakterküldő "primitívet" (pl. putch, putchar) fog meghívogatni minden egyes kiírandó karakterrel, azt, hogy ezt milyen néven és hogy kell megírni, hogy működjön is, az adott fordító manualjából kell kilesni.
Aha, köszi, én nem használtam még ilyen beépített dolgot. Ez biztosan az ASM miatt van.
Hali
Ezt tudjuk, de a kezdok szempontjabol, es ha van eleg nagy memoriad sokkal egyszerubb. Majd ha 98 % lesz a memoria telitettsege lehet gondolkodni mikent csokkentsuk a progi meretet. (vagy veszunk eggyel nagyobb PIC-et) De ha itoa fv-t hasznalsz akkor is kell printf, putc vagy valami amivel a terminalra kuldod.
Udv Vili
Egy übergagyi eljárással így lehet egy legfeljebb 16 bites számot hexában kiküldeni:
void out4hex(unsigned int t)
{
char c;
c=(char)((t>>12) & 0x0F);
if (c>9) c+=7;
putcUART2(c+'0');
c=(char)((t>>8) & 0x0F);
if (c>9) c+=7;
putcUART2(c+'0');
c=(char)((t>>4) & 0x0F);
if (c>9) c+=7;
putcUART2(c+'0');
c=(char)(t & 0x0F);
if (c>9) c+=7;
putcUART2(c+'0');
}
Szia,
Használtam ezt de ezzel sem müködik :
sprintf (RS232_Out_Buffer, "Analog Input %d\r\n", ADCValue )
putcUART2 (RS232_Out_Buffer );
gondolom ez is ugyanaz mint a printf csak itt átrakja ebbe a változóba, ami ki tudok küldeni rs232-esen
Amúgy nekem a terminálon megjelenik hexában is meg rendesen is. Pl. ha kiküldok a putcUART2("Hello world!") akkór azt ki tudom olvasni a terminálon.
Megpróbálom watt ötletét hátha azzal menni fog.
Hali
Mert strig-kent kellene kikuldeni. sprintf (RS232_Out_Buffer, "Analog Input %d\r\n", ADCValue )
putcUART2 ("%s", RS232_Out_Buffer );
a Te programodban a string hexa ertekeit kuldi ki nem ASCII-kent.
Jaj Köszi szépen, megoldódott.
Most kijön szépen a 0 és az 1023
ADCValue = ADC1BUF0;
sprintf (RS232_Out_Buffer, "Analog Input %d\r\n", ADCValue ); // make the string
putsUART2 (RS232_Out_Buffer );
ez a jó megoldás ha valaki még belebotlik ebbe a problémába.
Ha már itt vagyok, az lenne a következő kérdésem, hogy mért van az hogy van 4 darab PWM motor vezérlőm, külön külön szépen megy mindenik, de ha egyszerre akarom öket müködtetni akkór nem kapnak áramot a motrok. A HBridge az megkapja a teljes feszültséget, de mikór mind a 4 motórt akarom futtatni (egyszerre) akkór nem engedi át a HBridgen a feszültséget csak nagyon keveset, amitől a motrok éppen csak morrognak.
Van erre valami ötletetek? Ugyancsak PIC32-es, és minden ugyanaz mint az elöbb.
Kódrészlet:
unsigned int Pwm = 0;
unsigned char Mode = 0;
void Wait_ms(WORD ms);
int main(void)
{
/* Enable OC | 32 bit Mode | Timer2 is selected | Continuous O/P | OC Pin High , S Compare value, Compare value*/
OpenOC1( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0 ); // JH Port 7-12
OpenOC2( OC_ON | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0 ); // JD Port 1-6
//OpenOC3( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0 ); // JD Port 7-12
//OpenOC4( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0 ); // JE Port 7-12
/* Open Timer2 with Period register value */
OpenTimer2(T2_ON | T2_PS_1_1 | T2_SOURCE_INT, 0x2710); // PWM period = (PR2+1) x Prescale / SYS_FRECV
// PWM period = (39999+1) x 1 / 80000000
OpenTimer3(T3_ON | T3_PS_1_1 | T3_SOURCE_INT, 0x2710); // PWM period = (PR2+1) x Prescale / SYS_FRECV
// PWM period = (39999+1) x 1 / 80000000
/*
The expected output looks like the diagram below with approximately 6% duty-cycle
|| || ||
______||______||______||______
*/
while (1)
{
if ( Mode )
{
if ( Pwm < 10000 ) // ramp up mode
{
Pwm++; // If the duty cycle is not at max, increase
SetDCOC1PWM(Pwm); // Write new duty cycle
SetDCOC2PWM(Pwm); // Write new duty cycle
//SetDCOC3PWM(Pwm); // Write new duty cycle
//SetDCOC4PWM(Pwm); // Write new duty cycle
Wait_ms(1);
}
else
{
Mode = 0; // PWM is at max, change mode to ramp down
}
} // end of ramp up
else
{
if ( Pwm > 0 ) // ramp down mode
{
Pwm--; // If the duty cycle is not at min, decrease
SetDCOC1PWM(Pwm); // Write new duty cycle
SetDCOC2PWM(Pwm); // Write new duty cycle
//SetDCOC3PWM(Pwm); // Write new duty cycle
//SetDCOC4PWM(Pwm); // Write new duty cycle
Wait_ms(1);
}
else
{
Mode = 1; // PWM is at min, change mode ro ramp up
}
} // end of ramp down
}
/* Close Output Compare */
CloseOC2();
return (0);
}
Mitől resetel a PIC-em? A watchdog ki van kapcsolva. Ráadásul olyan helyről resetel ahol eddig minden probléma nélkül továbbment. A gyakorlatban és a szimulátorban is resetel. Mi okozhatja ezt?
Szerk.: Van egy "delay100ms" nevű időzítő szubrutinom. Ezt egy helyen közvetlen egymás után háromszor hívom meg és a második meghíváskor resetel a PIC.
Hohóóó... ha a szubrutint visszamásolom az inc fájlomból az asm fájlba és az inc-ben kikommentezem akkor nem resetel a PIC! Ez így elég rossz dolog... Mitől van ez?
Szerk.: Sajnos így is resetel csak később, egy későbbi rutin-hívásnál.
Stack overflow ? Esetleg.
Veremtar. A PIC-nel (18F) 31 szintu lehet. Ebben tarolja a szubrutinhivaskor es a megszakitaskor a visszateresi cimeket. Ha sok az egymasbaagyazott szubrutinhivas es meg 2 szintu megszakitast is hasznalsz, tul lehet lepni a hatart es akkor csinal hibakat. A STKFUL es a STKUNF biteket kell lesni a STPTR regiszterben. Magasabb szintu programnyelveknel a fordito automatikusan figyeli, de ASM-nel Neked kell figyelni ra.
UdV Vili
Ja akkor tudom mi az. Megnéztem és igen, a veremtár telítődése miatt resetel a PIC. Viszont erre nincs semmi oka! Van a programomban ez a három sor:
call delay100ms
call delay100ms
call delay100ms
Az elsőn még átmegy rendesen, aztán belép a másodikba és ott elkezdi dekrementálni az egyik regisztert (időzítés) aztán egyszercsak hirtelen a semmiből az STKPTR legfelső bitje H lesz és a PIC resetel. Mindezt mondom úgy, hogy az előző "call delay100ms" szubrutinból még hibátlanul visszatért. Sőt, nem hogy a veremtár 31. szintjét, de még csak a másodikat sem éri el a PIC mert ez a szubrutin-hívás a főprogramban történik (a legfelső szinten).
De ahogy nézem a probléma a megszakítás okozhatja valahogyan mert ha a GIE bitet nullára állítom az inicializáció után akkor már nem resetel a PIC (de nem is lép be soha a megszakításba). A megszakításból akárhova vissza tud ugrani a PIC, ugye?
hogy mért van az hogy van 4 darab PWM motor vezérlőm, külön külön szépen megy mindenik, de ha egyszerre akarom öket müködtetni akkór nem kapnak áramot a motrok. A HBridge az megkapja a teljes feszültséget, de mikór mind a 4 motórt akarom futtatni (egyszerre) akkór nem engedi át a HBridgen a feszültséget csak nagyon keveset, amitől a motrok éppen csak morrognak.
Van erre valami ötletetek? Ugyancsak PIC32-es, és minden ugyanaz mint az elöbb.
Hali
Idézet: „A megszakításból akárhova vissza tud ugrani a PIC, ugye?” termeszetesen. A keslelteteseket probald meg maskepp megoldani. Pl TMR0 IT-vel. Ha sok az egymasba agyazott szubrutin akkor eloferdulnek ezek a problemak. At kell szervezni a programot, hogy ne legyen annyi szubrutin hivas. Kesleltetest pl IT-ben flag billegtetessel is el lehet erni, es akkor nincs Delay100ms szubrutin, csak varsz egyhelyben a flag visszabillentesere.
Udv Vili
Szia!
Nézegetem a kódot de egyszerűen elképzelhetetlennek tartom hogy eljut 31 szintig a verem! Szerintem még csak 10-ig sem de 31-ig az tényleg lehetetlen! Ennyire azért nem komplex a programom.
Azt ki lehet valahogyan deríteni hogy hol éri el a 31. szintet?
Szerk.: Végignéztem a programot az összes call utasításra rákeresve hogy mik lehetnek egybe ágyazva és arra jutottam, hogy a legeslegrosszabb esetben is a verem mélysége 5 lehet.
A szimulaciokor bekapcsolod a Hardware Stack ablakot es voila lathato a stack mozgasa.
Hali
Esetleg meg lehet ilyen hiba a tablazatok olvasasakor is. Tulcimzed a tablazatot, vagy laphataron atnyul a tablazat.
Ez sem lehet mert dcfsnz és retlw párossal van megoldva mindhárom táblázatom, tehát nem a PC-hez adok hozzá.
Köszönöm, így már mindjárt látom a dolgokat! A reset vektorra ugrás előtt a verem tényleg a 31. szinten van!
De érdekes ez a verem, mert a 0. szintjéhez azt van írva hogy "Empty", az 1.-höz 0007FA, a 2.-hoz 000F62. A 3. és a 29. köztiekhez egyöntetűen 0006FE, a 30.-hoz 00007E és a 31.-hez 000DAE. Na ezt én nem értem. Hogyan lehet az hogy a 3. és a 29. szinteken ugyan az a cím van?
A szimulációnál nézd meg, hol jár a progid amikor arra részre pakol. Lehet, hogy véletlenül bennmaradt egy sor ami többször fut.
A verem alulcsordulásakor is resetel a proci, ha van egy kallódó return, vagy "függvény hívást" csinálsz goto utasítással call helyett. mindkettő okozhat ilyet, és ilyenkor lehet hogy a hibás rész nem is ott van, ahol kifagy a program
|
|