16F648A Uart MikroC

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

> Jag menar som en int, decimalt eller hex...

men kör med hex då, så slipper du (som vfr också säger) allt pyssel
med binära överföringar. Om du inte har väldigt speciella krav på
prestanda och bandbreddsutnyttjande i överföringen, kör alltid med
ASCII baserad överföring och koda om i ändarna.
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

Det skulle betyda att jag måste konvertera strängen till en int för att ställa ett pwm värde. Någon som vet hur man gör det i Mikroc, letade men ser inte ut att finnas nått lib. Eller går det att göra utan int helt?

Kod: Markera allt

int uart_rd;
unsigned int pwm0; //maintained by interrupt code
unsigned int pwmValue0 = 0; //set by main code
unsigned int pwm1; //maintained by interrupt code
unsigned int pwmValue1 = 0; //set by main code
unsigned int pwm2; //maintained by interrupt code
unsigned int pwmValue2 = 0; //set by main code
unsigned int pwm3; //maintained by interrupt code
unsigned int pwmValue3 = 0; //set by main code

void interrupt() { //called by timer
  pwm0 += pwmValue0;
  if (pwm0 & 0x08) //3bits pwm
  PORTA.F0 = 0;
  else
  PORTA.F0 = 1;
  pwm0 &= 0x07; //clear overflow bit
  pwm1 += pwmValue1;
  if (pwm1 & 0x100) //8bits pwm
  PORTA.F1 = 1;
  else
  PORTA.F1 = 0;
  pwm1 &= 0xFF; //clear overflow bit
  pwm2 += pwmValue2;
  if (pwm2 & 0x100) //8bits pwm
  PORTA.F2 = 1;
  else
  PORTA.F2 = 0;
  pwm2 &= 0xFF; //clear overflow bit
  pwm3 += pwmValue3;
  if (pwm3 & 0x100) //8bits pwm
  PORTA.F3 = 1;
  else
  PORTA.F3 = 0;
  pwm3 &= 0xFF; //clear overflow bit
  TMR0 = 96;                // Timer TMR0 is returned its initial value
  INTCON = 0x20;            // Bit T0IE is set, bit T0IF is cleared

}


void main() {
  PCON.OSCF = 1;
  
  CMCON = 7;
  PORTA = 0;
  TRISA = 0;
  
  PORTB = 0;
  TRISB = 0;
  
  OPTION_REG = 0b10000000;        // Prescaler is assigned to timer TMR0
  TMR0 = 96;                // Timer T0 counts from 96 to 255
  INTCON = 0xA0;            // Enable interrupt TMR0

  UART1_Init(9600);              // Initialize UART module at 9600 bps
  Delay_ms(100);                 // Wait for UART module to stabilize


  while (1) {                    // Endless loop
   if (UART1_Data_Ready()) {     // If data is received,
     uart_rd = UART1_Read();     //   read the received data,
     if (uart_rd == 1 ) {
        while (1) {
           if (UART1_Data_Ready()) {     // If data is received,
              uart_rd = UART1_Read();
              pwmValue1 = uart_rd;
              break;
           }
        }
     }
     if (uart_rd == 2 ) {
        while (1) {
           if (UART1_Data_Ready()) {     // If data is received,
              uart_rd = UART1_Read();
              pwmValue2 = uart_rd;
              break;
           }
        }
     }
     if (uart_rd == 3 ) {
        while (1) {
           if (UART1_Data_Ready()) {     // If data is received,
              uart_rd = UART1_Read();
              pwmValue3 = uart_rd;
              break;
           }
        }
     }
     if (uart_rd == 4 ) {
        while (1) {
           if (UART1_Data_Ready()) {     // If data is received,
              uart_rd = UART1_Read();
              pwmValue0 = uart_rd;
              break;
           }
        }
     }
     if (uart_rd == 10 ) { pwmValue0 = 0; }
     if (uart_rd == 11 ) { pwmValue3 = 0; pwmValue2 = 0; pwmValue1 = 0; pwmValue0 = 0; }

   }
  }
}
EDIT: missade en code tag
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

Jag vet inte, men det känns lite som att du blandar ihop själva överföring
med representationen av värdet i vardera änden. Det är ju två helt olika
saker.

Bara för att klara ut ett par saker...

Du ska överföra ett värde från en PC till en PIC ? Eller är det tvärtom ?

