pollkey()
应该每毫秒调用一次,tick(&timeloc)
应该每秒钟调用一次,我没有线程库。很明显的方法是使用线程来完成这项工作,但是现在看来我需要一些建议来执行这两个更新。我尝试的代码是
int main() {
while (TRUE) {
pollkey();
puttime(&timeloc);
delay(1);
IOWR_ALTERA_AVALON_PIO_DATA(DE2_PIO_REDLED18_BASE, timeloc);
if (RUN == 1) {
tick(&timeloc);
puthex(timeloc);
}
}
return 0;
}
但我不认为以上是100%正确的。整个程序是
#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);
putchar(action);
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) {
pollkey();
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]);
}
我为延迟创建了子例程,我想我可能不会更改:
.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
br delay
fin: ret
tick文件是
extern void delay(int millisec);
/*
* tick - update the time by adding one second
*
* Parameter (only one): the address of the time variable.
*/
void tick( int * timeloc )
{
/* Read time variable. */
int tmp = * timeloc;
tmp = tmp + 1; /* try a tick */
/* if we ticked from 9 seconds to 10, adjust time properly */
if( (tmp & 0x000f) == 0x000a ) tmp = tmp - 0x000a + 0x0010;
/* if we ticked from 59 seconds to 60, adjust time properly */
if( (tmp & 0x00f0) == 0x0060 ) tmp = tmp - 0x0060 + 0x0100;
/* if we ticked from 9 minutes to 10, adjust time properly */
if( (tmp & 0x0f00) == 0x0a00 ) tmp = tmp - 0x0a00 + 0x1000;
/* if we ticked from 59 minutes to 60, adjust time properly */
if( (tmp & 0xf000) == 0x6000 ) tmp = 0x0000;
*timeloc = tmp; /* update memory with new time value */
delay(1000);
}
它在tick文件中,1秒的延迟是。你能想出一个更正确的方法来达到目的吗?
最佳答案
标准的方法是跟踪上一次调用函数的时间,并在足够长的时间后重新运行它。
#include <unistd.h>
#include <sys/time.h>
#define SLEEP_INTERVAL 200
struct timeval last_pollkey_call, last_tick_call, now, diff;
memset(&last_pollkey_call, 0, sizeof(last_pollkey_call));
memset(&last_tick_call, 0, sizeof(last_pollkey_call));
while(1) {
gettimeofday(&now, NULL);
timersub(&now, &last_pollkey_call, &diff);
if (diff.tv_sec >= 1 || diff.tv_usec >= 1000) {
pollkey();
last_pollkey_call = now;
}
timersub(&now, &last_tick_call, &diff);
if (diff.tv_sec >= 1) {
tick();
last_tick_call = now;
}
usleep(SLEEP_INTERVAL);
}
你可以有尽可能多的活动,有尽可能多的不同间隔。
关于c - 如何开发此算法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18657912/