硬件_IMX6ULL的LCD控制器
硬件_IMX6ULL的LCD控制器
文章目录
- 硬件_IMX6ULL的LCD控制器
 - 一、 LCD控制器模块介绍
 - 1.1 硬件框图
 - 1.2 数据传输与处理
 - 1.3 时序控制
 
- 二、 LCD控制器寄存器简介
 - 2.1 LCDIF_CTRL寄存器
 - 2.2 LCDIF_CTRL1寄存器
 - 2.3 LCDIF_TRANSFER_COUNT寄存器
 - 2.4 LCDIF_VDCTRL0寄存器
 - 2.5 LCDIF_VDCTRL1寄存器
 - 2.6 LCDIF_VDCTRL2寄存器
 - 2.7 LCDIF_VDCTRL3寄存器
 - 2.8 LCDIF_VDCTRL4寄存器
 - 2.9 LCDIF_CUR_BUF寄存器
 - 2.10 LCDIF_NEXT_BUF寄存器
 
- 致谢
 
一、 LCD控制器模块介绍
1.1 硬件框图
IMX6ULL的LCD控制器名称为eLCDIF(Enhanced LCD Interface,增强型LCD接口),主要特性如下:
- 支持MPU模式:有些显示屏自带显存,只需要把命令、数据发送给显示屏即可;就是前面讲的8080接口
 - VSYNC模式:跟MPU模式类似,多了VSYNC信号。针对高速数据传输(行场信号)
 - 支持DOTCLK模式:RGB接口,就是前面讲的TFT-RGB接口
 - 支持ITU-R BT.656接口,可以把4:2:2 YcbCr格式的数据转换为模拟电视信号
 - 8/16/18/24/32 bit 的bpp数据都支持,取决于IO的复用设置及寄存器配置
 - MPU模式,VSYNC模式,DOTCLK模式,都可以配置时序参数。
上图是IMX6ULL的LCD控制器框图。
我们在内存中划出一块内存,称之为显存,软件把数据写入显存。
设置好LCD控制器之后,它会通过AXI总线协议从显存把RGB数据读入FIFO,再到达LCD接口(LCD Interface)。
LCD控制器有两个时钟域:外设总线时钟域,LCD像素时钟域。前者是用来让LCD控制器正常工作,后者是用来控制电子枪移动。
上图的Read_Data操作,在MPU模式下才用到;我们采用的是DCLK模式,因此不予考虑。 
更详细的内容可以查看IMX6ull芯片手册《Chapter 34 Enhanced LCD Interface (eLCDIF)》。
1.2 数据传输与处理
- 框图:

 
1.3 时序控制
看寄存器说明。
二、 LCD控制器寄存器简介
查看任何芯片的LCD控制器寄存器时,记住几个要点:
① 怎么把LCD的信息告诉LCD控制器:即分辨率、行列时序、像素时钟等;
 ② 怎么把显存地址、像素格式告诉LCD控制器。

 上图是我们将要使用到的寄存器,下面逐个讲解这些寄存器,在后续的LCD控制编程实验会用到。
