gpt4 book ai didi

c - Nios 2 的 C 轮询和汇编

转载 作者:行者123 更新时间:2023-11-30 15:46:03 24 4
gpt4 key购买 nike

我想每毫秒调用一次 pollkey 函数,并每秒增加一次时间变量 (timeloc)。我认为如果我将 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中得到了答案,而我认为答案应该是更改程序集。

How to develop this algorithm?

更新

我使用 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

最佳答案

在特定时间尺度上在嵌入式系统中运行例程的正确方法是使用硬件定时器并将操作(假设它相对较小!)放入该定时器的中断服务例程中,或者使用该函数来告诉更长的时间在后台循环中运行的例程。

使用delay()函数将会导致

  • 可变延迟 - 延迟函数已经是使用指令周期的近似值,如果您在中间调用另一个函数,有时情况只会变得更糟
  • 不准确的 1 毫秒轮询 - 不准确程度可能足以满足您的目的,也可能不够好。

一旦您有了 1ms 计时器,您就可以从中运行 pollkey 函数,并且还可以准确地安排更长的事件。

当然,此时您已经开始构建 RTOS,因此您可能仍然想使用一个:)

关于c - Nios 2 的 C 轮询和汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18667635/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com