pollkey 関数を 1 ミリ秒に 1 回呼び出し、時間変数 (timeloc) を 1 秒に 1 回インクリメントしたいと考えています。遅延サブルーチンに a を追加すればうまくいくと思いますが、call pollkey
なぜうまくいかないのですか?
.equ delaycount, 16911 #set right delay value here!
.text # Instructions follow
.global delay # Makes "main" globally known
delay: beq r4,r0,fin # exit outer loop
movi r8,delaycount # delay estimation for 1ms
inner: beq r8,r0,outer # exit from inner loop
subi r8,r8,1 # decrement inner counter
br inner
outer: subi r4,r4,1 # decrement outer counter
call pollkey
br delay
fin: ret
上記はCで実行しました
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
extern void puttime(int* timeloc);
extern void puthex(int time);
extern void tick(int* timeloc);
extern void delay(int millisec);
extern int hexasc(int invalue);
#define TRUE 1
#define KEYS4 ( (unsigned int *) 0x840 )
int timeloc = 0x5957; /* startvalue given in hexadecimal/BCD-code */
int RUN = 1;
void pollkey() {
int action = IORD_ALTERA_AVALON_PIO_DATA(DE2_PIO_KEYS4_BASE);
if (action == 7) {
timeloc = 0x0;
} else if (action == 13) {
RUN = 0;
} else if (action == 14) {
RUN = 1;
} else if (action == 11) {
tick(&timeloc);
}
}
int main() {
while (TRUE) {
puttime(&timeloc);
delay(1);
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_REDLED18_BASE, timeloc);
if (RUN == 1) {
tick(&timeloc);
puthex(timeloc);
}
}
return 0;
}
int hex7seg(int digit) {
int trantab[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e };
register int tmp = digit & 0xf;
return (trantab[tmp]);
}
void puthex(int inval) {
unsigned int hexresult;
hexresult = hex7seg(inval);
hexresult = hexresult | (hex7seg(inval >> 4) << 7);
hexresult = hexresult | (hex7seg(inval >> 8) << 14);
hexresult = hexresult | (hex7seg(inval >> 12) << 21);
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_HEX_LOW28_BASE, hexresult);
}
int hex7seg2(int digit) {
int trantab[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e };
register int tmp = digit & 0xf0;
return (trantab[tmp]);
}
毎秒ポーリングする場合、ポーリングは機能しますが、ミリ秒ごとにポーリングしたいのですが、それができると思う唯一の方法は、dely サブルーチンから pollkey を呼び出すことですが、それを行っても何も起こらないようです。手伝って頂けますか?前にどうしたらいいのか聞いてみたところ、アセンブリを変更すればいいのかと思っていたところ、Cでしか答えがありませんでした。
アップデート
br
の代わりに使用した方がはるかに良い結果が得られているcall
ので、違いを確認する必要があります。これは私が使用しているもので、よりうまく機能します:
.equ delaycount, 16911 #set right delay value here!
.text # Instructions follow
.global delay # Makes "delay" globally known
delay: beq r4,r0,fin # exit outer loop
movi r8,delaycount # delay estimation for 1ms
inner: beq r8,r0,outer # exit from inner loop
subi r8,r8,1 # decrement inner counter
br inner
outer: subi r4,r4,1 # decrement outer counter
br pollkey
br delay
fin: ret
唯一の問題は、時計が速すぎることです。
アップデート
モジュロ1000を数秒間破るカウンターを導入することで解決したと思います:
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
extern void puttime(int* timeloc);
extern void puthex(int time);
extern void tick(int* timeloc);
extern void delay(int millisec);
extern int hexasc(int invalue);
#define TRUE 1
#define KEYS4 ( (unsigned int *) 0x840 )
int timeloc = 0x5957; /* startvalue given in hexadecimal/BCD-code */
int RUN = 0;
void pollkey() {
int action = IORD_ALTERA_AVALON_PIO_DATA(DE2_PIO_KEYS4_BASE);
if (action == 7) {
timeloc = 0x0;
puttime(&timeloc);
puthex(timeloc);
} else if (action == 13) {
RUN = 0;
} else if (action == 14) {
RUN = 1;
} else if (action == 11) {
tick(&timeloc);
puttime(&timeloc);
puthex(timeloc);
delay(1000);
}
}
int main() {
int counter = 0;
while (TRUE) {
pollkey();
delay(1);
++counter;
if (counter % 1000 == 0) {
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_REDLED18_BASE, timeloc);
if (RUN == 1) {
tick(&timeloc);
puttime(&timeloc);
puthex(timeloc);
}
}
}
return 0;
}
int hex7seg(int digit) {
int trantab[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e };
register int tmp = digit & 0xf;
return (trantab[tmp]);
}
void puthex(int inval) {
unsigned int hexresult;
hexresult = hex7seg(inval);
hexresult = hexresult | (hex7seg(inval >> 4) << 7);
hexresult = hexresult | (hex7seg(inval >> 8) << 14);
hexresult = hexresult | (hex7seg(inval >> 12) << 21);
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_HEX_LOW28_BASE, hexresult);
}
int hex7seg2(int digit) {
int trantab[] = { 0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00,
0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e };
register int tmp = digit & 0xf0;
return (trantab[tmp]);
}
.equ delaycount, 16911 #set right delay value here!
.text # Instructions follow
.global delay # Makes "delay" globally known
delay: beq r4,r0,fin # exit outer loop
movi r8,delaycount # delay estimation for 1ms
inner: beq r8,r0,outer # exit from inner loop
subi r8,r8,1 # decrement inner counter
br inner
outer: subi r4,r4,1 # decrement outer counter
br delay
fin: ret