Freescale MC9S12G128 GPIO

2021-07-21来源: eefocus关键字:Freescale  GPIO

MC9S12G-Family Block Diagram

在这里插入图片描述

不同芯片封装端口:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Port J相关寄存器

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

The PIM includes these distinctive registers:

• Data registers and data direction registers for ports A, B, C, D, E, T, S, M, P, J and AD when used

as general-purpose I/O

• Control registers to enable/disable pull devices and select pullups/pulldowns on ports T, S, M, P, J

and AD on per-pin basis

• Single control register to enable/disable pull devices on ports A, B, C, D and E, on per-port basis

and on BKGD pin

• Control registers to enable/disable open-drain (wired-or) mode on ports S and M

• Interrupt flag register for pin interrupts on ports P, J and AD

• Control register to configure IRQ pin operation

• Routing register to support programmable signal redirection in 20 TSSOP only

• Routing register to support programmable signal redirection in 100 LQFP package only

• Package code register preset by factory related to package in use, writable once after reset. Also

includes bit to reprogram routing of API_EXTCLK in all packages.

• Control register for free-running clock outputs


寄存器简述

项目代码需要引入的头文件:

#include /* common defines and macros /

#include “derivative.h” / derivative-specific definitions */

mc9s12g128.h(寄存器相关定义)


PORTx (端口数据寄存器):可读写端口数据 1:高电平, 0:低电平;

DDRx(端口方向寄存器):设置端口方向 1:输出,0:输入;

PUCR(引脚上拉控制寄存器) 1:使能上拉,0:禁止上拉;

RDRIV(低功耗驱动寄存器) 1:低功耗 0:正常功耗;

x: 取值有A,B AB,C,D,CD,E等取值(不同版本芯片有差异,以实际芯片定义为准)

端口掩码定义,用于位操作,可查阅mc9s12g128.h文件中定义


端口操作

端口数据寄存器:PO

RTA,PORTB, PORTAB, PORTC, PORTD, PORTCD,PORTE

端口方向寄存器:DDRA,DDRB,DDRAB,DDRC,DDRD,DDRCD,DDRE

AB操作(PA0…PA7, PB0…PB7 共16个GPIO)


端口数据寄存器或端口方向寄存器每一位对应单个GPIO;


单个I/O操作

这个以PA端口举例:

PORTA

PORTA_PA0 ~ PORTA_PA7

PORTAB_PB

PORTAB_PA


设置单个GPIO的方向

DDRA

DDRA_DDRA0 ~ DDRA_DDRA7

DDRAB_DDRB

DDRAB_DDRA


端口J 相关寄存器:

/*** PTJ - Port J Data Register; 0x00000268 ***/

端口J 数据寄存器(0:低电平,1:高电平)

PTJ

PTJ_PTJ0 ~ PTJ_PTJ7

PTJ_PTJ0_MASK ~ PTJ_PTJ7_MASK


/*** PTIJ - Port J Input Register; 0x00000269 ***/

端口J 输入寄存器 (0:输入电平,1:输入高电平)

PTIJ

PTIJ_PTIJ0 ~ PTIJ_PTIJ7

PTIJ_PTIJ0_MASK ~ PTIJ_PTIJ7_MASK


/*** DDRJ - Port J Data Direction Register; 0x0000026A ***/

端口J 数据方向寄存器 (0:输入,1:输出)

DDRJ

DDRJ_DDRJ0 ~ DDRJ_DDRJ7

DDRJ_DDRJ0_MASK ~ DDRJ_DDRJ7_MASK


/*** PERJ - Port J Pull Device Enable Register; 0x0000026C ***/

端口J 拉设备使能寄存器

PERJ

PERJ_PERJ0 ~ PERJ_PERJ7

PERJ_PERJ0_MASK ~ PERJ_PERJ7_MASK


/*** PPSJ - Port J Polarity Select Register; 0x0000026D ***/

端口J 拉设备极性选择寄存器 (0:选择上拉,下降沿触发中断,1:选择下拉,上升沿触发中断)

PPSJ

PPSJ_PPSJ0 ~ PPSJ_PPSJ7

