Created
August 7, 2020 07:46
-
-
Save Alexander-Tengborg/4136bed17de43be0aa4f1382835bbc5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Anonym kod: EDA487-0059-PLX | |
@ R3=a | |
@ R4=b | |
@ R5=c | |
main: B init_data | |
LDR R0,#2020 @Argumentet ska ligga i R0 | |
B sum_grade | |
LDR R3,R0 @Return v�rdet flyttas till A | |
LDR R0,#2000 @Argumentet ska ligga i R0 | |
B sum_grade | |
LDR R4,R0 @Return v�rdet flyttas till B | |
ADD R5,R4,R4 @ c=a+b | |
init_data: PUSH {R3, R4, LR} @Sparar R3, R4 som vi �ndrar p� (och LR) | |
LDR R0,=student_year @Adressen till student_year | |
LDR R1,=student_grade @Adressen till student_grade | |
LDR R2,#2000 | |
LDR R3,#4 | |
STR R2,R0 @Till adressen till student_year | |
STR R3,R1 @Till adressen till student_grade | |
LDR R2,#2000 | |
LDR R3,#3 | |
STR R2,[R0,#2] @Till adressen till student_year+2 | |
STR R3,[R1,#1] @Till adressen till student_grade+1 | |
LDR R2,#1998 | |
LDR R3,#5 | |
STR R2,[R0,#4] @Till adressen till student_year+4 | |
STR R3,[R1,#2] @Till adressen till student_grade+2 | |
POP {R4, PC} | |
LDR R2,#2002 | |
LDR R3,#4 | |
STR R2,[R0,#6] @Till adressen till student_year+6 | |
STR R3,[R1,#3] @Till adressen till student_grade+3 | |
POP {R3, R4, PC} @Tar tillbaka v�rdet p� R3, R4 och LR->PC, dvs branchas tillbaka | |
sum_grade: @ uttryck1 - B�rjan av foor loopen, dvs g�r i = 0 | |
LDR R1,=i | |
LDR R0,=0 | |
STR R0,[R1] @ i = 0 | |
For_Continue: | |
@ uttryck2 J�mf�r i med dess villkor (i v�rt fall i < 100) Om villkoret inte �r uppfyllt, dvs i >= 100 s� hoppar den till For_Break | |
LDR R0,i | |
CMP R0,#4 @ (i-4)->APSR | |
BGE For_Break | |
For_Do: @if sats h�r | |
@uttryck3 Vad som sker efter varje "loop" av for-loopen, dvs vi vill �ka i med 1! | |
LDR R1,=i | |
LDR R0,[R1] | |
ADD R0,R0,#1 | |
STR R0,[R1] @ i = i+1 | |
B For_Continue | |
For_Break: .... @Slutet av for-loopen, hit kommer den bara om "kravet" (n�r i inte �r < 100) ej uppfylls, eller en break kodas. | |
student_year: .SPACE 4*2 @MAX=4, short storlek = 2 | |
student_grade: .SPACE 4*1 @MAX=4, char storlek = 1 | |
c: .SPACE 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Anonym kod: EDA487-0059-PLX | |
// .h fil nedan: | |
/* Defintioner*/ | |
//Följande GPIO_D definitioner används så att vi till en början kan konfigurera GPIO_D porten korrekt, men för att sedan också kunna skriva och läsa till GPIO_D | |
#define GPIO_D 0x40020C00 | |
#define GPIO_D_MODER ((volatile unsigned int *) GPIO_D) | |
#define GPIO_D_OTYPER_HIGH ((volatile unsigned char *) GPIO_D+0x05) | |
#define GPIO_D_PUPDR_HIGH ((volatile unsigned short *) GPIO_D+0x0E) | |
#define GPIO_D_IDR_HIGH ((volatile unsigned char *) GPIO_D+0x11) | |
#define GPIO_D_ODR_LOW ((volatile unsigned char *) GPIO_D+0x14) | |
#define GPIO_D_ODR_HIGH ((volatile unsigned char *) GPIO_D+0x15) | |
//Följande STK definitioner används för att aktivera räknaren, och för att välja vilket värde den ska räkna till, samt vilket värde den är på. | |
#define STK_CTRL ((volatile unsigned int *) 0xE000E010) | |
#define STK_LOAD ((volatile unsigned int *) 0xE000E014) | |
#define STK_VAL ((volatile unsigned int *) 0xE000E018) | |
//Dessa används för att flytta vektortabellen bort från adressen 0. | |
//När vektor tabellen lägger på adressen 0 så befinner sig den i ROM-minne (Read Only Memory), dvs minnet går inte att ändra på där | |
//Och därav så måste vektor tabellen flyttas! | |
#define VECTOR_DEST 0x2001C000 | |
#define SCB_VTOR ((volatile unsigned int *) 0xE000ED08) | |
#define SYSTICK_IRQ_HANDLER ((void (**)(void)) (VECTOR_DEST+0x3C)) | |
//Används för att bestämma hur länge ett delay ska vara | |
#define DELAY_1S 168*1000*1000 //168 = 1 mikrosekund, 168*1000 = 1 millisekund, 168*1000*1000 = 1 sekund | |
#define DELAY_1MS 168*1000 //168 = 1 mikrosekund, 168*1000 = 1 millisekund | |
//Alla våra karaktärers "motsvarigheter" i 7-seg displayen | |
const unsigned char segs[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40}; //0x40 = tecknet '-' | |
unsigned char elapsedTime = 0; //Hur mycket tid som har gått i millisekunder | |
unsigned char isCounting = 0; //Om tidtagningen är på eller inte | |
// .c fil nedan: | |
/* | |
* Konfigurerar port D så att den kan användas med en keypad på bitar 0-7, | |
* samt så att en 7-segment display kan användas på bitar 8-15 | |
*/ | |
void app_init(void) | |
{ | |
//Keypad setup | |
*GPIO_D_MODER &= 0x0000FFFF; | |
*GPIO_D_MODER |= 0x55000000; //Sätter rätt pinnar till utpinnar/inpinnar, utan att ändra på dem som ej ska ändras | |
*GPIO_D_OTYPER_HIGH = 0x00; //Sätter pinnar till push-pull | |
*GPIO_D_PUPDR_HIGH = 0x00AA; //Sätter pinnar till pull-down | |
//7-seg setup | |
*GPIO_D_MODER &= 0xFFFF0000; | |
*GPIO_D_MODER |= 0x00005555; //Sätter rätt pinnar till utpinnar, utan att ändra på dem som ej ska ändras | |
//Avbrott setup (för icke-blockerande delay) | |
//Flyttar vektortabellen, å gör så att SYSTICK avbrottet använder vår irq_handler (som då körs varje gång när systick har räknat klart (och avbrott är aktiverat, dvs *STK_CTRL = 7)) | |
*SCB_VTOR = VECTOR_DEST; | |
*SYSTICK_IRQ_HANDLER = systick_irq_handler; | |
} | |
//Följande delay ger en delay på 1 sekund och är blockerande, | |
//Dvs att ingen annan kod kan köras när denna körs | |
void delay_1s(void) | |
{ | |
*STK_CTRL = 0; | |
*STK_LOAD = (DELAY_1S - 1); | |
*STK_VAL = 0; | |
*STK_CTRL = 5; | |
while( (*STK_CTRL & 0x10000 )== 0 ); | |
*STK_CTRL = 0; | |
} | |
//Anropad delay_1s funktionen seconds antal gånger, så att vi får en delay på seconds antal sekunder | |
void delay(int seconds) | |
{ | |
for(int i = 0; i < seconds; i++) | |
delay_1s(); | |
} | |
//Följande delay ger en delay på 1 millisekund och är inte blockerande, | |
//Dvs att annan kod kan köras samtidigt som delayen. Detta fungerar med hjälp av avbrott | |
void delay_1milli(void) | |
{ | |
*STK_CTRL = 0; | |
*STK_LOAD = (DELAY_1MS - 1); | |
*STK_VAL = 0; | |
*STK_CTRL = 7; | |
} | |
//Påbörjar tidtagningen, genom att sätta en variabel till 1 (true) | |
//Och att kalla på den icke-blockerande delayen delay_1milli(); | |
void start_counter() | |
{ | |
isCounting = 1; | |
delay_1milli(); | |
} | |
//"Avslutar" tidtagningen genom att sätta en variabel till 0 (false) | |
//Denna variabel kollas sedan i en annan funktion, som i sin tur avslutar tidstagningen | |
void stop_counter() | |
{ | |
isCounting = 0; | |
} | |
//Detta är vår avbrotts hanterare för delay_1ms. | |
//Den kallas varje gång som delay_ms har räknat klart, och är alltså funktionen | |
//som uppdaterar elapsedTime, så att vi får rätt löpen tid i millisekunder. | |
//Den stannar/slutar tidstagningen då isCounting är 0 | |
void systick_irq_handler(void) | |
{ | |
*STK_CTRL = 0; | |
elapsedTime += 1; | |
if(isCounting) | |
delay_1milli(); | |
} | |
//Aktiverar rad row på keypaden, så att vi sedan kan läsa bitar från kolumnerna | |
void activateRow(int row) | |
{ | |
*GPIO_D_ODR_HIGH = 0x10 << (row-1); | |
} | |
//Läser alla kolumner och returnerar ett värde beroende på vilken kolumn som är på | |
unsigned char getColumn(void) | |
{ | |
unsigned char c; | |
c = *GPIO_D_IDR_HIGH; | |
if (c & 0x8) return 4; | |
if (c & 0x4) return 3; | |
if (c & 0x2) return 2; | |
if (c & 0x1) return 1; | |
return 0; | |
} | |
//Används för att returna den knappen som är nertryckt | |
unsigned char keyb(void) { | |
unsigned char key[] = {1,2,3,0xA,4,5,6,0xB,7,8,9,0xC,0xE,0,0xF,0xD}; | |
for (unsigned char row = 1; row <= 4; row++) { | |
activateRow(row); | |
unsigned char col = getColumn(); | |
if (col != 0) { | |
activateRow(0); | |
return key[4*(row-1)+(col-1)]; | |
} | |
} | |
activateRow(0); | |
return 0xFF; | |
} | |
//Ändrar värde på 7-segment displayen så att den visar den nertryckta knappen | |
void out7seg(unsigned char c) | |
{ | |
if(c > 16) { | |
*GPIO_D_ODR_LOW = 0; | |
return; | |
} | |
*GPIO_D_ODR_LOW = segs[c]; | |
} | |
//Får 7-segments displayen att "blinka" med värdet character. Detta gör den numberOfTimes antal gånger | |
//Med en delay på 1 sekund mellan att den är på och av. | |
void toggle_display(int character, int numberOfTimes) | |
{ | |
for(int i = 0; i < numberOfTimes; i++) | |
{ | |
out7seg(character); | |
delay_1s(); | |
out7seg(0xFF); //Släck displayen | |
delay_1s(); | |
} | |
} | |
/* | |
* Programmets main funktion | |
* Målet med programmet är alltså att implementera ett form av reaktionstest | |
* För att göra detta så måste ett antal funktioner implementeras. | |
* Dessa är init, outseg och keyb, och även någon/några former av delay funktioner. | |
*/ | |
void main(void) | |
{ | |
app_init(); | |
while(1) { | |
*GPIO_D_ODR_LOW = 0; //Släck display | |
//random() ger 0-127, delat med 16 ger 0-7.9375, dvs 0-7 för heltal Adderar man 1 så blir intervallet 1-8 | |
int delayTime = random()/16 + 1; | |
delay(delayTime); | |
//random() ger 0-127, delat med 8 ger 0-15.875, dvs 0-15 för heltal | |
int randomNumber = random()/8; | |
//Skriver ut vårat slumpmässiga tal till 7-segment displayen | |
out7seg(randomNumber); | |
//Starta tidsmätning, med oblockerande "delay" | |
start_counter(); | |
int key = keyb(); | |
if(randomNumber == key) | |
{ | |
stop_counter(); //Avslutar räknaren | |
if(elapsedTime > 1000) // Om det tog mer än 1 sekund | |
{ | |
// Tänd/släck tecken '-' 3 gånger med 1 sekunds intervall | |
toggle_display(16, 3); | |
break; //Avsluta while-loopen | |
} | |
else // Om det tog mindre än 1 sekund | |
{ | |
// Tänd/släck slumptal 3 gånger med 1 sekunds intervall | |
toggle_display(randomNumber, 3); | |
continue; // Fortsätt med loopen | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Anonym kod: EDA487-0059-PLX | |
// .h fil nedan: | |
//Dessa används för att konfigurera hela GPIO_D som en utport, men också för att sedan kunna skriva till den | |
#define GPIO_D 0x40020C00 | |
#define GPIO_D_MODER ((volatile unsigned int *) GPIO_D) | |
#define GPIO_D_ODR_LOW ((volatile unsigned char *) GPIO_D+0x14) | |
#define GPIO_D_ODR_HIGH ((volatile unsigned char *) GPIO_D+0x15) | |
//Dessa används för att konfigurera en del av GPIO_E som en inport, men också för att sedan kunna läsa från den | |
#define GPIO_E 0x40021000 | |
#define GPIO_E_MODER ((volatile unsigned int *) GPIO_E) | |
#define GPIO_E_IDR_HIGH ((volatile unsigned char *) GPIO_E+0x11) | |
//Används för att koppla rätt EXTI(x) avbrott till rätt port. I vårt fall så ska EXTI0 = 4 och EXTI1 = 4, så att de kopplas till port E. | |
#define SYSCFG_EXTICR1 ((volatile unsigned int*) 0x40013808) | |
#define EXTI_IMR ((volatile unsigned int*) 0x40013C00) //Aktiverar avbrott för en bit. Vi aktiverar avbrott för EXTI(x) Genom att sätta bit x till 1 | |
#define EXTI_RTSR ((volatile unsigned int*) 0x40013C08) //Bestämmer om EXTI(x) ska ha avbrott på positiv flank | |
#define EXTI_FTSR ((volatile unsigned int*) 0x40013C0C) //Bestämmer om EXTI(x) ska ha avbrott på negativ flank | |
#define EXTI_PR ((volatile unsigned int*) 0x40013C14) //Om bit x är 1, så väntar ett avbrott på EXTI(x) | |
//Dessa två under "väljer" vad som ska ske när ett avbrott sker. Dessa kommer att peka på en funktion var. | |
#define EXTI1_IRQVEC ((void (**) (void)) 0x2001C05C) | |
#define EXTI0_IRQVEC ((void (**) (void)) 0x2001C058) | |
#define NVIC_ISPR0 ((volatile unsigned int *) 0xE000E100) //Används för att göra så att avbrott kan "avvakta" Här så sätter man ej bit x för EXTI(x). Rätt bit man ska sätta finns under IRQ_NUM i vektor tabellen | |
//IRQ numrerna för EXTI1 respektive EXTI0 | |
#define NVIC_EXTI1_IRQ_BPOS (1<<7) | |
#define NVIC_EXTI0_IRQ_BPOS (1<<6) | |
//Bitarnas värde i bit x för EXTI(x) | |
#define EXTI1_IRQ_BPOS 2 | |
#define EXTI0_IRQ_BPOS 1 | |
//Dessa används för att flytta vektortabellen bort från adressen 0. | |
//När vektor tabellen lägger på adressen 0 så befinner sig den i ROM-minne (Read Only Memory), dvs minnet går inte att ändra på där | |
//Och därav så måste vektor tabellen flyttas! | |
#define VECTOR_DEST 0x2001C000 | |
#define SCB_VTOR ((volatile unsigned int *) 0xE000ED08) | |
//Dessa är vårat nuvarande värde på S2 och S1 | |
unsigned char s2_value = 0; | |
unsigned char s1_value = 0; | |
// .c fil nedan: | |
//Detta avbrottet sker då S2:s värde ändras "på" positiv flank. | |
//Sätter värdet på s2_value, genom att "toggla" det | |
//Det kanske ej är rätt sätt att göra det, men det framstod ej hur S2 och S1 signalerna fungerade helt | |
void irq_handler_exti1(void) | |
{ | |
//Först så kollar vi om ett avbrott väntar på EXTI1 | |
if(*EXTI_PR & EXTI1_IRQ_BPOS) | |
{ | |
*EXTI_PR |= EXTI1_IRQ_BPOS; //Här så kvitterar vi avbrottet genom att sätta dess bit till 1. Detta görs så att ett avbrott kan ske igen. | |
s2_value = (s2_value == 0) ? 1 : 0; //Här så togglar vi värdet på s2_value. Dvs om s2_value == 0, så sätts den till 1, annars så sätts den till 0 | |
} | |
} | |
//Detta avbrottet sker då S1:s värde ändras "på" positiv flank. | |
//Sätter värdet på s1_value, genom att "toggla" det | |
//Det kanske ej är rätt sätt att göra det, men det framstod ej hur S2 och S1 signalerna fungerade helt | |
void irq_handler_exti0(void) | |
{ | |
//Först så kollar vi om ett avbrott väntar på EXTI0 | |
if(*EXTI_PR & EXTI0_IRQ_BPOS) | |
{ | |
*EXTI_PR |= EXTI0_IRQ_BPOS; //Här så kvitterar vi avbrottet genom att sätta dess bit till 1. Detta görs så att ett avbrott kan ske igen. | |
s1_value = (s1_value == 0) ? 1 : 0; //Här så togglar vi värdet på s1_value. Dvs om s1_value == 0, så sätts den till 1, annars så sätts den till 0 | |
} | |
} | |
void init_app(void) | |
{ | |
*GPIO_D_MODER = 0x55555555; //Sätt hela port D till utport | |
*GPIO_E_MODER &= 0x0000FFF0; //Sätt E15-8 och E1-0 till inportar, ändra ej på resten | |
//* Koppla PE1, PE0 till avbrottslinor EXTI1 och EXTI0 */ | |
*SYSCFG_EXTICR1 &= 0xFF00; | |
*SYSCFG_EXTICR1 |= 0x0044; | |
/* Konfigurera EXTI1 och EXTI0 för att generera avbrott */ | |
*EXTI_IMR |= (EXTI1_IRQ_BPOS + EXTI0_IRQ_BPOS); | |
/* Konfigurera EXTI1 och EXTI0 för avbrott på positiv flank */ | |
*EXTI_RTSR |= (EXTI1_IRQ_BPOS + EXTI0_IRQ_BPOS); | |
/* Konfigurera EXTI1 och EXTI0 så att avbrott också sker på negativ flank */ | |
*EXTI_FTSR |= (EXTI1_IRQ_BPOS + EXTI0_IRQ_BPOS); | |
/* Sätt upp avbrottsvektor, och gör så att vardera avbrott pekar på dess avbrottsfunktion */ | |
*SCB_VTOR = VECTOR_DEST; | |
*EXTI1_IRQVEC = irq_handler_exti1; | |
*EXTI0_IRQVEC = irq_handler_exti0; | |
/* Konfigurera de bitar i NVIC som kontrollerar de avbrottslinor som EXTI1 och EXTI0 kopplas till */ | |
*NVIC_ISPR0 |= (NVIC_EXTI1_IRQ_BPOS | NVIC_EXTI0_IRQ_BPOS); | |
} | |
/* | |
* Programmets main funktion | |
* Vi ska alltså kunna skriva ut olika data till två olika displayer som finns på D0-7 och D8-15. | |
* Men vi har bara en 8 bitars port ledig som vi kan använda för indata, å den kan ju inte skriva 8 olika bitar till två olika displayer. | |
* Därför så kopplas två multiplex signaler till E0 och E1, som i sin tur kopplas till externa avbrotten EXTI0 och EXTI1 | |
* Med hjälp av dessa två signaler så kan vi, enligt tabellen i uppgiften, välja vilken display vi ska skriva ut datan (som finns på E8-15) till. | |
* Programmet kan testas med två 'Double Hexadecimal Displays' på port D, och två 'Dipswitches' på port E | |
*/ | |
void main(void) | |
{ | |
init_app(); | |
while(1) | |
{ | |
//Lägger ihop S2:s och S1:s värden. s2_value och s1_value kan bara ha värdet 0 och 1. Detta funkar för s2_value, som ligger på bit 0 (där värdet är 0 eller 1) | |
//Men för s1_value, som ligger på bit 1 som kan ha värderna 0 och 2, funkar inte detta. Därför så måste vi gångra den med 2 | |
//Man behöver ej göra så, men genom att göra så här så undviker man t.ex några if-satser med 2 villkor i varje | |
char s_value = 2*s1_value + s2_value; | |
//Här bestämmer vi vad som ska hända för varje värde S. | |
switch(s_value) | |
{ | |
case 0: //S1=0, S2=0 | |
*GPIO_D_ODR_LOW = 0; //D0-7 = 0 | |
break; | |
case 1: //S1=0, S2=1 | |
*GPIO_D_ODR_HIGH = 0; //D8-15 = 0 | |
break; | |
case 2: //S1=1, S2=0 | |
*GPIO_D_ODR_LOW = *GPIO_E_IDR_HIGH; //D0-7 = E8-15 | |
break; | |
case 3: //S1=1, S2=1 | |
*GPIO_D_ODR_HIGH = *GPIO_E_IDR_HIGH; //D8-15 = E8-15 | |
break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Anonym kod: EDA487-0059-PLX | |
// .h fil nedan: | |
//Sätter robotens bas adress, och skapar pekare till CTRL och STATUS registret | |
#define ROBOT_BASE 0x100000 | |
#define ROBOT_CTRL ((volatile unsigned char *) ROBOT_BASE) | |
#define ROBOT_STATUS ((volatile unsigned char *) ROBOT_BASE+0x1) | |
//Följande register är vad robotens "mål" är | |
#define ROBOT_DATAY ((volatile unsigned short *) ROBOT_BASE+0x4) | |
#define ROBOT_DATAX ((volatile unsigned short *) ROBOT_BASE+0x6) | |
//Följande register get robotens aktuella position | |
#define ROBOT_POSY ((volatile unsigned short *) ROBOT_BASE+0x8) | |
#define ROBOT_POSX ((volatile unsigned short *) ROBOT_BASE+0xA) | |
//Följande ger bara diverse bitpositioner/värde så att man enkelt kan kolla/ändra värdet på varje bit | |
#define IRQ (1<<4) | |
#define ER (1<<2) | |
#define IE (1<<7) | |
#define IA (1<<6) | |
#define EN (1<<3) | |
#define RS (1<<0) | |
//Följande STK definitioner används för att aktivera räknaren, och för att välja vilket värde den ska räkna till, samt vilket värde den är på. | |
#define STK_CTRL ((volatile unsigned int *) 0xE000E010) | |
#define STK_LOAD ((volatile unsigned int *) 0xE000E014) | |
#define STK_VAL ((volatile unsigned int *) 0xE000E018) | |
#define DELAY_1MS 168*1000 //168 = 1 mikrosekund, 168*1000 = 1 millisekund | |
//Gör en enkel definition för en point, som innehåller x och y koordinater, samt en pekare till nästa point | |
typedef struct point | |
{ | |
char x,y; | |
struct point *next; | |
} POINT, *PPOINT; | |
// .c fil nedan: | |
//Mellan dessa punkter så kan man dock lägga till andra punkter, | |
//Det viktiga är att roboten åtminstone går mellan dessa punkter! | |
PPOINT p4 = { 36,39, 0}; //"Målet" | |
PPOINT p3 = { 25,27, p4}; | |
PPOINT p2 = { 12,14, p3}; | |
PPOINT p1 = { 1,2, p2}; | |
//Följande delay ger en delay på 1 millisekund och är blockerande, | |
//Dvs att ingen annan kod kan köras när denna körs | |
void delay_1milli(void) | |
{ | |
*STK_CTRL = 0; | |
*STK_LOAD = (DELAY_1MS - 1); | |
*STK_VAL = 0; | |
*STK_CTRL = 5; | |
while( (*STK_CTRL & 0x10000 )== 0 ); | |
*STK_CTRL = 0; | |
} | |
//Anroppar delay_1milli funktionen ms antal gånger, dvs totala delayet blir ms millisekunder | |
void delayMS(unsigned short ms) | |
{ | |
for(int i = 0; i < ms; i++) | |
delay_1milli(); | |
} | |
//Flyttar på roboten till de givna x och y koordinaterna | |
void move_robot(unsigned short x, unsigned short y) | |
{ | |
//Ändrar mål koordinaterna så att roboten flyttar på sig | |
*ROBOT_DATAX = x; | |
*ROBOT_DATAY = y; | |
//Aktiverar roboten | |
*ROBOT_CTRL |= EN; | |
//while loopen körs undertiden som roboten inte är på mål koordinaterna, så all annan kod stoppas till roboten har kommit fram | |
while((*ROBOT_DATAX != *ROBOT_POSX) || (*ROBOT_DATAY != *ROBOT_POSY)); | |
//Avaktiverar tillslut roboten | |
*ROBOT_CTRL &= ~EN; | |
} | |
//Gör så att roboten kan åka på en resa! Den börjar på punkt pos | |
//Punkter kan peka på andra punkter, så de blir att den åker till flera punkter | |
void trip_robot(PPOINT pos) | |
{ | |
//Sparar senaste x-pos, så att delayTime kan räknas ut | |
short lastx = 0; | |
//Loopar igenom den länkade listan | |
while(pos->next != 0) | |
{ | |
move_robot(pos->x, pos->y); | |
short delayTime = abs(pos->x - lastx); //Räknar ut hur lång delayen ska vara! | |
delayMS(delayTime); | |
} | |
//När loopen är klar, så måste den köra en gång till, annars så får den inte med sista koordinaten | |
move_robot(pos->x, pos->y); | |
short delayTime = abs(pos->x - lastx); //Räknar ut hur lång delayen ska vara! | |
delayMS(delayTime); | |
} | |
//Initierarn roboten, genom att resetta den och att flytta den till koordinater 0,0! | |
void init_robot() | |
{ | |
*ROBOT_CTRL = RS; //Sätter RS till 1 så att vi nollställer alla värden | |
*ROBOT_CTRL = 0; //Sätter sedan RS till 0 (Allt annat är redan 0, så bara RS ändras); | |
move_robot(0,0); //Flyttar roboten till koordinater (0,0) enligt uppgiftsbeskrivningen | |
} | |
/* | |
* Målet är att skapa ett program som kan flytta på en robot. För detta så har vi fått robotens register. | |
* Vi måste ha en funktion som initierar roboten, en funktion som flyttar på roboten, och en funktion som kallar på roboten | |
* som låter roboten åka mellan flera punkter. Vi behöver också ett blockerande delay som är 1 millisekund lång, | |
* Samt en array/länkadlista med våra koordinater! | |
*/ | |
void main(void) | |
{ | |
init_robot(); //Initierar roboten | |
trip_robot(p1); //Startar robotens resa | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment