今天看了一个例程,在nios2中用c实现一个电子钟.
c是大概是这样的#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include <unistd.h>
#include "sys/alt_irq.h"
#include "alt_types.h"
#include "LCD.h"//自己设计的头文件
static volatile alt_u8 hour;
static volatile alt_u8 minute;
static volatile alt_u8 second;
static volatile alt_u16 year;
static volatile alt_u8 month;
static volatile alt_u8 day;
static volatile alt_u8 max_day;
static int flag;
static int begin;
static alt_u8 str1[17];
static alt_u8 str2[17];
volatile int edge_capture;
alt_u8 Tyear, Hyear, Dyear, Nyear;
static void last_day(){
if(month==4||month==5||month==9||month==11)
max_day=30;
else if(month==2){
if((year%4==0&&year%100!=0)||year%400==0)
max_day=29;
else
max_day=28;
}
else
max_day=31;
}
static void handle_button_interrupts(void* context, alt_u32 id){
volatile int* edge_capture_ptr=(volatile int*)context;
*edge_capture_ptr=IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE,0);
}
static void init_button_pio(){
void* edge_capture_ptr=(void*)&edge_capture;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE,0xf);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE,0x0);
alt_irq_register(BUTTON_PIO_IRQ,edge_capture_ptr,handle_button_interrupts);
}
void LCD_Init()//lcd初始化
{
lcd_write_cmd(LCD_DISPLAY_BASE,0x38); //lcd_write_cmd在头文件"LCD.h"中对应IOWR(base, 0, data)
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x01);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x06);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x80);
usleep(2000);
}
.......
.......
static void handle_button_press(){
if(flag==0){
switch(edge_capture){
case 0x1:
timer_set();
display_time1();
usleep(500000);
display_time();
break;
case 0x2:
display_day();
break;
case 0x4:
display_time();
break;
default:
display_time();
break;
}
}
........
........
int main()
{
init_button_pio();
LCD_Init();
initial_time();
while(1){
if(begin==0){
usleep(1000000);
second++;
if(second>=60){
second=0;
minute++;
}
if(minute>=60){
minute=0;
hour++;
}
if(hour>=24){
hour=0;
day++;
}
last_day();
if(day>max_day){
day=1;
month++;
last_day();
}
if(month>12){
day=1;
year++;
}
}
if(edge_capture!=0){
handle_button_press();
}
else{
if(flag==3||flag==4||flag==5||flag==6)
display_day();
else
display_time();
}
}
我想问一下:以上程序中标红色的那些字
1.(void LCD_Init中)应该是为了在对lcd初始化中实现某项功能吧??
这些数对应的是什么功能呢?或者比如我自己要写程序时哪里能查到??我查了altra的几个文档都没有说明啊
2.(void handle_button_press中)应该是edge_capture在电路板上按下不同按键时捕获的值吧??
哪里说明的那几个按键对应的是这几个数字??
小弟初学,请帮帮忙
谢谢了!!
1、LCD_Init中的红字是初使化的命令字,具体是什么功能,要看你用的LCD是什么控制器(如SED1335、ST7920等),你可以看一下LCD控制芯片的型号,查后在网上查找它的datasheet(www.alldatasheet.com),手册里有对它的包括命令在内的详细说明。这个不是在altera的文件中查。
2、edge_capture是捕获的按键值,具体对应哪个键,我给你打个比方:
假设你的板上有四个键:Button3,Button2,Button1,Button0为别对应PIO中的key[3],key[2],key[1],key[0],如果你按下Button0,则key[0]为1,key[3..1]为0,所以key就为b(0001)=h(0x01),同样
按Button1,key[1]为1,key[3..2]和key[0]为0,key就为b(0010)=h(0x02),
如果按下两个,如Button1,Button0,则,key:b(0011)=h(0x03)
谢谢楼上
第二个问题明白了
第一个问题我用的实验箱没给出具体lcd的型号,难道是通用的那种?郁闷,不过倒是给了5个不同型号lcd的datasheet.....晕
还有一个问题请教:
还是那个程序中
void LCD_Init()
{
lcd_write_cmd(LCD_DISPLAY_BASE,0x38);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x0C);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x01);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x06);
usleep(2000);
lcd_write_cmd(LCD_DISPLAY_BASE,0x80);
usleep(2000);
}
....
....
static void display_day(){
alt_u8 Tyear, Hyear, Dyear, Nyear;
Tyear = (alt_u8)(year/1000);
Hyear = (alt_u8)((year%(1000*Tyear))/100);
Dyear = (alt_u8)((year%(1000*Tyear+100*Hyear))/10);
Nyear = (alt_u8)(year%(1000*Tyear+100*Hyear+10*Dyear));
str1[0]=' ';
str1[1]=' ';
str1[2]=' ';
str1[3]= (alt_u8)(Tyear+0x30);
str1[4]= (alt_u8)(Hyear+0x30);
str1[5]= (alt_u8)(Dyear+0x30);
str1[6]= (alt_u8)(Nyear+0x30);
str1[7]='-';
str1[8]=(alt_u8)(month/10+0x30);
str1[9]=(alt_u8)(month%10+0x30);
str1[10]='-';
str1[11]=(alt_u8)(day/10+0x30);
str1[12]=(alt_u8)(day%10+0x30);
str1[13]=' ';
str1[14]=' ';
str1[15]=' ';
str1[16]='\0';
LCD_Line2();
LCD_Show_Text(str1);
}
.....
void LCD_Show_Text(char* Text)
{
int i;
for(i=0;i<strlen(Text);i++)
{
lcd_write_data(LCD_DISPLAY_BASE,Text);
usleep(2000);
}
}
这里好像把不同的数都写入了同一个地址??请问是怎么回事?
难道是类似于堆栈的原理?
谢谢!!
请注意lcd_write_cmd()和lcd_write_data()是不同的函数,它们中有语句控制LCD的A0(有的是RS)线,就是这个线决定了是向LCD发指令或是数据。而LCD_DISPLAY_BASE接的应该是LCD的DATA线。
根据你的LCD的初使化命令字看,好像是ST7920的控制器。
我的理解是这样:LCD_DISPLAY_BASE在system.h中定义为0x01011080
(#define LCD_DISPLAY_BASE 0x01011080) 0x01011080即在sopc builder中为lcd分配的
基地址(base 0x01011080 end 0x0101108F)
请问这里的base end的地址是什么意思??和哪里对应的??
你说"LCD_DISPLAY_BASE接的应该是LCD的DATA线"是和这里对应吗??我有点不大明白.....
能给我讲一下吗?
谢谢了!
我认为实际上只是LCD_DISPLAY_BASE (0x01011080)该地址所在的一个字节对应着LCD的DATA线,DATA也是8根,一个字节.
从0x01011081开始至0x0101108F都是空着的地址,没有实际的东西与之对应。
哦.....
谢谢了...
小弟正在学习NIOS 楼主可否把电子钟的所有原程序发给我 万分感谢
邮箱:djjyt@163.com
楼上的发言对你应该有帮助吧。
你只要掌握了LCD的读写,其它应该不难吧。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |