MC9S12G128模块化分层化软件架构之七_外部中断

文章目录

内容

1        overview

1.1        目的

2        优化内容

2.1        软件功能

2.2        编程健壮性

3        软件实现

3.1        Coding Rule

3.2        中断基础知识

3.2.1        mc9s12g128的中断向量号

3.2.2        mc9s12g128中断向量表

3.3        driver层

3.3.1        drio_cfg.c

3.3.2        drio_cfg.h

3.3.3        drio.c

3.3.4        drio.h

3.3.5        新建drint.c

3.3.6        新建drint.h

3.4        中间件module层优化

3.4.1        mdio_cfg.h

3.4.2        mdio_cfg.c

3.4.3        mdio.c

3.4.4        mdio.h

3.5        应用层

3.5.1        apl_key.h

3.5.2        apl_key.c

3.6        main.c

3.6.1        main

4        软件测试及调试

4.1        PORTJ验证代码

4.2        MCU register

4.2.1        中断使能寄存器PIEJ

4.2.2        极性选择寄存器PPSJ

4.2.3        中断标志位寄存器PIFJ

5       实物展示

上一期的

MC9S12G128模块化分层化软件架构之六——KEY代码下载地址:

https://download.csdn.net/download/Sure_gengjia/12801323

实物展示:

更多内容,请持续关注公众号:激活未来

 

 

  • 1      overview

  • 1.1    目的

本文档用于起点开发板的外部中断模块软件说明。

不局限于硬件功能的实现,着眼于实现高质量、优美的软件

  • 2       优化内容

  • 2.1     软件功能

①      增加PORTA、PORTB、PORTC、PORTD和PORTAD引脚的相关配置;

②      driver层和module层针对新增的PORT进行调整;

2.2     编程健壮性

①     常量前增加const修饰;

②     仅用于本文件调用的变量和函数前增加static;

3      软件实现

3.1     CodingRule

具体可在源码的\Sources\code_rules.txt中可见。

3.2     中断基础知识

3.2.1         mc9s12g128的中断向量号

见mc9s12g128.h文件的第51行,如下:

 

每一个中断处理函数都要有一个中断向量号,中断处理函数格式如下:

3.2.2         mc9s12g128中断向量表

每个中断发生后,PC都会跳转到对应的地址去取值,然后进入不同的中断处理函数中。

3.3    driver层

3.3.1         drio_cfg.c

change log:

3.3.1.1          新增drio_enable_interrupt_reg[]中断使能使能寄存器

如下:

在mc9s12g128数据手册中提到:

只有PORTP、PORTJ和PORTAD支持外部中断功能,如下:

注意:由于不是所有的PORT都支持中断,所有在使能中断时不能像其他寄存器一样在drio_enable_interrupt_reg[]中直接用PORT的枚举索引,需要在PORTP的基础上索引中断使能寄存器,如使能PORTJ的PIN3,应写成:

BYTEOP_BIT_SET_AT(*drio_interrupt_flag_reg[DRIO_PORTJ - DRIO_PORTP], DRIO_PIN3);

 

3.3.1.1.1    PIEP

在MC9S12G128.h中的定义:

在芯片手册中的定义:

3.3.1.1.2     PIEJ

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.1.3     PIE1AD

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.1.4     PIE0AD

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.2          新增drio_interrupt_flag_reg[]中断标志位寄存器

如下:

在mc9s12g128数据手册中提到:

只有PORTP、PORTJ和PORTAD支持外部中断功能。

注意:由于不是所有的PORT都支持中断,所有在查询使能中断时不能像其他寄存器一样在drio_interrupt_flag_reg[]中直接用PORT的枚举索引,需要在PORTP的基础上索引中断使能寄存器,如查询PORTJ的PIN3中断标志位,应写成:

BYTEOP_BIT_READ_AT(*drio_interrupt_flag_reg[DRIO_PORTJ - DRIO_PORTP], DRIO_PIN3);

3.3.1.2.1     PIFP

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.2.2     PIFJ

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.2.3     PIF1AD

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.2.4     PIF0AD

在mc9s12g128.h中的定义:

在datasheet中的定义:

3.3.1.3          新增drio_pins_in_port[]

用于确定每个port有多少个引脚PIN。

3.3.2         drio_cfg.h

3.3.2.1          声明extern

3.3.3         drio.c

3.3.3.1          修改drio_set_pin_pull()

只有PORTT、PORTS、PORTM、PORTP、PORTJ和PORTAD有上下拉极性选择,所以drio_polarity_select_reg[]中是以PPST开始的寄存器。

3.3.3.2          增加drio_enable_interrupt()

使能中断使能前先清中断标志位。

3.3.3.3          增加drio_set_pin_int_type()