PPSJ_PPSJ0_MASK ~ PPSJ_PPSJ7_MASK


/*** PIEJ - Port J Interrupt Enable Register; 0x0000026E ***/

端口J 中断使能寄存器 (0:关闭中断, 1:使能中断)

PIEJ

PIEJ_PIEJ0 ~ PIEJ_PIEJ7

PIEJ_PIEJ0_MASK ~ PIEJ_PIEJ7_MASK


/*** PIFJ - Port J Interrupt Flag Register; 0x0000026F ***/

端口J 中断标志寄存器 (写1清中断,写0无效)

PIFJ

PIFJ_PIFJ0 ~ PIFJ_PIFJ1

PIFJ_PIFJ0_MASK ~ PIFJ_PIFJ7_MASK


其他端口都大同小异可以查阅相关文档;


GPIO点亮LED灯示例:

#include       /* common defines and macros */

#include "derivative.h"      /* derivative-specific definitions */



#define LEDPORT     PORTA

#define LEDDIR      DDRA


#define LED1_PORT   PORTD_PD3

#define LED1_DIR    DDRD_DDRD3


/**

* @brief 延时函数

* @param none

* @return none

*/

void delay(void) {

  unsigned int i,j;

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

    for(j=0; j<50000; j++){

      ;

    }

  }

}


/**

* @brief LED GPIO初始化

* @param none

* @return none

*/

void LED_Init(void) {

  LEDDIR = 0xff;     // 设置PORTA(PA0~PA7 8PIN)端口为输出

  LEDPORT = 0x00;    // 设置PORTA默认电平全为0

  

  LED1_DIR = 0x1;      // 设置PORTD_PD3(PD3 PIN)GPIO为输出

  LED1_PORT = 0x0;     // 设置PORTD_PD3(PD3 PIN)GPIO低电平

}


void main(void) {

  /* put your own code here */

  

  DisableInterrupts;  // 关总中断

  LED_Init();

EnableInterrupts;   // 开总中断


  for(;;) {

  

    // 操作整个端口 这里是PA端口(PA0~PA7)8个GPIO

    delay();

    LEDPORT = 0xf0;  // 端口操作

    LED1_PORT = 0;   // GPIO操作

    

    delay();

    LEDPORT = 0x0f;  // 端口操作

    LED1_PORT = 1;   // GPIO操作

    

    _FEED_COP(); /* feeds the dog */

  } /* loop forever */

  /* please make sure that you never leave main */

}


轮询方式GPIO按键示例:

#include       /* common defines and macros */

#include "derivative.h"      /* derivative-specific definitions */


#define KEYCODE_0 (0)

#define KEYCODE_1 (1)

#define KEYCODE_2 (2)

#define KEYCODE_3 (3)

#define KEYCODE_NONE (0xff)


#define LED_PORT PORTA

#define LED_DIR  DDRA



#define KEY0_IN  PTIJ_PTIJ0

#define KEY1_IN  PTIJ_PTIJ1

#define KEY2_IN  PTIJ_PTIJ2

#define KEY3_IN  PTIJ_PTIJ3


#define KEY0_DIR DDRJ_DDRJ0

#define KEY1_DIR DDRJ_DDRJ1

#define KEY2_DIR DDRJ_DDRJ2

#define KEY3_DIR DDRJ_DDRJ3



unsigned char keycode = KEYCODE_NONE;


void key_delay(void){

  unsigned int i;

  i = 10000;

  while(i--){

    ;

  }

}



void led_gpio_init(void) {

  LED_DIR = 0xFF;

  LED_PORT = 0xFF;  

}


void key_gpio_init(void){

  // 设置GPIO输入模式 0:输入, 1:输出

  KEY0_DIR = 0;

  KEY1_DIR = 0;

  KEY2_DIR = 0;

  KEY3_DIR = 0;

}


/*

* @brief 查询方式检测按键

*

*

*/

