Chapter22: 国产FPGA之8051中断使用
0赞第二十二章
国产FPGA之8051中断使用
本章仅仅是为了通过使用8051外部中断源,做个示范,让大家知道国产FPGA内部资源的使用方法!
玩过8051的孩纸都知道,8051有5个中断源,其介绍如下:
8051单片机有5个中断源:
●INTO-外部中断0请求,低电平有效,通过P3.2引脚输入。
●INTl-外部中断1请求,低电平有效,通过P3.3引脚输入。
●TO-定时器/计数器0溢出中断请求。
●T1-定时器/计数器1溢出中断请求。
●TX/RX-串口中断请求。
中断优先级是指通过软件设定中断优先级的控制位使某种中断被系统优先处理。8051单片机有两个中断优先级,可通过软件设定IP来规定某个中断位高级中断,相反为低级中断。
但是,我们的国产FPGA有13个中断源,其包括如下:
本例程,我们将采用外部中断0,并且设置为下降沿触发,没接收到一次触发,led_data自增,流水灯点亮一位。
由于我们的核心板上没有外部按键,本例程我模拟了一个按键的中断,如下:
module key_analog
(
input clk,
input rst_n,
output ext_key_analog
);
reg [23:0] cnt;
reg ext_key_analog;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= 0;
ext_key_analog <= 0;
end
else
begin
if(cnt < 24'd11059200)
begin
cnt <= cnt + 1'b1;
end
else
begin
cnt <= 0;
ext_key_analog <= ~ext_key_analog;
end
end
end
Endmodule
在Primance中,首先,我们在PLL中设置,输出clkcpu作为8051内核的时钟,以及clkout0作为key_analog的时钟。通过互联,将P3^2连接到ext_key_analog上,作为中断0的外部按键信号,FPGA中相关逻辑代码如下所示:
相关代码如下:
module irq_design
(
output [7:0] led_data //8位LED灯
);
//-----------------------------
//振荡器例化
wire clk_1106; //11.06MHz
myOscillator u_myOscillator
(
.clkout (clk_1106)
);
//-----------------------------
//PLL例化
wire clkcpu; //8051内核全局时钟 11.06M
wire clkout0; //logic clock 11.06M
myPll u_myPll
(
.clkin (clk_1106), // Reference clock input.
.clkcpu (clkcpu), // Main clock output.
.clkout0 (clkout0)
);
//--------------------------------
//8051内核例化
wire [7:0] port3i;
mySystem u_mySystem
(
//8051 MSS时钟
.clkcpu (clkcpu), //8051内核时钟 11.06MHz
//Fabric总结结构接口
.reset (1'b1), //始终有效
.clkcpuen (),
.clkperen (),
.ro (),
.swd (),
//通用IO口
.port0i (),
.port1i (),
.port2i (),
.port3i (port3i),
.port0o (led_data), //P0端口为流水灯
.port1o (),
.port2o (),
.port3o (),
//SPI总线接口
.scki (),
.scko (),
.scktri (),
.ssn (),
.misoi (),
.misoo (),
.misotri (),
.mosii (),
.mosio (),
.mositri (),
.spssn (),
//emif外部存储接口
.clkemif (),
.memack (),
.memdatai (),
.memdatao (),
.memaddr (),
.memwr (),
.memrd (),
//4K的DPRAM 接口
.clkb (),
.cenb (),
.wenb (),
.db (),
.ab (),
.qb ()
);
//模拟按键输入
wire ext_key_analog;
key_analog u_key_analog
(
.clk (clkout0),
.rst_n (1'b1),
.ext_key_analog(ext_key_analog)
);
//外部按键连到中断 0
wire ext_int0 = ext_key_analog;
//中断0 复用到 P3口
assign port3i[2] = ext_int0;
endmodule
最终省城的 RTL图如下所示从左到右非别为“外部无源晶振时钟模块”,“PLL模块”,“按键模拟生成模块”,“8051内核”
最后,在Keil中建立工程,设计代码,主要完成以下几部分工作:
(1)打开中断
(2)选择中断标志(低电平或者下降沿)
(3)编写中断处理函数
相关代码如下所示:
#include
void Delay_ms(unsigned int cnt);
sbit KEY = P3^2;
unsigned char led_data = 0;
void main()
{
EX0 = 1; //enable Ext Int 0
IT0 = 1; //负边沿触发
EAL = 1; //开总中断
P0 = 0xff; //关闭LED灯
while(1)
{
P0 = ~led_data; //低电平亮
}
}
//ms延时函数
void Delay_ms(unsigned int cnt)
{
unsigned int i;
while(cnt--)
{
for(i=0; i<255; i++);
}
}
void isr_ExtInt0() interrupt 0
{
EAL = 0; //关中断
Delay_ms(20) ; //延时20ms
if(KEY == 0)
{
led_data ++;//led自增
}
Delay_ms(20); //延时20ms
EAL = 1; //开中断
}
如上代码所示,每当接收到外部中断0下降沿信号的时候,关闭中断,延时20ms,读取按键值,处理相关参数,之后一段延时后,打开中断,进行下一轮扫描。在led_data全局变量更新后,P0 = ~led_data;同时更新了LED灯的值。
由于在key_analog中模拟了1s的高低电平,因此LED从0x00开始到0xff自增。
至此,Astro II 8051内核中断源使用完毕,总结如下:
(1)在Primance中verilog建立互联结构
(2)在keil中编写中断处理函数生成hex
(3)在Primace中编译综合,成成spi_acf,download
AstroII的8051内部资源丰富,不仅具有13个中断源,还有uart,spi,I2C等总线,相关操作只要根据数据手册配置参数,如上操作即可!
Just Try!!!
本例程下载地址如下:http://www.chinaaet.com/lib/detail.aspx?id=89636
AstroII芯片技术手册:http://www.chinaaet.com/lib/detail.aspx?id=89637