Vilket intervall har du på det värde som ska överföras ?
Av din kod ser det ut att vara 0- 255 (decimalt), eller "00" - "FF" överfört som hex.
Så då behöver du konvertera "0" - "F" till ett värde 0 - 15 (decimalt) och
ta första teckenet * 16 (dec) och lägga till det andra. Konverteringen från HEX
kan ske antingern med några redaer kod eller med en lookuptabell.

Vad har du för format på ett "paket" i överföringen ?

> Det skulle betyda att jag måste konvertera strängen till en int för att ställa ett pwm värde.
> Någon som vet hur man gör det i Mikroc,

Manualen kanske ?? Fungerade inte xtoi() ?
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

Jag ska överföra från PC till PIC.

>Vilket intervall har du på det värde som ska överföras ?
Det är långt, 0.5 som minst och uppåt (tex 0.5-5 sek) Så hastigheten är inte så noga.

>Vad har du för format på ett "paket" i överföringen ?
Nu skickar jag decimalt som int

>Fungerade inte xtoi() ?
Nej, känns mer som fel i lib än hos mig...

Kod: Markera allt

0 1 mikroCPIC1618.exe -MSF -DBG -pP16F648A -DL -O11111114 -fo4 -N"C:\Users\Pajn\Pic\16f648a-usart.mcppi" -SP"C:\Program Files (x86)\Mikroelektronika\mikroC PRO for PIC\defs\" -SP"C:\Program Files (x86)\Mikroelektronika\mikroC PRO for PIC\Uses\P16\" -SP"C:\Users\Pajn\Pic\" "16f648a-usart.c" "__Lib_Math.mcl" "__Lib_MathDouble.mcl" "__Lib_System.mcl" "__Lib_Delays.mcl" "__Lib_CStdlib.mcl" "__Lib_UART_b21.mcl"  
0 125 All files Preprocessed in 218 ms  
0 121 Compilation Started 16f648a-usart.c
58 1509 Generated baud rate is 9615 bps (error = 0.16 percent) 16f648a-usart.c
69 1508 Implicit conversion of int to ptr 16f648a-usart.c
106 122 Compiled Successfully 16f648a-usart.c
0 126 All files Compiled in 359 ms  
0 359 Unresolved extern 'isspace' __Lib_CStdlib.c
0 359 Unresolved extern 'isspace' __Lib_CStdlib.c
0 359 Unresolved extern 'isxdigit' __Lib_CStdlib.c
0 359 Unresolved extern 'isxdigit' __Lib_CStdlib.c
0 359 Unresolved extern 'isupper' __Lib_CStdlib.c
0 359 Unresolved extern 'isupper' __Lib_CStdlib.c
0 359 Unresolved extern 'tolower' __Lib_CStdlib.c
0 359 Unresolved extern 'tolower' __Lib_CStdlib.c
0 359 Unresolved extern 'isdigit' __Lib_CStdlib.c
0 359 Unresolved extern 'isdigit' __Lib_CStdlib.c
0 359 Unresolved extern 'isspace' __Lib_CStdlib.c
0 0  
0 102 Finished (with errors): 20 feb 2010, 15:39:00 16f648a-usart.mcppi
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

> >Vilket intervall har du på det värde som ska överföras ?
> Det är långt, 0.5 som minst och uppåt (tex 0.5-5 sek) Så hastigheten är inte så noga.

Hur menar du ? 0.5, 1.0, 1.5 ... 5.0 ?
Alltså bara ca 10 olika värden ??

Sen så om det är, säg, 100 olika värden så är det enklare att skicka det
som 1-100, vad det representerar i verkligheten är ganska ointressant
(d.v.s om det är sekunder, meter eller något annat). Det tar du om hand
om i respektive ände. Det beror ju även på hur det ska användas, upplösning
på PWM'en (eller vad det ska användas till) o.s.v.

> >Vad har du för format på ett "paket" i överföringen ?
> Nu skickar jag decimalt som int

ja, jo, det var inte så jag menade.
Hur ser första byten ut ? Och andra byten ? Tredje ? O.s.v...
D.v.s hur ser det "paket" ut som du tänker skicka ?
Vad har det för format tecken för tecken ?
DU kan inte bara skicka på något från PC'n utan att veta exakt
vad som kommer att skickas tecken för tecken, annars blir det
bara problem att tolka det i PIC'en.
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

Förlåt jag missförstod helt båda frågorna :doh:

