【NiosII学习】第五篇、TIMER定时器中断

目录

第一部分、关于Timer定时器的储备知识

1、内部寄存器的个数

2、你要会的寄存器的使用方法

第二部分、新建Quartus II工程

1、注意

第三部分、修改别人软核

1、添加定时器IP核详细步骤

2、添加控制LED的PIOIP核步骤

3、复制生成的LED端口

第四部分、编写Quartus中的verilog代码

1、注意

第五部分、编写Ecplise里面的C代码

1、注意

2、C代码功能解析

3、代码

第六部分、总结

1、结果演示

2、闲话

3、完整资料


第一部分、关于Timer定时器的储备知识

1、内部寄存器的个数

【NiosII学习】第五篇、TIMER定时器中断_第1张图片

2、你要会的寄存器的使用方法

(1)status寄存器

//清除Timer中断标志寄存器 
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE, 0);

(2)control寄存器

让control寄存器低四位为:0x0007(低四位0111),0——计数器开始(STOP = 0)计数器停止(STOP = 1);1——计数器开始运行(START = 1);1——设置为连续计数模式(CONT = 1)如果是0就是只计数一次;1——打开定时器中断(ITO = 1);

注意:这里我没有详细介绍NiosII定时器的寄存器的详细内容,自己去百度哦,或者私信找我要资料。

IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_1_BASE,0x0007); 

(3)周期的高八位和第八位寄存器

明白计算方法:因为内部计数器是递减的,和51单片机是一样的。

所以你要延时1s时,那么1s除以1/100M = 1s *100M - 1 在到计算机中进行换算,再将高十六位赋值给PERIODH,低十六位赋值给PERIODL。(这里和51单片机的定时器中断特别像,只不过51单片机是高8位和低8位)

注意:不能超出定时器的位数,如果这里是32位的计数器(不信你自己去下面看定时器的配置,有个32),那么计数的最大值应该小于42.9s

100MHz表示频率是100M每秒,1/100M = 0.000 000 01s

所以 定时器中 2的32次方 =  4 294 967 296 * 0.000 000 01s =42.9s

2的64次方 = 184467440737 09 551 616 * 0.000 000 01 =5930.6年

//设置 PERIOD 寄存器
//PERIODH << 16 | PERIODL = 计数器周期因子 * 系统时钟频率因子 - 1
//PERIODH << 16 | PERIODL = 5s*100M - 1 = 499999999 = 0x1DCD_64FF
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_1_BASE, 0x1DCD);//5s对应的高16位
OWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_1_BASE, 0x64FF); //5s对应的低16位

第二部分、新建Quartus II工程

1、注意