设置中断类型:上升沿中断还是下降沿中断,由于中断方式选择和上下拉极性选择是同一个寄存器,但是支持中断的只有PORTP、PORTJ、PORTAD,所以要从PORTP开始,增加有效port范围检查。

3.3.4         drio.h

3.3.5         新建drint.c

change log:

3.3.5.1          新增drint_portj_isr()

PORTJ中断处理函数:

说明:

1.       所有的中断处理函数都要在非分页区,因为16位芯片的MC9S12寻址范围0~2^16,十六进制范围(0, 0xFFFF),这个地址范围内是非分页区;

2.       中断处理函数需要有中断向量号,VectorNumber_Vportj为PORTJ中断向量号,具体的中断向量号可以在mc9s12g128.h的第51找到;

3.       PIFJ是PORTJ中断标志位寄存器,应在处理完任务之后写1清中断标志位;清中断标志位是为了下次中断能正常进入;在处理完之后再清中断标志位是防止在没有处理完中断处理任务时PORTJ再次触发中断,造成中断嵌套,造成处理错乱。

3.3.5.2          新增drint_portp_isr()

PORTP外部中断处理函数:

3.3.5.3          新增drint_portad_isr()

PORTAD中断处理函数:

在中断处理函数接收后,需要声明代码段恢复到默认代码段。

代码段定义在Project.prm中可见:

3.3.6         新建drint.h

中断处理函数自下而上调用callback函数,driver层调用module中间层,使用宏替换实现。

3.4    中间件module层优化

3.4.1         mdio_cfg.h

change history:

3.4.1.1          增加中断类型枚举

枚举数值需要和极性选择对应,在数据手册中可见,对于支持中断的PORT,极性选择寄存器1代表pulldown,同时代表上升沿中断选择;0代表pullup,同时代表下降沿中断选择。输入和中断不能同时选择,可以共用这个寄存器。

3.4.1.2          修改MdIoInputCfgStruct

增加中断类型选择

3.4.2         mdio_cfg.c

change log:

3.4.2.1          修改mdio_input_cfg[]

增加int_type选择,KEY1设置为下降沿触发中断,KEY2设置为上升沿触发中断。

根据原理图可知,对应的按键

key

SW丝印标号

PIN

key1

SW4

PJ4

key2

SW5

PJ5

key3

SW6

PJ6

key4

SW3

PJ7

 

3.4.3         mdio.c

change log:

3.4.3.1          io初始化函数mdio_init优化

1.       增加中断类型判断;

2.      如果配置了中断,设置中断触发方式,并使能中断;

3.4.3.2          增加静态函数uint8 mdio_find_in_input_cfg(uint8port, uint8 pin)

根据port和pin找到在mdio_input_cfg[]数组中排第几个,返回给mdio_portj_isr_callback(),便于应用层查询。

3.4.3.3          增加mdio_portj_isr_callback()

中间层中断处理函数callback函数,根据产生中断的PORT和pin查找到配置的index,然后传递给应用层,便于应用层处理。

3.4.4         mdio.h

新增函数声明:

3.5    应用层

3.5.1         apl_key.h

有原理图知:按键按下,PIN脚电平为0,松开为1。

3.5.2         apl_key.c

3.5.2.1          新增void apl_key_int_handler(uint8 keyx)

用于按键中断处理。第一个按键触发中断,LED1~LED4开,LED5~LED8关,第二个按键触发中断,LED1~LED4关,LED5~LED8开。

3.6    main.c

3.6.1         main

1.       调用初始化函数;

2.      调用周期任务;

4       软件测试及调试

4.1    PORTJ验证代码

4.2    MCU register

4.2.1         中断使能寄存器PIEJ

PORTJ的中断使能寄存器PIEJ,从图中可以看出,我们需要PIEJ位4到位5都为1,即使能中断。

4.2.2         极性选择寄存器PPSJ

根据mdio_cfg.c中的配置,在KEY1对应的PJ4设置为下降沿触发中断,KEY2对应的PJ5设置为上升沿触发中断,所以PPSJ极性寄存器bit4应为0,bit5应为1, debug可以看到如下:

4.2.3         中断标志位寄存器PIFJ

4.2.3.1          没有按键触发中断时

在没有外部中断触发时,中断标志位寄存器都为0:

4.2.3.2          按键KEY1触发中断时

在drint.c中的drint_portj_isr()打断点,当按键KEY1按下时(下降沿):

此时的中断标志位寄存器PIFJ的位4为1:

在中断处理函数接收后清中断标志位后,中断标志位重新恢复到0x00。

4.2.3.3          按键KEY2触发中断时

在drint..c中的drint_portj_isr()打断点,当按键KEY2按下并松开时(上升沿):

此时的中断标志位寄存器PIFJ的位4为1:

在中断处理函数接收后清中断标志位后,中断标志位重新恢复到0x00。

5      实物展示

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值