>Vilket intervall har du på det värde som ska överföras ?
0-255 (eller 00-FF)

>Vad har du för format på ett "paket" i överföringen ?
Först en siffra 1-4 som talar om vilken pwm jag vill ändra och sedan 0-255 för att ställa in duty.

tex:
Sent: 1 (as number)
Sent: 100 (as number)
Sent: 4 (as number)
Sent: 4 (as number)

Där jag ställer pwm1 till 100(av 255, åtta bitars pwm alltså) och pwm0 till 4(av 8, tre bitars pwm alltså)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

OK... :-)
Det här kan verka lite tjatigt, men eftersom detta verkar vara lite
nytt för dig så kan det vara bra ändå... :-)

> Först en siffra 1-4

Och vad betyder det mer konkret ? Vad menar du med en "siffra" ?
Är det ASCII tecknen '1', '2', '3' och '4' ? (d.v.s h'31', h'32', h'33 och h'34' ?)
Eller är det en byte med värderna h'01', h'02, h'03' och h'04' ?
Det första är oftast att rekomendera.

> ...och sedan 0-255

Alltså sänt som h'00' - h'FF' som ett tecken ?
(Inte att rekomendera, som sagt tidigare. Bättre att
skicka det i hex format. Det blir enklare att felsöka och att
testa kommunikationen med en terminalemulator.)
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: 16F648A Uart MikroC

Inlägg av Icecap »

Hur skiljer du dessa värden ifrån varandra? Siffran '1' motsvarar 31h vilket även motsvarar ett PWM-värde.

Med "block" menas att man alltid sänder en mängd data som man kan hitta startpunkten på. Jag brukar ha en block som överför datan i text och startar med STX och avslutas med ETX, (ex: STX "1,234" ETX) detta kostar lite overhead men kan sniffas och man kan se vad det visar, det är enkelt att se om ett block börjar och slutar och lägger man en checksum med får man en viss säkerhet i om datan är korrekt.

Det kan även vara så att man sänder ett visst antal bytes och de bildar ett block. Man kan dela upp dom vid att det t.ex. ska vara en viss minimitid mellan varje block.

Lite tips: Med "FF" menar man 2 st bokstäver (i detta fall 'F') direkt efter varandra.
Med 'F' menas tecknet F (46h)
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

Ja, det är helt nytt för mig. Är ledsen om jag blandar ihop saker och ting.

>Och vad betyder det mer konkret ? Vad menar du med en "siffra" ?
Förut skickade jag som en byte med värdet men bytte nu till ASCII på den delen.

>Alltså sänt som h'00' - h'FF' som ett tecken ?
Ja, inte som ASCII.

>Bättre att skicka det i hex format.
Jag har börjat förstå det nu ;) Jag fattar dock fortfarande inte riktigt hur jag ska gå till väga för att senare konvertera det till en int, xtoi() eller atoi() funkar inte (ovan nämnda fel).

>Hur skiljer du dessa värden ifrån varandra?
Inte alls, man måste hålla reda på vad man skickar och alltid skicka "duty" efter att man har valt pwm.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: 16F648A Uart MikroC

Inlägg av vfr »

Då kommer du att få problem förr eller senare. Så fort sändare och mottagare kommer ur synk så kommer dom aldrig att hitta varandra igen. Det räcker med något överföringsfel i serielänken så är synkningen sabbad. Precis som Icecap säger så bör du definiera ett "paket" eller "block" av data med ett starttecken och ett sluttecken som avgränsar. Då kommer det iallafall i synk igen vid nästa paketstart. Det är också lätt att senare lägga på t.ex checksumma på paketen eller adressering av olika enheter. :D
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

> xtoi() eller atoi() funkar inte (ovan nämnda fel).

Är det inte bara så enkelt som att du inte har länkat med rätt lib ?
"Unresolved extern" (eller "Unresolved symbol" som det oftare brukar kallas)
beror nästan alltid på ett det saknas en lib fil i länkningen. I just fallet med
MikroC så är det sannolikt en .mcl fi som saknas. Det är dock lite
märkligt, enligt MikroC manualen så ska xtoi finnas i Stdlib, och det ser ju
ut som att du länker in den. Å andra sidan, de fel du har visat här inkldudera
ju inte xtoi, utan andra funktioner som finns i CType, och den finns inte
med bland de filer som du länker in. Kolla det ! Enligt manualen så
finns alla symboler som rapporteras i just CType...