2.1 LCDIF_CTRL寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31] | SFTRST | R/W | 软件复位,正常工作时应设为0;如果设为1,它会复位整个LCD控制器 | 
| [30] | CLKGATE | R/W | 时钟开关, 0:正常工作时要设置为0; 1:关闭LCD控制器时钟 | 
| [29] | YCBCR422_INPUT | R/W | 使用RGB接口时,设置为0;其他接口我们暂时不关心 | 
| [28] | READ_WRITEB | R/W | 使用RGB接口时,设置为0;其他接口我们暂时不关心 | 
| [27] | WAIT_FOR_VSYNC_EDGE | R/W | 在VSYNC模式时,设置为1;我们不关心 | 
| [26] | DATA_SHIFT_DIR | R/W | 在DVI模式下才需要设置,我们不关心 | 
| [25:21] | SHIFT_NUM_BITS | R/W | 在DVI模式下才需要设置,我们不关心 | 
| [20] | DVI_MODE | R/W | 设置为1时,使用DVI模式,就是ITU-R BT.656数字接口 | 
| [19] | BYPASS_COUNT | R/W | DOTCLK和DVI模式下需要设置为1;MPU、VSYNC模式时设为0 | 
| [18] | VSYNC_MODE | R/W | 使用VSYNC模式时,设置为1 | 
| [17] | DOTCLK_MODE | R/W | 使用DOTCLK模式时,设置为1;本实验用的就是这个模式 | 
| [16] | DATA_SELECT | R/W | MPU模式下才用到,我们不关心 | 
| [15:14] | INPUT_DATA_SWIZZLE | R/W | 显存中像素颜色的数据转给LCD控制器时,字节位置是否交换:  0x0:NO_SWAP,不交换; 0x0:LITTLE_ENDIAN,小字节序,跟NO_SWAP一样; 0x1:BIG_ENDIAN_SWAP,字节0、3交换;字节1、2交换; 0x1:SWAP_ALL_BYTES,字节0、3交换;字节1、2交换; 0x2:HWD_SWAP,半字交换,即0x12345678转为0x56781234 0x3:HWD_BYTE_SWAP,在每个半字内部放换字节, 即0x12345678转换为0x34127856  | 
| [13:12] | CSC_DATA_SWIZZLE | R/W | 显存中的数据被传入LCD控制器内部并被转换为24BPP后,在它被转给LCD接口之前,字节位置是否交换: 0x0:NO_SWAP,不交换; 0x0:LITTLE_ENDIAN,小字节序,跟NO_SWAP一样; 0x1:BIG_ENDIAN_SWAP,字节0、3交换;字节1、2交换; 0x1:SWAP_ALL_BYTES,字节0、3交换;字节1、2交换; 0x2:HWD_SWAP,半字交换,即0x12345678转为0x56781234 0x3:HWD_BYTE_SWAP,在每个半字内部放换字节, 即0x12345678转换为0x34127856 | 
| [11:10] | LCD_DATABUS_WIDTH | R/W | LCD数据总线宽度,就是对外输出的LCD数据的位宽, 0x0:16位; 0x1:8位; 0x2:18位; 0x3:24位 | 
| [9:8] | WORD_LENGTH | R/W | 输入的数据格式,即显存中每个像素占多少位, 0x0:16位; 0x1:8位; 0x2:18位; 0x3:24位 | 
| [7] | RGB_TO_YCBCR422_CSC | R/W | 设置为1时,使能颜色空间转换:RGB转为YCbCr | 
| [6] | ENABLE_PXP_HANDSHAKE | R/W | 当LCDIF_MASTER设置为1时,再设置这位, 则LCD控制器跟PXP之间的握手机制被关闭(我们不关心) | 
| [5] | MASTER | R/W | 设置为1时,LCD控制器成为bus master | 
| [4] | RSRVD0 | R/W | 保留 | 
| [3] | DATA_FORMAT_16_BIT | R/W | WORD_LENGTH为0时,表示一个像素用16位,此位作用如下: 0:数据格式为ARGB555; 1:数据格式为RGB565 | 
| [2] | DATA_FORMAT_18_BIT | R/W | WORD_LENGTH为2时,表示一个像素用18位,RGB数据还是保存在32位数据里,此位作用如下: 0:低18位用来表示RGB666,高14位无效 1:高18位用来表示RGB666,低14位无效 | 
| [1] | DATA_FORMAT_24_BIT | R/W | WORD_LENGTH为3时,表示一个像素用24位,此位作用如下: 0:所有的24位数据都有效,格式为RGB888 1:转给LCD控制器的数据是24位的,但只用到其中的18位, 每个字节用来表示一个原色,每字节中高2位无效 | 
| [0] | RUN | R/W | 使能LCD控制器,开始传输数据 | 
2.2 LCDIF_CTRL1寄存器

 本实验中使用TFT LCD,LCD控制器使用DOTCLK模式。本寄存器中其他用不到的位,就不介绍了。
| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [19:16] | BYTE_PACKING_FORMAT | R/W | 用来表示一个32位的word中,哪些字节是有效的,即哪些字节是用来表示颜色的。 bit16、17、18、19分别对应byte0、1、2、3;某位为1,就表示对应的字节有效。 默认值是0xf,表示32位的word中,所有字节都有效。 对于8bpp,可以忽略本设置,所有的字节都是有效的; 对于16bpp,bit[1:0]、bit[3:2]分别对应一个字节,组合中的2位都为1时,对应的字节才有效; 对于24bpp,0x7表示32位数据中只用到3个字节,这称为“24 bit unpacked format”,即ARGB,其中的A字节被丢弃 | 
| [0] | RESET | R/W | 用来复位了接的LCD, 0:LCD_RESET引脚输出低电平; 1:LCD_RESET引脚输出高电平 | 
2.3 LCDIF_TRANSFER_COUNT寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31:16] | V_COUNT | R/W | 一帧中,有多少行有效数据 | 
| [15:0] | H_COUNT | R/W | 一行中,有多少个像素 | 
2.4 LCDIF_VDCTRL0寄存器

 本寄存器用来设置Vsync信号相关的时序,及极性。
| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [29] | VSYNC_OEB | R/W | 用来控制VSYNC信号,对于DOTCLK模式,设为0, 0:VSYNC是输出引脚,用LCD控制器产生; 1:VSYNC是输入引脚 | 
| [28] | ENABLE_PRESENT | R/W | 在DOTCLK模式下,硬件是否会产生数据使能信号ENALBE: 0:不产生; 1:产生 | 
| [27] | VSYNC_POL | R/W | 用来决定VSYNC脉冲的极性, 0:低脉冲; 1:高脉冲 | 
| [26] | HSYNC_POL | R/W | 用来决定HSYNC脉冲的极性, 0:低脉冲; 1:高脉冲 | 
| [25] | DOTCLK_POL | R/W | 用来决定DOTCLK的极性, 0:LCD控制器在DOTCLK下降沿发送数据,LCD在上升沿捕获数据; 1:反过来 | 
| [24] | ENABLE_POL | R/W | 用来决定ENABLE信号的极性, 0:数据有效期间,ENABLE信号为低; 1:反过来 | 
| [21] | VSYNC_PERIOD_UNIT | R/W | 用来决定VSYNC_PERIOD的单位, 0:单位是像素时钟(pix_clk),这在VSYNC模式下使用; 1:单位是“整行”,这在DOTCLK模式下使用 | 
| [20] | VSYNC_PULSE_WIDTH_UNIT | R/W | 用来决定VSYNC_PULSE_WIDTH的单位, 0:单位是像素时钟(pix_clk); 1:单位是“整行” | 
| [19] | HALF_LINE | R/W | VSYNC周期是否周加上半行的时间, 0:VSYNC周期=VSYNC_PERIOD; 1:VSYNC周期=VSYNC_PERIOD+HORIZONTAL_PERIOD/2 | 
| [18] | HALF_LINE_MODE | R/W | 0:第1帧将在一行的中间结束,第2帧在一行的中间开始; 1:所有帧结束前都加上半行时间,这样所有帧都会起始于“行的开头” | 
| [17:0] | VSYNC_PULSE_WIDTH | R/W | VSYNC脉冲的宽度 | 
2.5 LCDIF_VDCTRL1寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [29] | VSYNC_PERIOD | R/W | 两个垂直同步信号之间的间隔,即垂直方向同步信号的总周期; 单位由VSYNC_PERIOD_UNIT决定 | 
2.6 LCDIF_VDCTRL2寄存器

 HSYNC_PULSE_WIDTH:水平同步信号脉冲宽度;
 HSYNC_PERIOD:两个水平同步信号之间的总数,即水平方向同步信号的总周期
| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31:18] | HSYNC_PULSE_WIDTH | R/W | HSYNC脉冲的宽度(单位:pix_clk) | 
| [17:0] | HSYNC_PERIOD | R/W | 整行的宽度,即两个HYSNC信号之间的宽度(单位:pix_clk) | 
2.7 LCDIF_VDCTRL3寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [29] | MUX_SYNC_SIGNALS | R/W | 用不着 | 
| [28] | VSYNC_ONLY | R/W | 0:DOTCLK模式时必须设置为0; 1:VSYNC模式时必须设置为1 | 
| [27:16] | HORIZONTAL_WAIT_CNT | R/W | 水平方向上的等待像素个数,等于thp+thb | 
| [15:0] | VERTICAL_WAIT_CNT | R/W | 垂直方向上的等待行数,等于tvp+tvb | 
2.8 LCDIF_VDCTRL4寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31:29] | DOTCLK_DLY_SEL | R/W | 在LCD控制器内部的DOTCLK输出到LCD_DOTCK引脚时,延时多久: 0:2ns; 1:4ns; 2:6ns; 3:8ns; 其他值保留 | 
| [18] | SYNC_SIGNALS_ON | R/W | DOTCLK模式下必须设为1 | 
| [17:0] | DOTCLK_H_VALID_DATA_CNT | R/W | 水平方向上的有效像素个数(pix_clk),即分辨率的y | 
2.9 LCDIF_CUR_BUF寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31:0] | ADDR | R/W | LCD控制器正在传输的当前帧在显存中的地址 | 
2.10 LCDIF_NEXT_BUF寄存器

| 位域 | 名 | 读写 | 描述 | 
|---|---|---|---|
| [31:0] | ADDR | R/W | 下一帧在显存中的地址 | 
LCD控制器传输完当前帧后,会把LCDIF_NEXT_BUF寄存器的值复制到LCDIF_CUR_BUF寄存器。
致谢
以上笔记源自
韦东山老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!
在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!
相关文章:
硬件_IMX6ULL的LCD控制器
硬件_IMX6ULL的LCD控制器 文章目录硬件_IMX6ULL的LCD控制器一、 LCD控制器模块介绍1.1 硬件框图1.2 数据传输与处理1.3 时序控制二、 LCD控制器寄存器简介2.1 LCDIF_CTRL寄存器2.2 LCDIF_CTRL1寄存器2.3 LCDIF_TRANSFER_COUNT寄存器2.4 LCDIF_VDCTRL0寄存器2.5 LCDIF_VDCTRL1寄…...
ICLR 2022—你不应该错过的 10 篇论文(下)
CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 ICLR 2023已经放榜,但是今天我们先来回顾一下去年的ICLR 2022! ICLR 2022将于2022年 4 月 25 日星期一至 4 月 29 日星期五在线举行(连续第三年!&#x…...
国内外优秀程序员的私域博客大全
文章目录 国内外优秀程序员的私域博客大全**国内的优秀程序员****国外的优秀程序员**结语国内外优秀程序员的私域博客大全 国内的优秀程序员 1、风雪之隅-惠新宸 擅长领域:PHP、PECL等 Laruance惠新宸——国内最有影响力的PHP技术专家,PHP开发组核心成员, Zend顾问, PHP7及…...
【C++ Primer Plus】第六章:分支语句和逻辑运算符
文章目录第六章 分支语句和逻辑运算符6.1 字符函数库cctype6.2 ?:运算符6.3 读取数字的输入6.4 cin的处理过程char类型intdoublechar数组使用char数组来存储输入6.5 写入到文本文件中6.6 读取文本文件6.7 总结第六章 分支语句和逻辑运算符 6.1 字符函数库cctype C从C语言继承…...
堡垒机的主要功能是什么?为什么需要堡垒机?
堡垒机是一种用于管理和控制服务器的工具,其主要功能是为管理人员提供安全、便捷的远程管理和操作方式。为什么需要堡垒机呢?下面我们将详细阐述堡垒机的主要功能和必要性。 一、堡垒机的主要功能: ①、用户认证和授权管理:堡垒机…...
记录spring中Transactional事务注解失效的六个场景
记录spring中Transactional事务注解失效的六个场景 方法内的自调用 原因:通过this内部调用其他带有Transactional注解的方法,是通过this进行调用,并没有通过cglib代理对象进行调用,导致方法未被增强导致无法检测内部事务 解决方…...
【23种设计模式】行为型模式详细介绍(下)
前言 本文为 【23种设计模式】行为型模式 相关内容介绍,下边将对访问者模式,模板模式,策略模式,状态模式,观察者模式,备忘录模式,中介者模式,迭代器模式,解释器模式&…...
dbeaver工具连接达梦数据库
、一 概述 DBeaver 是一个基于 Java 开发,免费开源的通用数据库管理和开发,DBeaver 采用 Eclipse 框架开发,支持插件扩展,并且提供了许多数据库管理工具:ER 图、数据导入/导出、数据库比较、模拟数据生成等࿰…...
比Teambition、Worktile 更适合研发团队的几大工具盘点
Worktile 和 Teambitiom 哪个更好?两个产品各有特点。1.Teambition 优势:操作简单、个人版永不收费、更适合小型团队;2.Teambition 劣势:无法满足中大型团队复杂的项目管理、自定义能力弱、无法与钉钉以外的工具打通等;…...
matlab图像处理常用功能以及函数
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、matlab灰度处理相关二、形态学的一些函数1.腐蚀2.膨胀3.开运算4.闭运算三、其他一些可能会用到的方法1.使用hough进行直线检测2.圆检测3.闭合形状检测4.寻找…...
eBPF 之 ProgramType、AttachType和InputContext
1. ProgramType 定义定义在 include/uapi/linux/bpf.h 文件中,不同 Linux 版本会有变化,以下是 Linux 5.19 版本定义:enum bpf_prog_type {BPF_PROG_TYPE_UNSPEC,BPF_PROG_TYPE_SOCKET_FILTER,BPF_PROG_TYPE_KPROBE,BPF_PROG_TYPE_SCHED_CLS,…...
C++运行时类型识别RTTI
C技能 runtime type identification(RTTI) 运行时类型识别在使用多态的时候经常用到。本文将会介绍RTTI的几个特征。1. 运行时类型转换下面的程序模仿了dynamic_cast<type_id>()类型转化符号,根据每个类的id来判断当前的类型,如果id不匹配…...
idea多时编辑多行-winmac都支持
1背景介绍 idea编辑器非常强大,其中一个功能非常优秀,很多程序员也非常喜欢用。这个功能能够大大大提高工作效率-------------多行代码同时编辑 2win 2.1方法1 按住alt鼠标左键上/下拖动即可 这样选中多行后,可以直接多行编辑。 优点&a…...
BI是报表?BI是可视化?BI到底是什么?
很多企业认为只要买一个前端商业智能BI分析工具就可以解决企业级的商业智能BI所有问题,这个看法实际上也不可行的。可能在最开始分析场景相对简单,对接数据的复杂度不是很高的情况下这类商业智能BI分析工具没有问题。但是在企业的商业智能BI项目建设有一…...
Python基础-数据类型之元组
一、元组的定义 nums (1, 2, 3, 4, 5) 元组是序列的其中一种,每个元素都以逗号分隔,用()包围。 当元组中只有一个元素时,需要在元素后面加逗号分隔,nums (1,),否则括号会被当成运算符 nums (1) print(type(nums…...
大数据面试小抄
项目地址:https://github.com/GTyingzi/BigDATA 该项目是自己在学习大数据过程中整理、总结下来的一份面试小抄。涵盖Hadoop、Spark、Flink、Hive、HBae、Kafka、ES、Zookeeper等。 开源给大家,若感觉不错欢迎star~ 摘取Flink部分如下文章目录FlinkFli…...
Vue:(三十一)Vue封装的过度与动画
上一篇订阅与发布不够过瘾,接着再来一篇,come on!!!作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名写法:过度:元素进入的样式:v-enter&am…...
文本处理:字符串替换
方法1:str.replace str.replace(old, new[, count]) Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. 该方法逻辑大致如下所示&am…...
python 调用 dll 出现精度问题
问题:python 在调用dll 的时候出现了精度问题 总结:使用decimal库进行转换就可以正常传递。 ‘ 心急的朋友可以略过下文了。 心急的朋友可以略过下文了。 心急的朋友可以略过下文了。 心急的朋友可以略过下文了。 ’ 遇到的问题具体情况 dll 生成函数…...
STL讲解——模拟实现string
STL讲解——模拟实现string 经典的string类问题 大厂在面试中,面试官总喜欢让学生自己来模拟实现string类,最主要是实现string类的增、删、查、改、构造、拷贝构造、赋值运算符重载以及析构函数。大家看下自己可不可以写一个string类? cla…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...
Axure零基础跟我学:展开与收回
亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...
