MC9S12G128 GPIO

  • MC9S12G-Family Block Diagram
  • Port J相关寄存器
  • 寄存器简述
    • 端口操作
    • 单个I/O操作
    • 端口J 相关寄存器:
  • GPIO点亮LED灯示例:
  • 轮询方式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 <hidef.h> /* 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 <hidef.h>      /* 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默认电平全为0LED1_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个GPIOdelay();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 <hidef.h>      /* 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_DDRJ3unsigned 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 <hidef.h>      /* 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_DDRJ3unsigned 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 DEFAULTvoid 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,中断函数指明中断向量号:
main.c
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 中断向量号 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 NON_BANKED
interrupt void 中断服务函数名(void) {
// 中断服务程序代码段
}
#pragma CODE_SEG DEFAULT

Project.prm:
文件尾增加 VECTOR ADDRESS 中断向量 中断服务函数名
例如:ProtJ 中断向量:0xFFCE ,中断函数名:PTJ_IRQ
VECTOR ADDRESS 0xFFCE PTJ_IRQ

中断向量在mc9s12g128.h文件里有定义,如:
/**************** interrupt vector table ****************/
#define Vportj 0xFFCEU

Freescale MC9S12G128 GPIO相关推荐

  1. freescale MC9S12G128单片机概述

    MC9S12G-Family Features: 开发环境: CodeWarrior IDE: 开发板: DBM下载器: Features: This section describes the ke ...

  2. MT7621_移植篇(3) uboot编译+配置项分析

    U-Boot("通用引导加载程序",通常简称为U-Boot)是一种开源的主引导加载程序,用于嵌入式设备中打包引导设备操作系统内核的指令.它可用于多种计算机架构,包括68k.ARM. ...

  3. Freescale k60的GPIO的操作

    电子创新网提供的代码对于GPIO的操作有这样的一段,通过分析这句程序来确定对于K60的GPIO的操作. GPIOA_PDOR&=~GPIO_PDOR_PDO(GPIO_PIN(10));    ...

  4. 【驱动】GPIO 作为按键时的 设备树 配置

    #[驱动]GPIO作为按键时的 设备树 配置 0.设备树 0.0 别名 imx6ul.dtsi 什么作用??? /*************开始/ / { aliases {- gpio0 = &am ...

  5. 嵌入式系统下对GPIO的简单操作

    在嵌入式设备中对GPIO的操作是最基本的操作.一般的做法是写一个单独驱动程序,网上大多数的例子都是这样的.其实linux下面有一个通用的GPIO操作接口,那就是我要介绍的 "/sys/cla ...

  6. FreeScale mpc8xxx + vxWorks平台下spi flash驱动开发三步走

    最近在弄PowerPC平台上的spi flash的驱动程序,总体比较简单,在借鉴了U-Boot中的相关源码后,花了两周左右的时间搞定了,对于spi总线之前一直都有了解,但未能实际接触,这次在vxWor ...

  7. MC9S12G128模块化分层化软件架构之六——KEY

    ONGOING! 1      overview 1.1    目的 本文档用于起点开发板的GPIO模块软件优化说明. 不局限于硬件功能的实现,着眼于实现高质量.优美的软件. 2       优化内容 ...

  8. MC9S12G128模块化分层化软件架构之二——IO驱动

    源码地址://download.csdn.net/download/Sure_gengjia/1253037 PDF文档://download.csdn.net/download/Sure_gengj ...

  9. 【正点原子Linux连载】第四十五章 pinctrl和gpio子系统实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

最新文章

  1. 集成ShareSDK里报错NSConcreteMutableData wbsdk_base64EncodedString]
  2. Jquery学习笔记-获取select标签已经选中的值
  3. 个人作业——软件产品分析
  4. 身体容易缺少的微量元素
  5. 笔记本长时间不用出现一片黑屏
  6. mesos-master启动失败,报错Failed to load unknown flag 'quorum.rpmsave'
  7. 使用Apache Isis快速进行SEMAT应用程序开发
  8. 古希腊的五大数学巨匠
  9. 《云云众声》第95期:业界大事接着看 HP成功收购Aruba;IBM战略变动 前景发展被看好...
  10. break、continue
  11. flowchart流程图编程语言下载_c语言流程图生成器下载
  12. 表格闪退怎么解决_Excel中出现表格打开闪退的处理技巧
  13. 机器人周志_智能机器人杂志
  14. linux img文件压缩及解压
  15. Java中创建Excel文档,POI使用详解
  16. 《指弹:HARD RAIN》
  17. SQL server 服务报 远程过程调用失败0x800706be
  18. 弹性盒子flex布局实现骰子六个面并让骰子3D空间旋转
  19. 开放式运动耳机好不好用,五款最好用的骨传导耳机推荐
  20. web开发从入门到精通一(详细)

热门文章

  1. 如何直接进入迅捷CAD官网页面上进行图纸的打开和测量?
  2. EXCEL如何将日期格式转换成文本格式
  3. latex常用命令:加粗、高亮、斜体
  4. win7(amd显卡) 安装 pyopencl
  5. 那些年,我们一起追的女孩
  6. Dzzoffice部署
  7. 域的泛解析到网站服务器,什么是域名泛解析 怎么设置域名泛解析
  8. 玩转手势控制,你可能还差些高标准手势识别数据
  9. resip协议栈下的TLS使用
  10. Win10 2004微软输入法导致卡顿