Det hela är ju väldigt tydligt i den fel-logg som du postade.
Bara att plocka upp PDFäen och söka på t.ex "isspace" eller
någon av de andra symbolerna som raporteras. Då ser du direkt
att det är CType som saknas...
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

CType hjälpte, måste lära mig att använda manualen till MikroC mer...

Jag har försökt mig på ASCII nu men får det inte att funka något bra.

Kod: Markera allt

Sent: 1ffs
Received: 11ffs
Sent: ff2
Received: ff22
Sent: ffs
Received: ffs
Sent: 1s
Received: 11s
Sent: 1
Received: 11
Sent: 2
Received: 22
Sent: 11
Received: 1111
Sent: 01
Received: 011
Sent: 21
Received: 2211
Här är koden:

Kod: Markera allt

char uart_rds[4];
//[...]
  while (1) {                    // Endless loop
   if (UART1_Data_Ready()) {     // If data is received,
     UART1_Read_Text(uart_rds, 's', 3);
     UART1_Write_Text(uart_rds);
     if (uart_rds[0] == '1' ) {
        pwmValue1 = xtoi(uart_rds[1,2]);
        UART1_Write('1');
        UART1_Write_Text(uart_rds[1,2]);
     }
     if (uart_rds[0] == '2' ) {
        pwmValue2 = xtoi(uart_rds[1,2]);
     }
     if (uart_rds[0] == '3' ) {
        pwmValue3 = xtoi(uart_rds[1,2]);
     }
     if (uart_rds[0] == '4' ) {
        pwmValue0 = xtoi(uart_rds[1,2]);
     }
  }
och när jag lägger in lite tecken för stt se var han skickar vad:

Kod: Markera allt

     UART1_Write_Text(uart_rds);
     UART1_Write('-');
     if (uart_rds[0] == '1' ) {
        pwmValue1 = xtoi(uart_rds[1,2]);
        UART1_Write('1');
        UART1_Write('/');
        UART1_Write_Text(uart_rds[1,2]);
     } //likadant på 2, 3 och 4 också
så får jag

Kod: Markera allt

Sent: 150s
Received: 1-1/5-0-
Sent: 1ffs
Received: 1-1/f-f-
Varför skickar UART1_Write_Text(uart_rds); bara det första tecknet? Dessutom verkar inte xtoi(uart_rds[1,2]); fungera bra då pwm:en aldrig startar.
"s" ska alltså föreställa ett slut tecken men UART1_Read_Text(uart_rds, 's', 3); verkar ju släppa igenom annat utan att ha tagit emot s.
Däremot fungerar if (uart_rds[0] == '1' ) (eller annan berörd siffra) då den svarar dubbelt med den siffran samt "/"
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: 16F648A Uart MikroC

Inlägg av sodjan »

Väntar UART1_Write på att UART'en är "ledig" ??
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: 16F648A Uart MikroC

Inlägg av Pajn »

Det tog jag för givet, men det kanske man inte ska göra.
Jag la in en paus på 500µs(borde ju vara klar då) samt kör sprintl innan xtoi men det funkar fortfarande inte

Kod: Markera allt

     UART1_Read_Text(uart_rds, 's', 3);
     UART1_Write_Text(uart_rds);
     sprintl(string, uart_rds[1], uart_rds[2]);
        Delay_us(500);
     if (uart_rds[0] == '1' ) {
        pwmValue1 = xtoi(string);
        UART1_Write('1');
        UART1_Write('/');
        UART1_Write_Text(string);
     }
ger

Kod: Markera allt

Sent: 408s
Received: 4
Received: 0
Sent: 1ffs
Received: 1
Received: f
och ingen pwm.

Edit: Gillar inte sprintl, hexfilen går från 3 till 13kb med den aktiverad...
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: 16F648A Uart MikroC

Inlägg av Icecap »

"printf"-funktionen är ganska stor, den innehåller en hel del möjligheter för att formatera utskrift men är det för att skriva ut något i hex eller decimalt kan man klara sig med mycket enklare funktioner.

Och när man sänder bör man istället kolla om TX-registret är klar eller upptagen, det finns en flagga till detta.
500µs mellan varje karaktär... kör du 20kbaud eller mer? Kör man 9600 baud kan det sändas 960 tecken/sekund vilket ger drygt 1ms/tecken.
Skriv svar