CPRESS 官方给出的SDK1.1中(目前最新的SDK),提供了大量的例程供我们开发软件的时候作参考,就像STM32的开发一样提供了库一样,但是又不是库,仅仅是参考例程。

首先看一个简单一点的GPIO的例子(GpioApp)

1.先是一个错误处理的函数,我们不需要它,故这是一个死循环。

2. CyFxDebugInit 这个函数,将串口作为调试口用115200bps。

3.

void CyFxGpioIntrCb (

uint8_t gpioId /* Indicates thepin that triggered the interrupt */

)

这个函数是一个中断回调函数。必须在某个地方注册一下。

它有下列过程:

apiRetStatus=CyU3PGpioGetValue(gpioID,&gpioValue);

这个函数得到某个端口中断的值

这个gpioValue是一个BOOL值。而ID则是某一个端口的端口号。这个函数只能返回一个引脚。

下面介绍这个ID是什么指定的。

4.

CyU3PEventSet(&glFxGpioAppEvent,CY_FX_GPIOAPP_GPIO_HIGH_EVENT,CYU3P_EVENT_OR);

如果为高,则设置一个事件。是一个高事件发生。注意到事件是一个全局变量,而这个事件中有许多参数,其中比较重要的是一个回调函数。应该在某个地方将这个事件与一个回调函数联系起来。

5.voidCyFxGpioInit (void)

apiRetStatus =CyU3PGpioInit(&gpioClock,CyFxGpioIntrCB);

这个函数是设定gpio的时钟,以及中断的回调函数。这与4中部分形成对照。

然后将gpio45定义为输入且允许中断

gpioConfig.intrMode = CY_U3P_GPIO_INTR_BOTH_EDGE;

apiRetStatus = CyU3PGpioSetSimpleConfig(45, &gpioConfig);

GPIO的21脚本来作为GPIF的控制信号的。不能用CyU3PDeviceConfigureIOMatrix来将它作为GPIF IOs.

这个过载API调用必须进行必须小心当改变这个引脚的功能时。如果IO脚作为GPIF的一部分连到外部设备上。则它不能再作为GPIF IO使用。在这里CTL4是不使用的,所以用它用IO脚是安全的。

apiRetStatus = CyU3PDeviceGpioOverride(21,CyTrue);

接下来

apiRetStatus =CyU3PGpioSetSimpleConfig(21,&gpioConfig);

6. 接下来有两个线程,一个是输出线程,一个是输入线程,先看输出线程:

apiRetStatus = CyFxDebugInit();

初始化调试模式。这个在2中定义的。

CyFxGpioInit();

这个也在前面定义过。后面是一个闪灯程序。

apiRetStatus = CyU3PGpioSetValue(21,true);

将输出置为高。

延时2秒,将输出变为低。

延时2秒。

7. 下面再来看输入线程:是一个循环,等事件发生。

txApiRetStatus = CyU3PEventGet(&glFxGpioAppEvent,

(CY_FX_GPIOAPP_GPIO_HIGH_EVENT |CY_FX_GPIOAPP_GPIO_LOW_EVENT),

CYU3P_EVENT_OR_CLEAR,&eventFlag, CYU3P_WAIT_FOREVER);

这里表示永远等下去。等到后要清除事件,另返回事件的标志,这个标志我们没有用。如果等到高的标志,就打印一个引脚为高,如果为低,就打印一个引脚为低的标志。估计这个等事件标志将被block.

这样整个过程清楚了,IO脚触发引起一个中断。这个中断回调函数中将触发一个事件。在这个线程中将等事件发生,如果发生了,就打印出引脚的状态。

事件在什么地方初始化呢?还是不需要初始化?

8. 事件是要初始化的。在应用程序中初始化了,下面就看这个应用程序

先创建一个输出线程。

再创建一个输入线程

然后

retThrdCreate =CyU3EventCreate(&glFxGpioAppEvent);

9. 最后看一下main()

main()中主要是将GPIO引脚初始化一下。

io_cfg.gpioSimpleEn[0] = 0;

io_cfg.gpioSimpleEn[1] = 0x00002000; /* GPIO 45 */

io_cfg.gpioComplexEn[0] = 0;

io_cfg.gpioComplexEn[1] = 0;

45引脚为什么对应的是0x2000.?这是因为它是32位的,45引脚=32+13 ,这个第13位正好是0X2000(1<<13 就是0x2000)。

*实例总结

从main开始看起:

再看一下几个定义:输出线程,输入线程及事件在文件一开始就定义了。

CyU3PThread gpioOutputThread; /* GPIOthread structure */

CyU3PThreadgpioInputThread; /* GPIO thread structure */

CyU3PEventglFxGpioAppEvent; /* GPIO input event group. */

它主要是调用了一个串口设置函数,然后就进入到cache控制设置,再后来就是设置一个IO脚,45脚使之使能。并且选用配置模式(即LPP模式)。允许了UART,不允许IIC,IIS,SPI,另外isDQ32bit也不允许。这个表示它不支持GPIF的32位模式。

