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å :humm:

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

Kod: Markera allt

call  RUTIN

RUTIN
;rutinen
return

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.