查看: 7375|回复: 8

FreeScale KL25Z学习(三)GPIO通用输入输出设备

  [复制链接]
  • TA的每日心情
    开心
    2013-7-2 13:29
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2014-1-11 11:47:29 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 shen2008jie 于 2014-1-11 16:41 编辑

    资料:
    DEMO历程和KL25P80M48SF0RM.pdf KL25 Sub-Family 参考手册
    FRDM-KL25Z_SCH.pdf原理图



    那么最简单的GPIO的第一个用法就是点亮LED灯。
    这里就是将管教设置为普通GPIO,输出模式。

    M0和M3,M4架构是有点相似的。了解M3以后,再看M0,就简单了。

    根据上一篇,我们得到Demo,我们先不必理解时钟频率的设置。


    那么对于GPIO。
    第一步:PORTx时钟使能

    第二步:PORTx中的某个管教开启普通GPIO模式

    第三步:GPIO控制器x 中的某个管教置位

    第四步:GPIO控制器
    x 中的某个管教开启输入输出模式(x为A,B,C,D..对应不端口)

    第三四步顺序随便。

    第一步:PORTx时钟使能
    System Clock Gating Control Register 5 (SIM_SCGC5)
    这个寄存器存着端口的时钟使能标志。看KL25P80M48SF0RM.pdf KL25 Sub-Family 参考手册 。 如下图
    a1.PNG
    那么只要SIM_SCGC5 对应的9~13位置对应控制PORTA~PORTE端口的时钟开关。

    (以后试验LED选用三色灯的红灯,对应管脚是PTB18)
    代码 SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;//第一步:PORTB时钟使能
    #define SIM_SCGC5_PORTB_MASK                     0x400u
    这个代码应该能看懂吧。看不懂就复习一下C语言。

    这样PORTB 的时钟被打开。

    第二步:PORTx中的某个管教开启普通GPIO模式
    端口被打开后。我们要选择,端口是要用普通GPIO,还是复用给别的设备,如UART,SPI。。。

    这里我们用GPIO

    那么看数据手册中KL25P80M48SF0RM.pdf KL25 Sub-Family 参考手册 。 ;如图 a2.PNG
    这个就是端口控制器Pin Control Register n (PORTx_PCRn)

    其中我们这个时候只要关注其中8~10位。如下图

    a3.PNG

    很简单只要选用GPIO。所以其中8~10位 置1就行。

    代码是:PORTB_PCR18 |= (1 << 8) ;
    //  (PORTx_PCRn) 狠容易明白x代表端口,n代表那个管脚。这个代码就是B18管脚的设置,设置为GPIO模式

    既然用了GPIO模式,那么就有GPIO控制寄存器:

    b1.PNG
    这里有具体的介绍几个寄存器。

    我罗列出底层代码里的:
    /** GPIO - Peripheral register structure */
    typedef struct GPIO_MemMap {
      uint32_t PDOR;                                   /**< Port Data Output Register, offset: 0x0 */
      uint32_t PSOR;                                   /**< Port Set Output Register, offset: 0x4 */
      uint32_t PCOR;                                   /**< Port Clear Output Register, offset: 0x8 */
      uint32_t PTOR;                                   /**< Port Toggle Output Register, offset: 0xC */
      uint32_t PDIR;                                   /**< Port Data Input Register, offset: 0x10 */
      uint32_t PDDR;                                   /**< Port Data Direction Register, offset: 0x14 */
    } volatile *GPIO_MemMapPtr;
    狠容易看出有上述几个代码。右边有英文注释,英文不好的可以翻译。很容易理解



    这里我们需要LED是输出模式。先将管教置位。
    代码:

    GPIOB_PSOR |= (1<<18);                // PORTB_18 = 1 -- LED1_OFF//第三步:GPIO控制器B中的某个管教置位
    GPIOB_PDDR |= (1<<18);                // PORTB_18 OUT//第四步:GPIO控制器B中的某个管教开启输入输出模式

    那么LED怎么置高(位)或置低呢?
      uint32_t PSOR;                                   /**< Port Set Output Register, offset: 0x4 */置高
      uint32_t PCOR;                                   /**< Port Clear Output Register, offset: 0x8 */置低
    历程代码:


                  GPIOB_PCOR |= (1<<18);                // PORTB_18 = 1 -- LED1_ON
       
                  GPIOB_PSOR |= (1<<18);                // PORTB_18 = 1 -- LED1_OFF

    那么管脚的初始化就好了
    整个代码就是:

    void gpio_init ()//GPIO_MemMapPtr GPIOx
    {
          
         SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;//第一步:PORTB时钟使能
         PORTB_PCR18 |= (1 << 8) ;//| (1 << 6) //第二步:PORTB中的某个管教开启普通GPIO模式
       

         
         GPIOB_PSOR |= (1<<18);                // PORTB_18 = 1 -- LED1_OFF//第三步:GPIO控制器B中的某个管教置位
                                           
         GPIOB_PDDR |= (1<<18);                // PORTB_18 OUT//第四步:GPIO控制器B中的某个管教开启输入输出模式
    }


    那么在main函数里加上初始化,然后加上延时就可以见到闪灯了。
    int main (void)
    {
                long i;

    #ifdef CMSIS  // If we are conforming to CMSIS, we need to call start here
        start();
    #endif  
            gpio_init ();

    printf("\n\rRunning the demo_1 gpio_init ();project.\n\r");
            while(1)
            {      
      for( i = 0; i < 6000000; ++i){

    }

                  GPIOB_PCOR |= (1<<18);                // PORTB_18 = 1 -- LED1_ON

    for( i = 0; i < 6000000; ++i)
    {

    }   
                  GPIOB_PSOR |= (1<<18);                // PORTB_18 = 1 -- LED1_OFF

            }
    }

    编译环境是IAR。源码资料

    demo_LED.rar

    2.33 MB, 下载次数: 65

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-5-12 10:32
  • 签到天数: 295 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2014-1-11 11:55:35 | 显示全部楼层
    顶一个~~~~~~~~··
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2017-4-9 11:17
  • 签到天数: 364 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2014-1-11 12:04:17 | 显示全部楼层
    帮顶!!!!!!!!!!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-11-30 08:37
  • 签到天数: 220 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-1-11 13:34:02 | 显示全部楼层
    楼主加油              
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-9-20 15:14
  • 签到天数: 5 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-1-15 19:13:54 | 显示全部楼层
    赞~~~~!!!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2017-12-1 15:13
  • 签到天数: 188 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-1-16 00:43:13 | 显示全部楼层
    支持一下~~~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-10-8 09:49
  • 签到天数: 430 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2014-1-17 11:22:31 | 显示全部楼层
    没有像ST一样的库么?直接操作寄存器太蛋疼了,对着数据手册,一个功能要老半天,软件复用功能也不行。如果改一个小的feature还要把寄存器对一遍。。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2013-7-2 13:29
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2014-1-17 13:17:05 | 显示全部楼层
    bruce_helen 发表于 2014-1-17 11:22
    没有像ST一样的库么?直接操作寄存器太蛋疼了,对着数据手册,一个功能要老半天,软件复用功能也不行。如果 ...

    那个历程已经基本写好,只是没有像ST的封装函数给你调用,不过,看数据手册,有助于你理解相同框架的原理。学习可以更深入一点。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-5-27 15:41
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-2-26 22:03:24 | 显示全部楼层
    太感谢啦   正适合我这种刚刚接触的小白学习   太好了
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-19 20:51 , Processed in 0.178970 second(s), 31 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.