六JTAG UART内核实验.docx
《六JTAG UART内核实验.docx》由会员分享,可在线阅读,更多相关《六JTAG UART内核实验.docx(15页珍藏版)》请在冰豆网上搜索。
六JTAGUART内核实验
2.2JTAGUART内核实验
1.实验目的
(1)熟悉JTAGUART内核结构;
(2)熟悉用C标准库函数访问JTAGUART;
(3)熟悉用HALAPI访问JTAGUART;
2.实验现象
(1)简单应用实验:
在信息栏打印“HellofromNiosII!
”
(2)C标准库实验:
根据用户从NiosIIIDE窗口“Console”栏输入0~4NiosII系统执行不同的操作,0—--两个灯全灭,1—--第一个灯亮,2----第二个灯亮,3----两个灯全亮,4----退出;若实验板上的第1个键按下,信息栏显示“Key1waspressed”,第2个键按下,信息栏显示“Key2waspressed”。
(3)HALAPI实验:
根据用户从NiosIIIDE窗口“Console”栏输入0~4NiosII系统执行不同的操作,0—--两个灯全灭,1—--第一个灯亮,2----第二个灯亮,3----两个灯全亮,4----退出。
3.实验原理
实验原理如图2.2.1所示,QuartusII顶层原理图如图2.2.2所示。
JTAGUART和JtagDebugModule实际上是通过JTAG集线器连到JTAG控制器上再与电脑相连。
带Avalon接口的JTAGUART设备实现PC与NiosII系统间的串行通信。
在许多设计中,JTAGUART常取代RS-232通信设备,用于字符的输入和输出。
与UART设备不同的是,JTAGUART是通过JTAG接口来传输数据的。
用户可以通过HALAPI和ANSIC标准库访问JTAGUART。
图2.2.1
由图2.2.1我们可以得到如表2.2.1所示的外设一览表:
表2.1.1
外设名称
描述
备注
cpu
NiosII/eDebugModule=Level1
sysid
系统ID
系统的唯一标识
sdram
Custom,Row=12,Column=8
Datawidth=16,Banks=4
flash
Custom,Addresswidth=21
Datawidth=8
三态桥
Registered
led_pio
PIO,2bits,outputonly
根据用户输入显示
key
PIO,2bits,inputonly
下降沿中断,使能边沿捕获
jtag_uart
使用默认设置
图2.2.2
4.实验内容
(1)在QuartusII中建立一个工程;
(2)使用SOPCBuilder建立生成一个具有表2.2.2所示元件的NiosII硬件系统;
(3)在QuartusII工程中添加PLL;
(4)建立基于NiosII的硬件系统并编译生成配置文件*.sof;
(5)在NiosIIIDE中建立对应硬件系统的NiosIIC/C++Application,编写通过ANSIC标准库访问JTAGUART设备的程序并验证;
(6)再建立一个NiosIIC/C++Application,编写通过HALAPI访问JTAGUART设备的程序并验证;
5.实验步骤
硬件系统的搭建不再详细介绍,整个系统如图2.2.3所示。
JTAGUART内核的详细构造参考“附录四Volume5EmbeddedPeripherals”。
图2.2.3
1)添加JTAGUART
在可用元件列表里双击JTAGUART(图2.2.4),不更改弹出的设置对话框的参数(图2.2.5),因为默认参数可以使面积和速度实现相对均衡。
图2.2.4
2)通过ANSIC标准库访问JTAGUART
首先我们使用NiosIIIDE提供的HelloWorld模板(图2.2.6)实现一个最简单而又经常用到的JTAGUART应用。
系统库属性中将stdout、stdin、stderr均选为jtag_uart(图2.2.7)。
程序如下所示,运行结果如图2.2.8所示。
图2.2.5
/*
*"HelloWorld"example.
*
*Thisexampleprints'HellofromNiosII'totheSTDOUTstream.Itrunson
*theNiosII'standard','full_featured','fast',and'low_cost'example
*designs.ItrunswithorwithouttheMicroC/OS-IIRTOSandrequiresaSTDOUT
*deviceinyoursystem'shardware.
*Thememoryfootprintofthishostedapplicationis~69kbytesbydefault
*usingthestandardreferencedesign.
*
*Forareducedfootprintversionofthistemplate,andanexplanationofhow
*toreducethememoryfootprintforagivenapplication,seethe
*"small_hello_world"template.
*
*/
#include
intmain()
{
printf("HellofromNiosII!
\n");
return0;
}
图2.2.6
图2.2.7
图2.2.8
下面所示程序将演示另一个稍为复杂的应用,程序注释得比较清楚,不再详细介绍,有关C标准库函数(fprintf(),fwrite(),getc()等)请读者自查阅相关书籍。
运行结果如图2.2.9所示。
/********************版权声明*****************************
*新疆大学信息科学与工程学院创新实验室
*文件名:
JTAG_CLib.c
*创建者:
吴占敏
*创建日期:
2010.4.30
*校验者:
*校验日期:
*版本号:
V1.0
*功能描述:
使用C库函数访问JTAGUART设备。
1、在IDE的Console栏打印
*菜单信息,操作者通过电脑键盘输入0~4五个数字中的一个控制
*实验板的LED灯开关状态;2、若有实验板上的按键按下,则在
*Console栏打印按键信息。
********************************************************/
#include
#include
#include"system.h"
#include"altera_avalon_pio_regs.h"
#include"sys/alt_irq.h"
#include"alt_types.h"
/**********************************************************
*名称:
KeyEdge_Isr()
*功能:
下降沿触发中断服务子程序
***********************************************************/
voidKeyEdge_Isr(void*context,alt_u32id)
{
//清边沿捕获寄存器
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0);
//两个键共用一个中断,所以应把按键的状态读回以判断是哪一个键触发的中断
alt_u8key_state=0;
key_state=IORD_ALTERA_AVALON_PIO_DATA(KEY_BASE);
key_state&=0x03;
switch(key_state)
{
case0x01:
//第1个按键
{
//重要说明:
为了验证方便在中断服务子程序里使用了printf()函数,
//实际应用时不建议在中断服务子程序里使用C标准库函数
printf("key1waspressed.\n");
break;
}
case0x02:
//第2个按键
{
printf("key2waspressed.\n");
break;
}
default:
break;
}
}
/**********************************************************
*名称:
PIO_Init()
*功能:
PIO口初始化,注册中断服务
***********************************************************/
voidPIO_Init(void)
{
//中断使能
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_BASE,0xff);
//清边沿捕获寄存器
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_BASE,0);
//LED初始化,全灭
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,3);
alt_irq_register(KEY_IRQ,NULL,KeyEdge_Isr);
}
/**********************************************************
*名称:
main()
*功能:
使用C库函数访问JTAGUART设备。
***********************************************************/
intmain()
{
charprompt=0;//实时存储输入信息
FILE*fp;//文件指针,指向JTAGUART
char*msg="PleaseEnterYourChoice:
\n";
PIO_Init();
//以文件读写方式打开JTAGUART设备
fp=fopen(JTAG_UART_NAME,"r+");
if(fp)
{
//打印菜单信息
fprintf(fp,"Menu:
\n");
fprintf(fp,"0:
AllLEDOff\n");
fprintf(fp,"1:
LED1On\n");
fprintf(fp,"2:
LED2On\n");
fprintf(fp,"3:
AllLEDOn\n");
fprintf(fp,"4:
Exit\n");
//该句=fprintf(fp,"PleaseEnterYourChoice:
\n");
//=printf("PleaseEnterYourChoice:
\n");
fwrite(msg,strlen(msg),1,fp);
while(prompt!
='4')//若输入'4'表示结束操作
{
prompt=getc(fp);//通过JTAGUART读取一个字符
switch(prompt)
{
case'0':
//两个LED均灭
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x03);
break;
}
case'1':
//第1个LED亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x01);
break;
}
case'2':
//第2个LED亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x02);
break;
}
case'3':
//两个LED均亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x00);
break;
}
default:
break;
}
if(ferror(fp))//检查错误是否与文件指针一起出现,若是,则清除
clearerr(fp);
}
fprintf(fp,"Exit.\n");
fclose(fp);
}
else
{
printf("OpenJTAGUARTfailed...\n");
}
return0;
}
图2.2.9
3)使用HALAPI访问JTAGUART
详细程序如下所示,通过HALAPI访问JTAGUART主要用到了几个具有UNIX风格的IO操作函数(write(),open(),read()等),有关这几个函数的详细使用方法请参考“附录五NiosIIsoftwaredeveloper”。
运行结果如图2.2.10所示。
/********************版权声明*****************************
*新疆大学信息科学与工程学院创新实验室
*文件名:
JTAG_API.c
*创建者:
吴占敏
*创建日期:
2010.5.1
*校验者:
*校验日期:
*版本号:
V1.0
*功能描述:
使用HALAPI访问JTAGUART设备。
在IDE的Console栏打印
*菜单信息,操作者通过电脑键盘输入0~4五个数字中的一个控制
*实验板的LED灯开关状态。
********************************************************/
#include
#include
#include
#include"system.h"
#include"unistd.h"
#include"altera_avalon_pio_regs.h"
/**********************************************************
*名称:
main()
*功能:
使用HALAPI访问JTAGUART设备。
***********************************************************/
intmain(void)
{
intfd;
intcount;
char*menu="Menu:
\n";
char*choice0="0:
AllLEDOff\n";
char*choice1="1:
LED1On\n";
char*choice2="2:
LED2On\n";
char*choice3="3:
AllLEDOn\n";
char*choice4="4:
Exit\n";
char*msg="PleaseEnterYourChoice:
\n";
char*buf;
fd=open(JTAG_UART_NAME,O_RDWR);//以可读写方式打开设备文件
if(fd<0){//打开失败
printf("OpenJTAGUARTfailed...\n");
return1;
}
//打印菜单信息
write(fd,menu,strlen(menu));
write(fd,choice0,strlen(choice0));
write(fd,choice1,strlen(choice1));
write(fd,choice2,strlen(choice2));
write(fd,choice3,strlen(choice3));
write(fd,choice4,strlen(choice4));
write(fd,msg,strlen(msg));
while(*buf!
='4')
{
count=read(fd,buf,1);//读入数据,读者可以观察一下count的值
write(fd,buf,count);//输出读入数据
switch(*buf)
{
case'0':
//两个LED均灭
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x03);
break;
}
case'1':
//第1个LED亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x01);
break;
}
case'2':
//第2个LED亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x02);
break;
}
case'3':
//两个LED均亮
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0x00);
break;
}
default:
break;
}
}
printf("\nExit...");
close(fd);//关闭设备
return0;
}
图2.2.10