zynq板zedboard+vitis设计(三)状态机及中断,PL与PS部分的状态交互

前言

本期讲的是一个状态机以及中断相结合的应用,展示的试验功能较为简单,主要是实现PL与PS部分的状态交互。

1.状态机部分

首先是状态机实现的功能。初始处于idle状态(led_idle亮起)收到开始指令(start)后切换到状态a,并向ps端发出一条指令,使ps端产生中断并执行相应命令(这里是输出一句话)。ps端完成任务后,返回一条指令done,状态机收到done指令后切换到状态b,并点亮led灯。保持b状态直到检测到按下按键(key),熄灭led并切回idle状态。

状态机代码

module blog(
input clk,
input rst_n,
input key,
input start,
input done,

output reg print,
output reg led_done,
output reg led_idle
);

parameter idle=0,a=1,b=2;
reg [1:0] state,nstate;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        state<=idle;
    else
        state<=nstate;
end

always @(*)begin
    case(state)
        idle:begin
            if(start)
                nstate=a;
            else
                nstate=state;
        end
        a:begin
            if(done)
                nstate=b;
            else
                nstate=state;
        end
        b:begin
            if(key)
                nstate=idle;
            else
                nstate=state;
        end
        default:;
    endcase
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        print<=1'b0;
        led_done<=1'b0;
        led_idle<=1'b0;
    end
    else if(state==idle)begin
        print<=1'b0;
        led_done<=1'b0;
        led_idle<=1'b1;
    end
    else if(state==a)begin
        print<=1'b1;
        led_done<=1'b0;
        led_idle<=1'b0;
    end
    else if(state==b)begin
        print<=1'b0;
        led_done<=1'b1;
        led_idle<=1'b0;
    end
    else begin
        print<=1'b0;
        led_done<=1'b0;
        led_idle<=1'b0;
    end
end
endmodule

block design设计

 bd内添加zynq后如图添加中断及emio接口

 在bd内右击空白处可以将编写的状态机设计文件作为模块添加进来

如图进行连线

 约束文件

set_property IOSTANDARD LVCMOS33 [get_ports key]
set_property IOSTANDARD LVCMOS33 [get_ports start]
set_property IOSTANDARD LVCMOS33 [get_ports led_done]
set_property IOSTANDARD LVCMOS33 [get_ports led_idle]
set_property PACKAGE_PIN N15 [get_ports key]
set_property PACKAGE_PIN R18 [get_ports start]
set_property PACKAGE_PIN T22 [get_ports led_done]
set_property PACKAGE_PIN T21 [get_ports led_idle]

 2.vitis部分

代码

#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"

#define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID   //PS端  GPIO器件 ID
#define SCUGIC_ID    XPAR_SCUGIC_0_DEVICE_ID    //中断控制器 ID

#define intr_id 61     //中断号

#define print_done 54  //将print_done信号连接到EMIO0

XGpioPs gpiops_inst;            				 //PS端 GPIO 驱动实例
XGpioPs_Config *gpiops_cfg_ptr; 				 //PS端 GPIO 配置信息
XScuGic          scugic_inst;                    //中断控制器  驱动实例
XScuGic_Config * scugic_cfg_ptr;                 //中断控制器  配置信息


void print_handler(void *CallbackRef);           //中断服务函数

int main()
{
    //根据器件ID查找配置信息
    gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
    scugic_cfg_ptr = XScuGic_LookupConfig(SCUGIC_ID);

    //初始化器件驱动
    XGpioPs_CfgInitialize(&gpiops_inst, gpiops_cfg_ptr, gpiops_cfg_ptr->BaseAddr);
    XScuGic_CfgInitialize(&scugic_inst, scugic_cfg_ptr, scugic_cfg_ptr->CpuBaseAddress);

    //设置print_done为输出
    XGpioPs_SetDirectionPin(&gpiops_inst, print_done, 1);
    //使能输出
    XGpioPs_SetOutputEnablePin(&gpiops_inst, print_done, 1);

    //设置中断优先级和触发类型(高电平触发)
    XScuGic_SetPriorityTriggerType(&scugic_inst, intr_id, 0xA0, 0x1);
    //关联中断ID和中断处理函数
    XScuGic_Connect(&scugic_inst, intr_id, print_handler,(void *) intr_id);
    //使能AXI GPIO中断
    XScuGic_Enable(&scugic_inst, intr_id);

    //设置并打开中断异常处理功能
    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
    Xil_ExceptionEnable();

    return 0;
}

//中断服务(处理)函数
void print_handler(void *CallbackRef)
{
    printf("print done!\n");
	XGpioPs_WritePin(&gpiops_inst, print_done,1);//中断完成后,将print_done信号拉高,使状态机切换状态
}

上板验证

 烧录好程序后,LD1会亮起,表示此刻处于idle状态

按下BTNR按键后(对应状态机内start命令),ps端会产生一个中断并在右下角terminal内输出一句话“print done!”,然后LD0亮起,表示此刻切换到了状态b,按下BTNL按键后(对应key命令),LD0熄灭,LD1亮起,即又切换回到IDLE状态

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值