void key_scaning(void) {

  // 有按键按下

  if ((KEY0_IN == 0) || (KEY1_IN == 0) || (KEY2_IN == 0) || (KEY3_IN == 0)) {

     // 按键去抖延时

     key_delay(); 


     // 确认有按键按下     

     if ((KEY0_IN == 0) || (KEY1_IN == 0) || (KEY2_IN == 0) || (KEY3_IN == 0)) {

        if (KEY0_IN == 0) {

           keycode = KEYCODE_0;

        } else if (KEY1_IN == 0) {

           keycode = KEYCODE_1;

        } else if (KEY2_IN == 0) {

           keycode = KEYCODE_2;

        } else if (KEY3_IN == 0) {

           keycode = KEYCODE_3;

        } else {

           keycode = KEYCODE_NONE;

        }

     }

  } else {

     keycode = KEYCODE_NONE;

  }

}



void key_process(void) {

  switch(keycode) {

    case KEYCODE_0:

      LED_PORT = ~(0x01 << 0); // LED0亮

      break;

    case KEYCODE_1:

      LED_PORT = ~(0x01 << 1); // LED1亮

      break;

    case KEYCODE_2:

      LED_PORT = ~(0x01 << 2); // LED2亮

      break;

    case KEYCODE_3:

      LED_PORT = ~(0x01 << 3); // LED3亮

      break;

    default:

      LED_PORT = 0xff;

      break;

  }


}



void main(void) {

  /* put your own code here */

  

  DisableInterrupts;

  led_gpio_init();

  key_gpio_init();

EnableInterrupts;


 

  

  for(;;) {

    key_scaning();


    key_process();

    _FEED_COP(); /* feeds the dog */

  } /* loop forever */

  /* please make sure that you never leave main */

}


中断方式按键示例:

#include       /* common defines and macros */

#include "derivative.h"      /* derivative-specific definitions */


#define KEYCODE_0 (0)

#define KEYCODE_1 (1)

#define KEYCODE_2 (2)

#define KEYCODE_3 (3)

#define KEYCODE_NONE (0xff)



#define LED PORTA

#define LED_dir DDRA


#define KEY0_IN   PTIJ_PTIJ0

#define KEY1_IN   PTIJ_PTIJ1

#define KEY2_IN   PTIJ_PTIJ2

#define KEY3_IN   PTIJ_PTIJ3


#define KEY0_dir  DDRJ_DDRJ0

#define KEY1_dir  DDRJ_DDRJ1

#define KEY2_dir  DDRJ_DDRJ2

#define KEY3_dir  DDRJ_DDRJ3



unsigned char keycode = KEYCODE_NONE;



void led_gpio_init(void) {

  LED_dir = 0xFF; // 设为输出模式, 1:输出 0:输入

  LED = 0xFF;     // LED全部熄灭高电平熄灭

}


void key_gpio_init(void) {

  KEY0_dir = 0;  // 设为输入模式, 1:输出 0:输入

  KEY1_dir = 0;  // 设为输入模式, 1:输出 0:输入

  KEY2_dir = 0;  // 设为输入模式, 1:输出 0:输入

  KEY3_dir = 0;  // 设为输入模式, 1:输出 0:输入

  

  PPSJ = 0x00;       //极性选择寄存器,选择下降沿; 0:下降沿, 1:上升沿

  PIFJ = 0x0f;     //对PIFJ的每一位写1来清除标志位;

  PIEJ = 0x0f;       //中断使能寄存器;    0:关闭中断, 1:使能中断

  

}



void key_process(void) {

  switch(keycode) {

    case KEYCODE_0:

      LED = ~(0x01 << 0); // LED0亮

      break;

    case KEYCODE_1:

      LED = ~(0x01 << 1); // LED1亮

      break;

    case KEYCODE_2:

      LED = ~(0x01 << 2); // LED2亮

      break;

    case KEYCODE_3:

      LED = ~(0x01 << 3); // LED3亮

      break;

    default:

      LED = 0xff;

      break;

  }


}


/*

* @brief 按键中断函数

*/

#pragma CODE_SEG __NEAR_SEG NON_BANKED