第一步、还是复制小梅哥的LCD9341的初始工程,到自己建立的文件夹中,为什么老是用这个工程?因为这个工程相当于一个基本的工程,如果你自己从零搭建,最终的结果还是和这个工程一样,那不如用别人搭建好的,我们会用就行。这个复制的详细步骤在(【NiosII学习】第一篇、如何烧录NiosII工程:https://blog.csdn.net/Learning1232/article/details/110225728)。

注意:如果你和我FPGA型号不一样,那就复制你的SOPC工程文件到文件夹中,和前面一样,因为其他的步骤大致都和我的一样,没有区别。

【NiosII学习】第五篇、TIMER定时器中断_第2张图片

第三部分、修改别人软核

1、添加定时器IP核详细步骤

第一步、Timer定时器IP核的配置

【NiosII学习】第五篇、TIMER定时器中断_第3张图片

第二步、进行连线,然后分配地址,然后再配置中断号,这里默认配置为3。

【NiosII学习】第五篇、TIMER定时器中断_第4张图片

2、添加控制LED的PIOIP核步骤

这里忘了回去看(第二篇),然后生成软核系统。

【NiosII学习】第五篇、TIMER定时器中断_第5张图片

3、复制生成的LED端口

【NiosII学习】第五篇、TIMER定时器中断_第6张图片

第四部分、编写Quartus中的verilog代码

1、注意

这里定时器没有生成可以例化的端口但是需要例化控制LED的有四个端口,随后进行预编译。预编译完成后,分配四个LED的引脚,再全编译。

 

module AC620_GHRD(

	//对端口进行定义
	output wire  [3:0] pio_led,

	input  wire        clk,                           //                        clk.clk
	input  wire        reset_n,                     //                      reset.reset_n
	output wire        lcd_rst,                    //                    lcd_rst.export
	output wire        lcd_rd_n,                     //                     lcd_rd.export
	output wire        lcd_bl,                     //                     lcd_bl.export
	output wire        lcd_wr_n,                     //                     lcd_wr.export
	output wire        lcd_rs,                     //                     lcd_rs.export
	output wire        lcd_cs_n,                     //                     lcd_cs.export
	inout  wire [15:0] lcd_data,                     //                     lcd_db.export
	output wire        sdram_clk,                     //                  sdram_clk.clk
	output wire [11:0] sdram_addr,                        //                      sdram.addr
	output wire [1:0]  sdram_ba,                          //                           .ba
	output wire        sdram_cas_n,                       //                           .cas_n
	output wire        sdram_cke,                         //                           .cke
	output wire        sdram_cs_n,                        //                           .cs_n
	inout  wire [15:0] sdram_dq,                          //                           .dq
	output wire [1:0]  sdram_dqm,                         //                           .dqm
	output wire        sdram_ras_n,                       //                           .ras_n
	output wire        sdram_we_n,                         //                           .we_n
	input  wire        uart_0_rxd,                        //                     uart_0.rxd
	output wire        uart_0_txd,                        //                           .txd
	output wire        epcs_dclk,                         //                       epcs.dclk
	output wire        epcs_sce,                          //                           .sce
	output wire        epcs_sdo,                          //                           .sdo
	input  wire        epcs_data0                         //                           .data0
);

    mysystem u0 (
		.clk_clk                           (clk),                           //                        clk.clk
		.reset_reset_n                     (reset_n),                     //                      reset.reset_n
           .uart_0_rxd                        (uart_0_rxd),                        //                     uart_0.rxd
           .uart_0_txd                        (uart_0_txd),                        //                           .txd
           .epcs_dclk                         (epcs_dclk),                         //                       epcs.dclk
           .epcs_sce                          (epcs_sce),                          //                           .sce
           .epcs_sdo                          (epcs_sdo),                          //                           .sdo
           .epcs_data0                        (epcs_data0),                        //
		.lcd_rst_export                    (lcd_rst),                    //                    lcd_rst.export
		.lcd_bl_export                     (lcd_bl),                     //                     lcd_bl.export
		.lcd_wr_n                          (lcd_wr_n),                          //                        lcd.wr_n
		.lcd_rd_n                          (lcd_rd_n),                          //                           .rd_n
		.lcd_data                          (lcd_data),                          //                           .data
		.lcd_rs                            (lcd_rs),                            //                           .rs
		.lcd_cs_n                          (lcd_cs_n),                           //  
		.sdram_clk_clk                     (sdram_clk),                     //                  sdram_clk.clk
		.altpll_0_phasedone_conduit_export (), // altpll_0_phasedone_conduit.export
		.altpll_0_locked_conduit_export    (),    //    altpll_0_locked_conduit.export
		.altpll_0_areset_conduit_export    (),    //    altpll_0_areset_conduit.export
		.sdram_addr                        (sdram_addr),                        //                      sdram.addr
		.sdram_ba                          (sdram_ba),                          //                           .ba
		.sdram_cas_n                       (sdram_cas_n),                       //                           .cas_n
		.sdram_cke                         (sdram_cke),                         //                           .cke
		.sdram_cs_n                        (sdram_cs_n),                        //                           .cs_n
		.sdram_dq                          (sdram_dq),                          //                           .dq
		.sdram_dqm                         (sdram_dqm),                         //                           .dqm
		.sdram_ras_n                       (sdram_ras_n),                       //                           .ras_n
		.sdram_we_n                        (sdram_we_n),                         //                           .we_n
		
		
		//复制过来的端口
		.pio_led_export                    (pio_led)  //   pio_led.export
	
	);

endmodule

第五部分、编写Ecplise里面的C代码

1、注意

这里省略了Ecplise软件的使用说明,如果忘了的小伙伴,可以看我的《【NiosII学习】第一篇、如何烧录NiosII工程https://blog.csdn.net/Learning1232/article/details/110225728》,有详细的步骤。注意:你还能忘,那你真该打。

2、C代码功能解析

四个LED亮5秒又灭五秒,如此循环

3、代码

/*
 * main.c
 *
 *  Created on: 2020年12月13日
 *      Author: dpt
 *
 */
#include "system.h" //系统头文件
#include "altera_avalon_timer_regs.h" //定时器头文件
#include "altera_avalon_pio_regs.h" //PIO 头文件
#include "sys/alt_irq.h" //中断头文件
#include "unistd.h" //延迟函数头文件
#include  //标准的输入输出头文件
#include "priv/alt_legacy_irq.h"

alt_u32 i=0;
alt_u32 timer_isr_context; //定义全局变量以储存 isr_context 指针
void Timer_Initial(void); //定时器中断初始化
void Timer_ISR_Interrupt(void); //定时器中断服务子程序

//--------------------------------------------------------------------------- //-- 名称 : Timer_Initial()
//-- 功能 : 定时器中断初始化
//-- 输入参数 : 无
//-- 输出参数 : 无§4 Qsys 丰富多彩的内置 IP 核 161
//---------------------------------------------------------------------------
 void Timer_Initial(void)
 {
	//改写 timer_isr_context 指针以匹配 alt_irq_register()函数原型
	void* isr_context_ptr = (void*) &timer_isr_context;
	//设置 PERIOD 寄存器
	//PERIODH << 16 | PERIODL = 计数器周期因子 * 系统时钟频率因子 - 1
	//PERIODH << 16 | PERIODL = 5s*100M - 1 = 499999999 = 0x1DCD_64FF
	IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_1_BASE, 0x1DCD);
	IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_1_BASE, 0x64FF);

	//设置 CONTROL 寄存器
	//位数 | 3 | 2 | 1 | 0 |
	//CONTROL | STOP | START | CONT | ITO |
	//ITO 1,产生 IRO; 0,不产生 IRQ
	//CONT 1,计数器连续运行直到 STOP 被置一; 0,计数到 0 停止
	//START 1,计数器开始运行; 0,无影响
	//STOP 1,计数器停止运行; 0,无影响
	IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_1_BASE,
	ALTERA_AVALON_TIMER_CONTROL_START_MSK | //START = 1
	ALTERA_AVALON_TIMER_CONTROL_CONT_MSK | //CONT = 1
	ALTERA_AVALON_TIMER_CONTROL_ITO_MSK); //ITO = 1
	
	//注册Timer1中断
	alt_irq_register(TIMER_1_IRQ, NULL, Timer_ISR_Interrupt);
 }

//---------------------------------------------------------------------------
//-- 名称 : Timer_Initial()
//-- 功能 : 定时器中断服务子程序
//-- 输入参数 : timer_isr_context,用于传递中断状态寄存器的值,id,中断号
//-- 输出参数 : 无
//---------------------------------------------------------------------------
void Timer_ISR_Interrupt(void)
{
	//用户中断代码
	i = 1;
	//应答中断,将 STATUS 寄存器清零
	IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_1_BASE,~ALTERA_AVALON_TIMER_STATUS_TO_MSK);
}


//---------------------------------------------------------------------------
//-- 名称 : main()
//-- 功能 : 程序入口
//-- 输入参数 : 无
//-- 输出参数 : 无
//---------------------------------------------------------------------------
int main(void)
{
	alt_u32 led_state = 0xff; //初始化 Led
	Timer_Initial(); //初始化定时器中断

	printf("Welcome To Timer Ip Demo Program... \n");
	IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x00); //首先让四个灯全亮
	while(1)
	{
		if(i == 1)
		{
			IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, led_state);//使 led 全灭
			led_state = ~led_state;
			i = 0;
		}
	}
}

第六部分、总结

1、结果演示

我已经拍成视频放在群文件中,你也可以先点击这个链接直接观看(https://live.csdn.net/v/120133),这里放张图片。

2、闲话

这篇笔记所设计到的所有的资料我都会放到下面这个群的群文件中,欢迎老铁扫码进QQ群一起学习。博主也还是笨学生,我要是不会可别喷我哈。当然还有第二种方法,关注我,就可以直接下载了!

3、完整资料

欢乐的白嫖时光从来不会缺席,向白嫖致敬!(完整工程、演示视频、参考资料下载链接:https://download.csdn.net/download/Learning1232/13680002)

 

你可能感兴趣的:(FPGA的学习之旅,fpga)