然后我们再看应用程序启动,这是由系统自动调用的。我们可能修改它的内容,但是它是必须的。

这个函数中,它创建了两个线程。一个是输入线程,一个是输出线程。

另外,容易遗忘的一件事是它创建了一个事件。事件的创建只要这样就可以了:

retThrdCreate = Cy3U3PEventCreate(&glFxGpioAppEvent);

再往上,就是输入线程了。这个线程看输入引脚的变化,而这个变化由中断回调函数引起,中断回调函数中,它会产生一个事件,而我们的线程就监视这个事件。如果有事件高发生,就串口打印一个引脚高,如果低,就打印一个引脚低。看它是如何实现的:

txApiRetStatus =CyU3PEventGet(&glFxGpioAppEvent,

(CY_FX_GPIOAPPP_GPIO_HIGH_EVENT|CY_FX_GPIOAPP_GPIO_LOW_EVENT),

CYU3P_EVENT_OR_CLEAR,&eventFlag,CYU3P_WAIT_FOREVER);

这是个等事件的函数,这个函数无法找到它的定义,它是一个API函数。我们找API,发现它的参数含义。

这里有一个CYU3P_EVENT_OR_CLEAR表示只要上面有一个位被设置就返回且清除标志。----OR。

而真正的事件就放在标志中返回了。

既然有读事件,就必有设置事件,事件的设置应该在中断回调中实现。而中断回调的注册,应该在初始化时实现。下面应该可以很快看到这点。---事实上,在下面的输出线程中就实现了注册。

输出线程实现,输出线程比较有意思的是其DebugInit()居然是在它中间实现的,其实这个也可以在main中。

而接下来,它又调用了初始化GpioInit()这个函数。在这个函数中,先初始化GPIO,这个GPIO居然还要将时钟也设置一下,有点不合常理。在这个初始化中,它还指明了GPIO中断回调函数的注册。尽管这个中断函数应该是在输入线程中注册似更合理一些。接下来,45脚要用之为输入,所以要将配置设一下:

gpioConfig.outValue = CyTrue; //输出为高 因为是输入,要将它设为高

gpioConfig.inputEn = CyTrue; //输入使能

gpioConfig.driveLowEn = CyFalse; //不要驱动低也不要驱动高

gpioConfig.driveHighEn = CyFalse;

gpioConfig.intrMode = CY_U3P_GPIO_INTR_BOTH_EDGE; //允许中断

apiRetStatus = CyU3PGpioSetSimpleConfig(45, &gpioConfig);

如此这般配置了45脚。

接下来,要配置21脚,因为21脚比较特殊本来是用于GPIF的CTRL4的。现在要使用它就要重载一下:

这样的IO脚是不可以象在主程序中哪样,将它直接设为输出的,而是要先重载。

同样,看输出脚是如何定义的

gpioConfig.outValue = CyFalse; //低电平

gpioConfig.driveLowEn = CyTrue; //允许低输出

gpioConfig.driveHighEn = CyTrue; //允许高输出

gpioConfig.inputEn = CyFalse; //方向设为输出

gpioConfig.intrMode = CY_U3P_GPIO_NO_INTR; //不用中断

再看一下回调函数,如何实现它的:

当引脚有跳变时,这个函数被调用。首先,它得到引脚的值。这个回调函数是带参数的。当它发生时,会带过来一个参数。表明是哪一个引脚触发了这个事件。这在库函数中可能已经处理了,提供给用户程序就不用麻烦再去看原因了。我想可能有一个机制,即有一个中断状态寄存器,表示是哪一个引脚变化了。

在这里调用了一个函数:

CyU3PGpioGetValue(gpioId,&gpioValue);

注意到这个值是一个BOOL型的。

然后根据情况来设置事件:

CyU3PEventSet(&glFxGpioAppEvent,CY_FX_GPIOAPP_GPIO_HIGH_EVENT,CYU3P_EVENT_OR);

我们看,其中有要设置的事件指针,有什么事件,以什么方式设置,它是以OR的方式设置的。这个OR表示的是将这个第2个参数与当前的事件标志进行或。显然,如果相或的话,则事件标志将被置1,而如果与则完全不同,它没效果。(在得到事件中,有一个AND表示全部标志都符合才生成事件,所以也是用OR的,不然,不可能全部符合的,永远不会发生事件了,因为不可能既变高又变低的)。

至此整个程序解读完了。在这个例子中,没用到USB有关的部分。就是当一个MCU用的GPIO,因为这个芯片的CPU是ARM926EJ的内核,运行频率可以达到200MHz,和之前的FX2芯片的51内核完全不是一个级别,所以这个做主控芯片是完全可以的。

CYPEESS USB3.0程序解读之---GPIO的更多相关文章

  1. CYPEESS USB3.0程序解读之---同步FIFO(slaveFifoSync)

    上一篇文章解读了CYPRESS FX3的GPIO的操作过程,下面解读同步FIFO的一个例子(slaveFifoSync). *生产者,消费者. 1.首先看DMA的回调函数(cyu3dma.h): ty ...

  2. CYPEESS USB3.0程序解读之---SPI读写

    前面已经解读了GPIO以及同步FIFO操作,下面我们看一个SPI读写的例子,它是主程序命令从SPI中读写一些数据. SPI传输子程序看一下: 页地址,字节计数,缓冲区,读写标志 因为只能一页一页的读或 ...

  3. AC6102开发板USB3.0测试和使用说明

    AC6102开发板USB3.0测试和使用说明 概述 AC6102上集成了一颗Cypress 推出的高性能USB3.0传输芯片CYUSB3014,Cypress称之为EZ-USBFX3.该芯片性能强劲, ...

  4. 给windows 7安装文件添加USB3.0驱动

    给Air安装win7进入语言与区域选择之后,发现键盘触摸板都失灵.   原因:新款的 Macbook Air 2013 因为使用了 USB3.0 端口键盘和触摸板设备,所以在安装 Windows 7 ...

  5. 【原创】基于部署映像服务和管理(DISM)修改映象解决WIN7 USB3.0安装时报错

    本文作者为博客园阿梓喵http://www.cnblogs.com/c4isr/,转载请注明作者. 本文源地址:http://www.cnblogs.com/c4isr/p/3532362.html ...

  6. 如何在Win7安装U盘中加入USB3.0驱动的支持

    U盘安装系统出现鼠标键盘不能使用,在intel六代处理器平台,安装过程中会出现安装原生镜像不能识别或者鼠标键盘不能使用等情况,可以参考以下方法进行. 风险提示:重装或升级系统会导致系统盘数据丢失,建议 ...

  7. 如何向 Windows 7 镜像中添加 USB3.0 驱动

    如何向 Windows 7 镜像中添加 USB3.0 驱动 1. Microsoft 在 Windows 7 的安装光盘并没有集成各个厂商的 USB3.0 驱动,可 以使用下面方法添加 USB3.0 ...

  8. U盘安装Win7系统,遇到硬盘鼠标键盘失灵等情况,如何安装U盘中加入USB3.0驱动的支持

    U盘安装系统出现鼠标键盘不能使用,在intel六代处理器平台,安装过程中会出现安装原生镜像不能识别或者鼠标键盘不能使用等情况,可以参考以下方法进行. 风险提示:重装或升级系统会导致系统盘数据丢失,建议 ...

  9. USB3.0测试和使用说明

    概述 AC6102上集成了一颗Cypress 推出的高性能USB3.0传输芯片CYUSB3014,Cypress称之为EZ-USBFX3.该芯片性能强劲,功能强大,接口简单,非常适合用于各种需要高速数 ...

随机推荐

  1. 最新的.NET 热重载介绍

    今天,我们很高兴的向您介绍 Visual Studio 2019 版本 16.11(预览版 1)和 .NET 6 中的 dotnet watch 命令行工具(预览版 4)中的 .NET 热重载体验的可 ...

  2. Nginx:Nginx动静分离

    1.什么是动静分离 将动态请求和静态请求区分访问 2.为什么要做动静分离 tomcat本身处理静态效率不高,还会带来资源开销.所以使用动静分离,将静态由Nginx处理, 动态由PHP处理或Tomcat ...

  3. ExtJs4学习(五)最基本的Ext类

    Ext类是ExtJs中最常见.最基础的一个类,它是一个全局对象,封装了所有类.单例和 Sencha 库所提供的实用方法. 大多数用户界面组件在一个较低的层次嵌套在命名空间中, 但是提供的许多常见的实用 ...

  4. SpringMVC(10)实现注解式权限验证

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...

  5. WPF教程八:如何更好的使用Application程序集资源

    这一篇单独拿出来分析这个程序集资源,为的就是不想让大家把程序集资源和exe程序强关联,因为程序集资源实际上是二进制资源,后续编译过程中会被嵌入到程序集中,而为了更方便的使用资源,我们要好好梳理一下程序 ...

  6. python 字符串 增、删、改、查基本操作

    private static String TAG = "MainActivity"; private String str = " a,bB,1cCcc,2dDd d2 ...

  7. ESP32-OTA升级

    基于ESP-IDF4.1 1 #include <string.h> 2 #include "freertos/FreeRTOS.h" 3 #include " ...

  8. Java | 标识符 & 关键字

    标识符是什么? 标识符 标识符是指在程序中,我们自己定义的内容.比如类的名字.方法的名字和变量的名字等等,都是标识符.在我们写的第一个程序当中,我们给类起名叫做Hello 也叫做标识符. 命名规则 标 ...

  9. 从sql2008导入表结构及数据到mysql

    打开navicat for mysql连接mysqlcreate database lianxi刷新,双击lianxi,双击"表"点击右边的"导入向导"选择&q ...

  10. File类与常用IO流第一章File类

    第一章:File类 一.1个重点单词: file:文件:directory:文件夹/目录:path:路径(绝对路径:absolutePath) 二.4个静态成员变量: 1.static String ...