• LPC4370使用学习:GPIO的引脚功能使用,和12864OLED模拟I2C驱动


    一:  手中有块LPC4370的开发板,因为便宜,所以引脚引出的不多,而且只有基本的底板资源驱动代码和例程。 

      看着手册和例程看了老半天,写程序写了半天,结果GPIO老是驱动不起来,因为引脚配置寄存器中有个MODE(选择引脚功能)的选项中8个function功能不知道到底啥意思,其中一个手册 LPC4350_30_20_10_User_manuall_CN( 下载地址: http://www.waveshare.net/w/upload/d/d9/LPC4350_30_20_10_User_manuall_CN.pdf    原谅我,只是单纯的找资源,我买的开发板不是这家的...... )中在 15.4.1 标准电平驱动引脚的引脚配置寄存器  的 表 123. 标准电平驱动引脚的引脚配置寄存器  中可以看到只标注了每个引脚有八个功能,看了例程也没有介绍到底是怎么用的。经过一番探究,终于知道了这八个引脚功能怎么用的。

      这八个引脚功能的使用要配合另一个手册 LPC4350_30_20_10_Datasheet_CN(下载地址:http://www.waveshare.net/w/upload/4/48/LPC4350_30_20_10_Datasheet_CN.pdf)中的6.2 引脚描述  中的 表 3. 引脚描述 来对应查找。

     首先在左侧的 多路复用数字引脚 找到对应使用的引脚,再在右侧找到要使用的功能,从上到下按照从0到7的顺序找自己要用到的功能,用到第几个就是FUNC几。每个引脚的功能顺序居然没有规则(还是虽然有但是我没找到?),要一个一个查找,好麻烦。

      注意:其中GPIO功能后面写着对应的GPIO引脚的数字命名(术语叫啥??),这个下面会用到。有的原理图上只有能标到字母的引脚号,而还找到了一张LPC43xx原理图上详细的引脚功能都写上了(这个自己找吧,一般的都会给,只要有一个引脚名就可以到第二个手册上查到)

      不知走过路过的有没有什么更好的方法么?只能按表查找?

    二:下面再来说说基本的库函数:(感觉寄存器方法不是我能驾驭的了的......怎么简单我喜欢怎么来)

      1)首先,为了使用方便,可以先做如下定义:

    /* 假设使用P9_4 的GPIO功能*/

    #define Pin_Name_GPIO_PORT      9
    #define Pin_Name_GPIO_Pin       4
    #define Name_GPIO_Function        FUNC4
    #define Name_GPIO_PORT         5
    #define Name_GPIO_BIT          17

    前两个好理解,用哪个脚就写啥,如用PD_4就分别写成0x0d 和 4,其他同理。

    function项上面说了,查表。

    最后两个呢,也是看FUNCX那个,就是上面说的那个引脚描述表,在GPIO功能后面紧接着标了GPIOx[y],则PORT 项定义的就是x,BIT项定义的就是y.到时候一看图就对应起来了。没截图,到时候一看就懂。

     2)初始化函数:

    void scu_pinmux(uint8_t port, uint8_t pin, uint8_t mode, uint8_t func)
    {
      uint32_t * scu_base=(uint32_t*)(LPC_SCU_BASE);
      scu_base[(PORT_OFFSET*port+PIN_OFFSET*pin)/4]=mode+func;
    }

    第一个参数就是上面的第一个  Pin_Name_GPIO_PORT ,第二个参数就是第二个Pin_Name_GPIO_Pin,第三个参数是引脚的一些模式设置,如速度,是否开启上拉等,具体的去scu_18xx_43xx.h查看。第四个参数就是FUNCx,x为你想用的那个功能。

    3)引脚方向设置:输入还是输出  0:输入;1:输出

    参数分别为第四个Name_GPIO_PORT和第五个Name_GPIO_BIT,其中bitValue需要左移一位,详情见例子(原因?我也不知道......以后多用用也许我就哪天顿悟了)

    void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
    {
      if (dir)
        {
          LPC_GPIO_PORT->DIR[portNum] |= bitValue;
        } else
        {
          LPC_GPIO_PORT->DIR[portNum] &= ~bitValue;
        }
    }

    使用例子:

        scu_pinmux(Pin_Name_GPIO_PORT  ,Pin_Name_GPIO_Pin  , (MD_PUP | MD_EZI | MD_ZI), Name_GPIO_Function );

        GPIO_SetDir(Name_GPIO_PORT,(1<<Name_GPIO_BIT), 1);

        两个语句完成对某个引脚的初始化。可能需要引脚时钟的初始化,这个可能在系统初始化中了,或者需要自己写?我再试试。

     4)某引脚输出高电平:

    void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
    {
    LPC_GPIO_PORT->SET[portNum] = bitValue;
    }

    5)某引脚输出低电平:

    void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)
    {
    LPC_GPIO_PORT->CLR[portNum] = bitValue;
    }

    两个参数都要用第四和第五个,即分别对应Name_GPIO_PORT 和Name_GPIO_BIT

    使用时可以修改定义,也可直接输入Pin值。

    而引脚的输入设置,就是把上面GPIO_SetDir 的最后一个方向参数设置为0即为输入。

    引脚的输入状态读取,函数都在 gpio_18xx_43xx.h头文件里,gpio_18xx_43xx.c里面没有。具体可自己翻阅。

    三:GPIO模拟IIC驱动12864OLED的模拟IIC代码:

      LPC4370貌似有两个很强大的硬件I2C口,包括I2C0,和I2C1,但是,目前我还没看懂,不会用。会用了在抽空贴一下用法。

    //模拟IIC使用引脚:

    //  SCL   P1_3   GPIO 0[10]   FUNC0
    //  SDA  PD_4   GPIO 6[18]   FUNC4
    //详情见LPC4357MCU的详细原理图
    //FUNCx的确定要到Datesheet文档按照引脚详细查询

    #define SCL_Pin_name_PORT 1
    #define SCL_Pin_name_BIT 3
    #define SCL_pin_Function FUNC0
    #define SCL_GPIO_PORT 0
    #define SCL_GPIO_BIT 10

    #define SDA_Pin_name_PORT 0xd
    #define SDA_Pin_name_BIT 4
    #define SDA_pin_Function FUNC4
    #define SDA_GPIO_PORT 6
    #define SDA_GPIO_BIT 18

    /***************************************/
    //IIC初始化代码

    //作者:执念执战
    /***************************************/

    void IIC_init(void )

    {

    scu_pinmux(SCL_Pin_name_PORT ,SCL_Pin_name_BIT , MD_PUP|MD_ZI , SCL_pin_Function);
    GPIO_SetDir(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT), 1);

    scu_pinmux(SDA_Pin_name_PORT ,SDA_Pin_name_BIT , MD_PUP|MD_ZI, SDA_pin_Function);
    GPIO_SetDir(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT), 1);

    }


    ///***************************************/

    //IICstart函数

    //作者:执念执战

    //备注:可能由于LPC4370速度太快,如果不加延时屏幕根本不亮。加了延时就好了。延时时间并不精确,随便写的。

    ///***************************************/

    void IIC_start()
    {

    GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    delay(10);

    }
    /***************************************/

    //IIC_stop函数

    // 作者:执念执战

    //备注:可能由于LPC4370速度太快,如果不加延时屏幕根本不亮。加了延时就好了。延时时间并不精确,随便写的。

    /***************************************/

    void IIC_stop()
    {

    GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    delay(10);


    }

    /***************************************/
    // Write_IIC_Byte函数

    //作者:执念执战
    //备注:可能由于LPC4370速度太快,如果不加延时屏幕根本不亮。加了延时就好了。延时时间并不精确,随便写的。
    /***************************************/

    void Write_IIC_Byte(uint8_t IIC_Byte)//I2C_WriteByte(uint8_t addr,uint8_t data)
    {
    uint8_t i;

    for(i=0;i<8;i++)
    {
    if(IIC_Byte&0x80)
      GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    else
      GPIO_ClearValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    delay(2);
    GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    delay(2);
    GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));

    IIC_Byte<<=1;
    }
    delay(5);
    GPIO_SetValue(SDA_GPIO_PORT,(1<<SDA_GPIO_BIT));
    delay(2);
    GPIO_SetValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    delay(2);
    GPIO_ClearValue(SCL_GPIO_PORT,(1<<SCL_GPIO_BIT));
    delay(2);


    }

    /***************************************/
    //I2C_WriteByte函数

    //作者:执念执战

    /***************************************/
    void I2C_WriteByte(uint8_t addr,uint8_t data)
    {
    IIC_start();
    Write_IIC_Byte(0x78);
    Write_IIC_Byte(addr); //write data
    Write_IIC_Byte(data);
    IIC_stop();
    }

  • 相关阅读:
    树形DP 统计树中长度为K的路径数量——Distance in Tree
    Linux下使用Vi是方向键变乱码 退格键不能使用的解决方法
    wikioi 1029 中序遍历总数
    struts2前端页面读取Clob/BLOB
    hdu 1712 ACboy needs your help
    HDU 2489 Minimal Ratio Tree (dfs+Prim最小生成树)
    用XMLRPC开服务进行server/client通信
    HDU 1171 Big Event in HDU
    VS2012调试执行,网页打不开
    解决安装OpenShift Client Tools时提示的dl/import (LoadError)问题
  • 原文地址:https://www.cnblogs.com/zhinianzhizhan/p/6323343.html
Copyright © 2020-2023  润新知