Sida 4 av 5
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 8 mars 2013, 15:54:03
av adent
Ett vanligt sätt att bygga upp kod för micro-kontrollers är i form av ett litet leksaks-OS t.ex. så här:
Kod: Markera allt
INTERRUPT PortAPin3()
{
Gör nått tidskritiskt, sätt en lämplig flagga.
}
INTERRUPT Timer1OverFlow()
{
Gör nått tidskritiskt, sätt en lämplig flagga.
}
main()
{
while(1)
{
Hantera otidskritiska saker apropå att Timerflagga satt
Hantera otidskritiska saker apropå att Pinflagga satt
}
}
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 8 mars 2013, 19:56:17
av kvaark
Ok testade att göra såhär
Kod: Markera allt
#include <xc.h>
#include <stdint.h>
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FOSC = INTRCIO, FCMEN = OFF, MCLRE = OFF, WDTE = OFF, CP = OFF, PWRTE = OFF
#define _XTAL_FREQ 8000000
#define LED PORTAbits.RA2
#define RX PORTCbits.RC0
uint16_t count_100us;
void main()
{
uint8_t count;
uint24_t adress;
PORTA = 0;
TRISA = 0b00000000;
PORTB = 0;
TRISB = 0b00000000;
PORTC = 0;
TRISC = 0b00000001;
ANSEL = 0;
ANSELH = 0;
ADCON0 = 0;
ADCON0 = 0;
OSCCON = 0b01110001;
OPTION_REG = 0b00001000;
T2CON = 0;
INTCON = 0b10100000;
TMR0 =88;
for (;;)
{
//Vänta på att RX = 0 i 7mS
for (count_100us = 0; count_100us <= 7000/100;)
{
if (RX == 1)
count_100us = 0;
}
//läs av in signaler spara i adress
adress = 0;
for (count = 0; count < 24; count++)
{
adress = adress << 1 ;
while (RX == 1)
{
;
}
while (RX == 0)
{
;
}
for (count_100us = 0; count_100us <= 7;)
{
;
}
adress = adress ^ RX;
}
//Gämför adress med nyckel
if (adress == 0x405015 || adress == 0x400415 || adress == 0x000015)
LED = 1;
if (adress == 0x405014 || adress == 0x400414 || adress == 0x000014)
LED = 0;
}
}
void interrupt tc_int(void)
{
if (T0IE || T0IF)
{
T0IF=0;
++count_100us;
TMR0 =88;
return;
}
// process other interrupt sources here, if required
}
Men det kändes mer stökigt och tar dessutom mer plats än innan..
men jag gör säkert inte som ni hade tänkt endå

Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 8 mars 2013, 21:00:17
av Krille Krokodil
Tillståndsmaskin är sätt att lösa det på. Man gör en tabell på hur länge varje tillstånd ska vara och sedan en funktion i avbrottsrutinen som räknar ner och stegar tillstånden. I main har man:
Kod: Markera allt
switch(state){
case 1:
// Vad som ska ske i tillstånd 1
break;
case 2:
// Vad som ska ske i tillstånd 2
break;
osv...
}
Edit: Du behöver inte sluta programmera assembler nu för att du har börjat med C, man kan blanda, sk inline assembly, för AVR fungerar det ut såhär:
http://www.nongnu.org/avr-libc/user-man ... e_asm.html
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 07:56:35
av kvaark
EDIT: dubblett
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 07:56:57
av kvaark
någon som har bra dokumentation eller vill förklara hur man använder rutiner
kommer att behöva anropa detta flera gånger i min kod
Kod: Markera allt
tusental = (adc / 1000) + '0';
adc = adc - (1000*(tusental - '0'));
hundratal = (adc / 100) + '0';
adc = adc - (100*(hundratal - '0'));
tiotal = (adc / 10) + '0';
adc = adc - (10*(tiotal - '0'));
ental = adc + '0';
det är hur jag löste att omvandla 10 bitars adc till ascii tal att sända via uart
men jag vill kunna anropa funktionen för att inte behöva skriva detta varje gång jag utför det i koden
i asm hade jag bara skrivit
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 09:58:44
av Walle
I C skriver du typ:
Kod: Markera allt
int BitToASCII(int x)
{
gör saker här;
return x;
}
Notera att den första datatypsdeklarationen talar om vilken datatyp funktionen returnerar. Inom parentesen är det vilken datatyp som är argument.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 10:05:55
av Icecap
Det ser ut som att du vill omvandla ett värde till siffror (text) och då väljer du en besvärlig väg, iaf. att läsa.
Nu beror det lite på hur du ska använda resultatet men EN lösning är att sända varje tecken eftersom med högsta värdet först:
ADC_Value är ingångsvärdet.
Send_Byte() är rutinen för att sända en byte.
Kod: Markera allt
void Send_Value(unsigned int Value)
{
unsigned char X[5]; // Max. 5 char's
x[4] = (Value % 10) + '0';
Value /= 10;
x[3] = (Value % 10) + '0';
Value /= 10;
x[2] = (Value % 10) + '0';
Value /= 10;
x[1] = (Value % 10) + '0';
Value /= 10; // Behövs för 10.000 siffran
x[0] = (Value % 10) + '0'; // Behövs för 10.000 siffran
Send_Byte(X[0]); // Behövs för 10.000 siffran
Send_Byte(X[1]); // Skickar 1.000 siffran
Send_Byte(X[2]); // Skickar 100 siffran
Send_Byte(X[3]); // Skickar 10 siffran
Send_Byte(X[4]); // Skickar 1 siffran
}
När du sedan ska sända ett värde skriver du bara:
Send_Value(ADC_Value);
och värdet blir omvandlat till text och sänd via Send_Byte()-rutinen.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 12:43:46
av Wedge
Icecap, modulo och division är fruktansvärt "dyra" operatorer även på processorer med inbyggda instruktioner för sånt. Jag skulle tippa på att TS kod är ganska mycket snabbare.
Läsbarheten vinner du i alla fall, men inte med några hästlängder.
TS kod lägger till och drar ifrån "0" lite för ofta. Den kunde bli aningen mer effektiv om presentationsdata skiljs från beräkningsdata.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 12:50:07
av Icecap
Wedge: jag brukar lösa detta på ett ganska annat sätt. Sedan är modulo inte mer krävande än en vanlig division.
kvaark's sätt är ganska krävande med multiplikationer och divisioner också så jag tror att det går ung. jämt ut.
Men jag håller med om att det går att lösa snyggare och snabbare, men utifrån den ganska svaga beskrivning som finns är det svårt att komma närmre.
Sedan var det själva funktionsanropet som var det viktiga och jag är osäker på om kvaark fick nog på benet med det.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 10 mars 2013, 14:36:14
av sodjan
> någon som har bra dokumentation eller vill förklara hur man använder rutiner
Nu är jag inte riktigt med här.
Varför inte använda de länkar och andra tips som du redan har fått?
T.ex "2.3 Funktioner"p å sidan 21 i
http://www.it.uu.se/edu/course/homepage ... C-kurs.pdf
som det länkades till redan i ett av de första svaren. Vad jag kan se så
är det rellativt vettigt skrivet.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 12 mars 2013, 00:57:43
av kvaark
Tack grabbar...
Mycket bra hjälp här.
Jag kom på att programmet jag kommunicerar med även kan tolka hex värden skrivna i ascii, alltså för 0x3F så skickar man '3' och 'F', och det tyckte jag borde vara både snabbare och mindre resurskrävande att omvandla till ..
Kod: Markera allt
void send (uint16_t value)
{
uint8_t X[4];
const uint8_t patHex [16] =
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
X[0] = patHex [value & 0x0F];
X[1] = patHex [((value >> 4) & 0x0F)];
X[2] = patHex [((value >> 8) & 0x0F)];
X[3] = patHex [((value >> 12) & 0x0F)];
while(!TXIF);
TXREG = X[3];
while(!TXIF);
TXREG = X[2];
while(!TXIF);
TXREG = X[1];
while(!TXIF);
TXREG = X[0];
}
Detta va vad jag kom fram till då..
Ps: Dessutom så behöver jag bara skicka 4 bytes för ett 16bitars tal istället för 5bytes..
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 24 juni 2013, 17:00:14
av kvaark
Hur gör jag för att kolla om en specifik bit i ett register är lika med 0?
det jag försöker göra är en IF där jag testar om en bit i ett register är lika med 0 men jag lyckas inte
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 24 juni 2013, 17:20:38
av Walle
Vad har du försökt?
Nåt i stil med:
If (!register.bit)
eller
If (register.bit == 0)
borde funka.
Edit: jag minns inte säkert om man kan köra typ "register.bit", men annars har ju nästan alla bitar inregistrens ett eget "namn", t.ex. "ADCON0" som är en kontrollbit för ADCn i 12F-familjen. Normalt används namnen som står i databladet i programmeringsmiljön.
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 24 juni 2013, 18:08:58
av kvaark
Ok då förklarade jag lite fel
För det jag menar är ett eget 8bitars variabelt tal
Men det kanske är samma där?
If (tal.8 == 0)
Re: Pratar Assembler. Vill lära mig nytt språk..
Postat: 24 juni 2013, 19:05:03
av ElectricNooB
Jag skulle göra såhär: if((talet&bitten)==0)
Ex: För att kolla bit nr 3 så skall bitten ha värdet 8 i decimal eller 00001000 i binär form.