基于NIOS-II的示波器:PART2 界面动态显示功能
本文所有的硬件基础以及工程参考来自魏坤示波仪,重新实现驱动并重构工程。
version 0.2 界面动态显示功能
界面显示功能原理
显示波形有如下两个方案:
- 每一帧直接重绘显示界面,再显示下一帧图形
- 用背景色覆盖上一帧图形,再显示被毁坏的坐标,最后显示下一帧图形
第一种解决方案代码比较简单,但是实际测试刷新缓慢(以肉眼可测的速度刷新),故选择第二种方案。
其中有几点需要注意的部分:
- 两个点直接需要连接起来,可以按照显示芯片写的顺序,依次填充y轴,来达到连线。
- 规划将波形数据保存在DISP数组中,再绘制的同时写入CLR数组中,供下一轮清理波形使用。
清波形函数如下:
/*
* 函数名:CLR_WAVE_CH1
* 功能:清除CH1波形
* 日期:2017-02-16
*/
void CLR_WAVE_CH1() {
unsigned int i, k;
for (i = 0; i < 400; i++) {
//确认CLR中有波形数据(在有效区域内)
if (CLR_DATA_CH1[i] > 60 && CLR_DATA_CH1[i] < 300) {
//清除这个点
set_addr(i + 11, CLR_DATA_CH1[i]);
send_data(WAVE_BACK_COLOR);
set_addr(i + 11, CLR_DATA_CH1[i] + 1);
send_data(WAVE_BACK_COLOR);
set_addr(i + 11, CLR_DATA_CH1[i] - 1);
send_data(WAVE_BACK_COLOR);
//下面清除连接两个点的线
if (i < 399) {
if (CLR_DATA_CH1[i] < CLR_DATA_CH1[i + 1]) {
set_addr(i + 11, CLR_DATA_CH1[i]);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, WAVE_BACK_COLOR);
for (k = CLR_DATA_CH1[i]; k < CLR_DATA_CH1[i + 1]; k++) {
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
}
} else {
set_addr(i + 11, CLR_DATA_CH1[i + 1]);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, WAVE_BACK_COLOR);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, WAVE_BACK_COLOR);
for (k = CLR_DATA_CH1[i + 1]; k < CLR_DATA_CH1[i]; k++) {
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
}
}
}
}
}
//显示坐标
display_area();
}
显示波形代码如下
void DISP_WAVE_CH1() {
unsigned int i, k;
//清除CH1波形
CLR_WAVE_CH1();
for (i = 0; i < 400; i++) {
//显示当前点
CLR_DATA_CH1[i] = DISP_DATA_CH1[i];
set_addr(i + 11, DISP_DATA_CH1[i]);
send_data(WAVE_COLOR_CH1);
// set_addr(i+11,DISP_DATA_CH1[i]+ 1);
set_y(DISP_DATA_CH1[i] + 1);
send_data(WAVE_COLOR_CH1);
set_addr(i + 11, DISP_DATA_CH1[i] - 1);
set_y(DISP_DATA_CH1[i] - 1);
// send_data(WAVE_COLOR_CH1);
//画连线
if (i < 399) {
if (DISP_DATA_CH1[i] < DISP_DATA_CH1[i + 1]) {
set_y(DISP_DATA_CH1[i]);
// set_addr(i+11,DISP_DATA_CH1[i]);
send_data(WAVE_COLOR_CH1);
for (k = DISP_DATA_CH1[i]; k < DISP_DATA_CH1[i + 1]; k++) {
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
// set_addr(i+11,k);
// send_data(WAVE_COLOR_CH1);
}
} else {
set_y(DISP_DATA_CH1[i + 1]);
send_data(WAVE_COLOR_CH1);
for (k = DISP_DATA_CH1[i + 1]; k < DISP_DATA_CH1[i]; k++) {
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
// set_addr(i+11,k);
// send_data(WAVE_COLOR_CH1);
}
}
}
}
}
类似的可以写出CH2的波形显示函数以及触发线等显示函数。
而其他的数据显示利用0.1版本的显示驱动即可轻松实现。
version 0.2.1 显示功能优化
在动态测试的过程中,发现这样通过调用打包中间层函数的方法,速度跟不上来,会出现频繁闪动的问题。
分析一个有以下几种可能
- 函数调用导致速度过慢
- 中间抽象层中有部分可以通过更少的时钟周期完成(利用像素的局部性)
将函数展开,以及部分不需要重新传输坐标的部分优化后解决了刷新的问题:
void CLR_WAVE_CH1() {
unsigned int i, k;
for (i = 0; i < 400; i++){
LCD_ILI9481_CMD(0x002b);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_RS_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, (i + 11) >> 8);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_WR_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(LCD_DATA_BASE, (i + 11) & 0x00ff);
//... 其余类似
}
}
Version 0.2版本演示
基于NIOS-II的示波器:PART2 界面动态显示功能的更多相关文章
- 【推荐图书】+ 基于Nios II的嵌入式SoPC系统设计与Verilog开发实例+C#入门经典等
[推荐图书]+ 基于Nios II的嵌入式SoPC系统设计与Verilog开发实例+C#入门经典等 3赞 发表于 2016/7/4 21:14:12 阅读(1921) 评论(3) 初次接触FPGA,到 ...
- 基于NIOS II的双端口CAN通信回环测试
基于NIOS II的双端口CAN通信回环测试 小梅哥编写,未经授权,严禁用于任何商业用途 说明:本稿件为初稿,如果大家在使用的过程中有什么疑问或者补充,或者需要本文中所述工程源文件,欢迎以邮件形式发送 ...
- FPGA回忆记事(一):基于Nios II的LED实验
实验一:基于Nios II的LED实验 一. 创建Quartus II工程 1.打开Quartus II环境.开始->程序->Altera->Quartus II 9.1. 2 ...
- [置顶]
基于FPGA的VGA简易显存设计&NIOS ii软核接入
项目简介 本项目基于Altera公司的Cyclone IV型芯片,利用NIOS II软核,2-port RAM与时序控制模块,实现64*48分辨率的显存(再大的显存板载资源m9k不够用) 实现效果如下 ...
- NIOS II 中直接调用Modelsim仿真
STEP1:创建一个工程,实现并编译该工程,编写TestBench文件. STEP2:设置启动Modelsim的路径 选择Nios II菜单Tools->Options..,在弹出的界面中,选择 ...
- NIOS ii 流水灯
为了做项目的前期验证工作,实验室购买了某开发板,下面是基于该板子的实现过程.作为笔记记录,供入门者参考. 1:创建一个Quartus II的工程 next选择器件,然后finish.我的器件是cycl ...
- 给NIOS II CPU增加看门狗定时器并使用
给NIOS II CPU增加看门狗定时器并使用 配置看门狗定时器: 设置计时溢出时间为1秒 计数器位宽为32位 勾选No Start/Stop control bits 勾选Fixed perio ...
- 关于Nios II的启动分析(转载)
原文地址:http://hi.baidu.com/goatdai/item/cc33671545d89243e75e06ad 常用到的存储器包括SDRMA.SRAM.FLASH.Onchip_memo ...
- 给NIOS II CPU添加一颗澎湃的心——sysclk的使用
给NIOS II CPU添加一颗澎湃的心——系统时钟的使用 本实验介绍如何在Qsys中添加一个定时器作为NIOS II的心跳定时器,并在NIOS II中软件编程使用该定时器. 将上一个实验watchd ...
随机推荐
- 最小生成树详解 prim+ kruskal代码模板
最小生成树概念: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里 ...
- bower基本使用
bower是什么? bower是基于nodejs的静态资源管理工具,由twitter公司开发.维护,使用它可以方便的安装.更新.卸载前端类库,同时解决类库之前的依赖关系. 依赖环境 bower依赖于n ...
- WCF项目的架构设计
本文将介绍以WCF开发项目为主的架构设计,主要从类库的分类和代码的结构. 下面将以一个WCF实例做具体的介绍.此项目底层是一个Windows Service,WCF服务Hosted在此Windows ...
- NYOJ 69 数的长度(数学)
数的长度 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)······*2*1.现在你的任务是计算出 ...
- HttpClient笔记与踩过的坑
本来有个指纹采集功能做了个winFrom小程序 在本地测试都还能行,后来快上线的时候发现 客户用的阿里云数据库, 不对外公布 ,然后发现本地采集的数据没办法上传到数据库怎么办呢? 然后曲线救国,用we ...
- python进阶(8):常用模块2+异常处理
前段时间讲了很多的模块应为当时面向对象没有讲有几个没有说今天补上,再说一个异常处理. 一.hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 摘要算法又称哈 ...
- 1.SpringBoo之Helloword 快速搭建一个web项目
背景: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配 ...
- React&Webpack 环境安装
react的安装依赖nodejs,nodejs安装下载可从http://nodejs.org/en/下载 1. 环境安装 1.1 创建lib目录 cd E:\ReactLib 1.2 ...
- C#多线程的用法5-线程间的协作Monitor
之前我们使用lock快捷方式,实现了多线程对同一资源的共享.在C#中lock实际上是Monitor操作的简化版本. 下面使用Monitor来完成之前的lock功能,你可以在此做一下对照: privat ...
- webpack入门篇--1.简单介绍
简单介绍: webpack是一个模块打包工具,给js准备的打包工具,可以把很多的模块打包成很少的文件 目标: 1.切分依赖数,分到不同代码块里,按需加载,懒加 载 2.任何静态资源都可以被视为一个模块 ...