打印
[应用相关]

kinetis 学习之GPIO

[复制链接]
762|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
之前学过一段时间的MSP430,现在由于课程的需要学习freescale的kinetis k20,具体芯片型号为MK20DN512。以前学习的时候也遇到过很多问题,在网上找到了很多有用的博客,现在希望把自己学习的一些经验也用博客的方式分享给新入门的童鞋们。其实我也不是老手,所以如果有错误之处还望各位看官指出。

       OK,废话少说!和学习C语言的hello world一样,在嵌入式学习最开始的就是跑马灯程序,也就是让GPIO工作起来。

       首先介绍一下自己的开发平台,硬件是THU的工物系开发的k_class v1.1,主控为freescale的Cortex-M4芯片MK20DN512,在开发板上有2个LED,八个按键,6个数码管,一个蜂鸣器,旋钮式可变电阻等常用外设。软件平台是使用CodeWarrior10.6,它是基于Eclipse内核开发的,所以虽然以前没有用过CodeWarrior但是界面还是比较熟悉的,据说它的功能很强大的哦,搞起奋斗

        好,首先来理清一下思路,为了让LED灯能够亮起来,分以下三部曲:(1)查看原理图弄清楚LED连接的是哪几个GPIO;(2)打开对应的GPIO的时钟,配置相关的引脚控制寄存器(Pin Control Register),数据的输入输出方向;(3)进行功能相关代码编写。

如图1所示,LEDs接到PTD4和PTD7这两个引脚。接下来是第(2)步,由于LEDs接到PTD上,所以首先要打开PORTD的时钟,那它在哪里呢?请看图2.

沙发
energy1|  楼主 | 2015-2-6 23:06 | 只看该作者

[size=18.399999618530273px] 图2  系统集成模块的系统门控时钟5(SIM_SCGC5)
[size=18.399999618530273px]

从图2中可以看到各个PORT端口对应的位置,其中PORTD为第12位。再接下来的打开每个引脚对应寄存器,这里主要用到PCB,PDDR,PDOR,至于其他的寄存器暂时不需要,不过最好也都了解一下,这个就得靠自己了。下面具体以PORTx_PCBn为例,通过参考手册上的描述,可知设置MUX为1,即选择GPIO功能。如果设置为0时选择的是模拟IO口功能,这个有什么用呢?以后会发现它可以应用到对外界模拟信号的采集上(ADC功能),当然这个是后话,以后再写一个使用到模拟口的功能的例子。

[size=14.399999618530273px] 图3    PORTx_PCBn功能描述

[size=14.399999618530273px]       下面直接上代码吧,注释已有。




使用特权

评论回复
板凳
energy1|  楼主 | 2015-2-6 23:07 | 只看该作者
char cnt =0; // max is 255
SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;  //  OPEN PORT D CLOCK
PORTD_PCR4 |= PORT_PCR_MUX(1);      // SET PORTD_PIN4 AS GPIO
PORTD_PCR7 |= PORT_PCR_MUX(1);      // SET PORTD_PIN7 AS GPIO
GPIOD_PDDR |= ( GPIO_PIN(4) | GPIO_PIN(7) ); // SET PIN4 AND PIN7 AS OUPUT PORT


       当我们完成了基本配置后,就要来走第三步。写功能函数,这里给出两个例子,一个是灯一起亮灭,也就是一闪一闪(twinkle),还有一个就是依次亮灭(flashing)跑马灯功能。  

      while(1) {
for( cnt = 0; cnt<10; cnt++)
     twinkle_1Hz();            //  twinkle the LEDs at 1Hz
for( cnt = 0; cnt<10; cnt++)
     flashing();               //  LEDs turn on and off one by one
}  

       要实现这个功能首先我们就需要知道当前的MCU的时钟是多少,这样才能便于控制亮灭的时间。在默认的情况下系统时钟为20.97MHz,具体和时钟相关的内容情况Chapter5 Clock Distribution这个章节。

使用特权

评论回复
地板
energy1|  楼主 | 2015-2-6 23:08 | 只看该作者

     图4    各个模块的时钟源

           写一个延时函数,延时为1ms,这样设置灯亮灭的频率为1Hz。

void twinkle_1Hz()  // led twinkle 1Hz
{
GPIOD_PDOR |= ( GPIO_PIN(4) | GPIO_PIN(7) ); // LED OFF
    delay_1ms(1000);
    GPIOD_PDOR &= ~( GPIO_PIN(4) | GPIO_PIN(7) ); // LED ON
delay_1ms(1000);
}

void flashing()  // led turn on or off one by one
{
GPIOD_PDOR &= ~( GPIO_PIN(4) ); // LED ON
GPIOD_PDOR |=  ( GPIO_PIN(7) ); // LED OFF
delay_1ms(1000);
GPIOD_PDOR |=  ( GPIO_PIN(4) ); // LED OFF
GPIOD_PDOR &= ~( GPIO_PIN(7) ); // LED ON
    delay_1ms(1000);
}

这样我们的LEDs已经可以亮灭了。

使用特权

评论回复
5
mmuuss586| | 2015-2-6 23:16 | 只看该作者

发错版块了,这是ST版块;

使用特权

评论回复
6
energy1|  楼主 | 2015-2-7 22:36 | 只看该作者
哦,不好意思啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

94

主题

422

帖子

10

粉丝