interrupt VectorNumber_Vportj void PTJ_IRQ(void) {

  // 判断中断标志

  if (PIFJ != 0) {

    PIFJ = 0xff; // 清除中断标志

    

    if (KEY0_IN == 0) {

        keycode =  KEYCODE_0;

    } else if (KEY1_IN == 0) {

        keycode =  KEYCODE_1;

    } else if (KEY2_IN == 0) {

        keycode =  KEYCODE_2;    

    } else if (KEY3_IN == 0) {

        keycode =  KEYCODE_3;    

    } else {

        //keycode = KEYCODE_NONE;

    }

  }

  

}

#pragma CODE_SEG DEFAULT



void main(void) {

  /* put your own code here */

  

  DisableInterrupts;

  led_gpio_init();

  key_gpio_init();

EnableInterrupts;



  for(;;) {

  

  key_process();

    _FEED_COP(); /* feeds the dog */

  } /* loop forever */

  /* please make sure that you never leave main */

[1] [2]
关键字:Freescale  GPIO 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic542567.html

上一篇:MC9S12XS128实现超声波测距
下一篇:freescale MC9S12G128 中断代码实现方法

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

freescale MC9S12G128 SCI,printf使用
; // PLLCLK:32M     BUSCLK:16M  //CPMUSYNR = 0x42; // PLLCLK:24M     BUSCLK:12M  CPMUSYNR = 0x01; // PLLCLK:16M    BUSCLK:8M  CPMUREFDIV = 0x81;//REFDIV基准分频器配置  #endif      CPMUPOSTDIV = 0x00;           // PLL
发表于 2021-07-21
freescale <font color='red'>MC9S12G128</font> SCI,printf使用
Freescale MC9S12G128 PLL,OSC
PLL OSC简述:S12CPMU Block Diagram:S12CPMU Synthesizer Register(CPMUSYNR)PLL相关主要寄存器:CPMUPROT:时钟配置寄存器保护Clock Configuration Registers Protection Bit — This bit protects the clock configuration registers fromaccidental overwrite (see list of affected registers above):Writing 0x26 to the CPMUPROT register clears the PROT bit
发表于 2021-07-21
Freescale <font color='red'>MC9S12G128</font> PLL,OSC
freescale MC9S12G128单片机概述
MC9S12G128MLL开发板实物图DBM下载器:飞翔科技DBM下载实物图:
发表于 2021-07-21
freescale <font color='red'>MC9S12G128</font>单片机概述
freescale MC9S12G128 中断代码实现方法
写法1:中断函数指明中断向量号:main.c#pragma CODE_SEG __NEAR_SEG NON_BANKEDinterrupt 中断向量号 void 中断服务函数名(void) {// 中断服务程序代码段}#pragma CODE_SEG DEFAULT中断向量号在mc9s12g128.h文件里有定义,如:/**************** interrupt vector numbers ****************/#define VectorNumber_Vportj 24U写法2:修改prm文件,在Project.prm文件声明中断函数:main.c:#pragma CODE_SEG __NEAR_SEG
发表于 2021-07-21
Freescale MC9S08AW60汇编学习笔记
能够实现用七段led数码管显示出数字和字母、让它们同时显示甚至于滚动显示,这些功能已经很不错了,但是这样还不够,我们还想实现更准确的控制,让数码管按照我们的想法来显示,而不是呆板的循环,这样我们引入中断的想法。也许其他人会从查询和中断的关系这些地方来引出中断,但是我还是倾向于从控制的观点来引出中断,毕竟中断也是实现更直观的人为控制的方法,程序的运行变得可以加入人的意愿来执行,如果我们要让程序进入某一个中断程序,那么给主程序发一个中断,让它跳到中断子程序中运行就行了;我们不发中断,中断子程序就不会执行。还是用七段led数码管来演示,我们没发一个中断信号,数码管就在0~9之间变化一下。代码如下: INCLUDE MC9S08A
发表于 2021-04-07
<font color='red'>Freescale</font> MC9S08AW60汇编学习笔记
MC9S12G128 SCI设置
以下代码SCI开启了接收中断。  /*************************************************************/  /*                        初始化SCI                          */  /********************
发表于 2021-07-30
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved