该程序侦听Altera DE2板的键,这些键可以启动、停止和重置计数器:
#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) { // 2^0+2^1+2^2
timeloc = 0x0;
} else if (action == 13) { // 2^0+2^2+2^3
RUN = 0;
} else if (action == 14) { // 2^1+2^2+2^3
RUN = 1;
} else if (action == 11) { // 2^0+2^1+2^3
tick(&timeloc);
}
}
int main() {
while (TRUE) {
pollkey();
puttime(&timeloc);
delay(1000);
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]);
}我还使用Nios 2程序集作为延迟:
.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我已经更新了程序,它的行为与预期的一样。变化是,我每毫秒需要一个动作,每秒需要一个动作,所以我使用了一个模块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);
delay(200);
} else if (action == 13) {
RUN = 0;
} else if (action == 14) {
RUN = 1;
} else if (action == 11) {
tick(&timeloc);
puttime(&timeloc);
puthex(timeloc);
delay(200);
}
}
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, 5800 #set 16911 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发布于 2013-09-08 20:19:01
您的外部原型最好位于定义它们的文件所共享的标题中。如果它们都是在汇编程序(如delay)中定义的,那么如果它们被多个C文件使用,它们仍然需要放在头中。在原型上:
puttime来说,接受非常量指针似乎很奇怪。它是修改引用的值,还是通过值传递?tick接受一个timeloc值并返回一个新值,它可能会更正常。int值可能应该是unsigned (例如,如果它们是位图之类的)。如果您的全局变量(timeloc或RUN)曾经从汇编程序或异步更新过,请确保将它们标记为volatile。RUN通常是run (大写通常用于常量)。如果只在这里访问,两者都应该是static。
事实似乎是多余的。它一无所获(对于我来说,while (1)和while (TRUE)一样容易理解),您甚至没有将它用于RUN状态。
在pollkey (它应该有一个void参数列表)中,您正在解释一个值,该值是一个活动的低位图。您的测试值的方式并不是立即就显而易见--如果您已经倒/屏蔽了该值,并针对1、2、4和8进行了测试,那么它将是。通过只对这些值进行测试,您将假设它们不能一起活动。也许那是真的。我宁愿看到一些常量,但不想看到那些常量(更好的1,2,4,8)。
在你的hex7seg中,ints可能应该是unsigned。我会将大小放在trantab中,以使编译器更有可能警告您,如果初始化器太多/少(取决于编译器警告级别),并基于相同的原因和可读性对值进行排列。临时变量是不必要的。
unsigned hex7seg(unsigned digit)
{
unisgned trantab[16] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78,
0x00, 0x10, 0x08, 0x03, 0x46, 0x21, 0x06, 0x0e};
return trantab[digit & 0xf];
}因为您不使用hex7seg2,所以请删除它。如果你需要它(这似乎不太可能),那么阿西姆说你不应该复制trantab
在您的delay代码中,每个循环有两个分支而不是一个分支。通常,我希望每个循环中只看到一个分支(内部和外部)。
outer: movi r8, delaycount
inner: subi r8, r8, 1
bneq r8, r0, inner
subi r4, r4, 1
delay: bneq r4, r0, outer
ret(假设bneq存在于Nios2中)。注意:在内部循环中对r0进行测试是正确的,而不是针对0吗?另外,如果您愿意,可以将入口点放在开头,在循环之前对0调用参数进行显式测试。
https://codereview.stackexchange.com/questions/30870
复制相似问题