16F648A Uart MikroC
Re: 16F648A Uart MikroC
> 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.
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.
Re: 16F648A Uart MikroC
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?
EDIT: missade en code tag
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; }
}
}
}
Re: 16F648A Uart MikroC
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() ?
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() ?
Re: 16F648A Uart MikroC
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...
>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
Re: 16F648A Uart MikroC
> >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.
> 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.
Re: 16F648A Uart MikroC
Förlåt jag missförstod helt båda frågorna 
>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å)

>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å)
Re: 16F648A Uart MikroC
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.)

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.)
Re: 16F648A Uart MikroC
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)
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)
Re: 16F648A Uart MikroC
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.
>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

>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.
Re: 16F648A Uart MikroC
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. 

Re: 16F648A Uart MikroC
> 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...
Ä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...
Re: 16F648A Uart MikroC
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.
Här är koden:
och när jag lägger in lite tecken för stt se var han skickar vad:
så får jag
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 "/"
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
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]);
}
}
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å
Kod: Markera allt
Sent: 150s
Received: 1-1/5-0-
Sent: 1ffs
Received: 1-1/f-f-
"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 "/"
Re: 16F648A Uart MikroC
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
ger
och ingen pwm.
Edit: Gillar inte sprintl, hexfilen går från 3 till 13kb med den aktiverad...
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);
}
Kod: Markera allt
Sent: 408s
Received: 4
Received: 0
Sent: 1ffs
Received: 1
Received: f
Edit: Gillar inte sprintl, hexfilen går från 3 till 13kb med den aktiverad...
Re: 16F648A Uart MikroC
"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.
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.