Soc之按键控制LED
一、硬件设置
1. 添加按键、LED
在Platform Designer 中添加两个按键、两个LED:
LED为输出:
Key为输入:
Assign Base Address
:
Generate HDL
:
Show Instantiation Template
:
复制最后两行:
Finish
:
2. 修改Verilog代码
改动1:
改动2:
3. 编译
编译后,进行引脚设置,再次编译。
4. 文件生成
参考SoC之HelloWorld
完成 生成rbf文件 、 生成新的hps_0头文件,并替换SD卡文件。
二、软件设置
参考SoC之HelloWorld打开Eclipse
并创建工程和源文件,并添加头文件:
编写C代码:
/*
* key_led.c
*
* Created on: 2022年7月19日
* Author: Sherlock
*/
//gcc标准头文件
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
//HPS厂家提供的底层定义头文件
#define soc_cv_av //开发平台Cyclone V 系列
#include "hwlib.h"
#include "socal/socal.h"
#include "socal/hps.h"
//与用户具体的HPS 应用系统相关的硬件描述头文件
#include "hps_0.h"
#define HW_REGS_BASE (ALT_STM_OFST) //HPS外设地址段基地址
#define HW_REGS_SPAN (0x04000000) //HPS外设地址段地址空间 64MB大小
#define HW_REGS_MASK (HW_REGS_SPAN - 1) //HPS外设地址段地址掩码
static unsigned long * led_pio_virtual_base = NULL;
static unsigned long * key_pio_virtual_base = NULL;
static void * virtual_base;
int init(){
// open函数打开MMU,获取总线虚拟地址
int fd = open("/dev/mem", (O_SYNC | O_RDWR));
if (fd == -1){
printf("Open MMU 失败!\n");
return -1;
}
// 映射虚拟地址
virtual_base = mmap(NULL, HW_REGS_SPAN, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, HW_REGS_BASE);
if ((unsigned long)virtual_base == MAP_SHARED){
printf("地址映射失败");
return 1;
}
// 获取LED和Key的地址
led_pio_virtual_base = virtual_base +
((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_LED_BASE) & (unsigned long)(HW_REGS_MASK));
key_pio_virtual_base = virtual_base +
((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_KEY_BASE) & (unsigned long)(HW_REGS_MASK));
return fd;
}
int main(){
int fd = init();
if (fd == -1){
printf("初始化失败\n");
return 1;
}
int i;
while (1){
for (i = 0; i < 2; i++){
if (!((*(key_pio_virtual_base + 0)) & (1 << i))){ // 第i位是0
*(led_pio_virtual_base + 0) = *(led_pio_virtual_base + 0) | (1 << i); // 将第i位变1
} else {
*(led_pio_virtual_base + 0) = *(led_pio_virtual_base + 0) & (~(1 << i)); // 将第1位变0
}
}
}
if (munmap(virtual_base, HW_REGS_SPAN) == -1){
printf("取消映射失败\n");
close(fd);
return -1;
}
close(fd);
return 0;
}
运行结果: