管脚号到中断号计算

本文介绍Linux内核中针对AM335x EVM板载GPIO的IRQ计算过程。通过定义宏将GPIO信号转换为pin number,并据此计算出IRQ中断号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux/arch/arm/mach-omap2/board-am335xevm.c 文件中有计算公式:

先获得GPIO的pin number:

/* Convert GPIO signal to GPIO pin number */
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

然后获得irq中断号:

irq = OMAP_GPIO_IRQ(pin_num)

其中pin_num=GPIO_TO_PIN(bank,gpio),比如GPIO1_7,pin_num=32*1+7=39, irq=160+39=199

<think>嗯,用户这次在深入询问中断号的具体细节和自动重装模式,看来ta正在学习51单片机的中断系统。从ta引用资料的严谨程度看,应该是电子相关专业的学生或工程师,需要准确的技术细节而非泛泛而谈。用户引用的四份资料很有价值,特别是引用[3]明确提到了TMOD的位结构[^3],这正好能解释为什么自动重装模式(模式2)对应M1M0=10。有趣的是,用户提供的资料[^1][^2]显示定时器0和1的初始化有混淆——资料[1]函数名time1_init()却配置了TH0/TL0,这可能是笔误,需要在回答中悄悄纠正。关于中断号部分,必须强调51内核的硬性规定:5个基本中断源对应固定向量地址和入口号[^4]。用户似乎对定时器0的interrupt1特别关注,这很合理,因为定时器0是最常用的定时中断源。引用[4]提到的TF0标志位自动清除机制[^4],可以自然融入自动重装模式的说明里。自动重装模式的解释要突出两个技术亮点:一是硬件自动重载消除了软件延迟,这点在引用[2]的16位模式对比中尤为明显[^2];二是TH0作为缓冲寄存器允许动态修改周期,这点用户没直接问但很有用。计算最小/最大周期时需说明晶振前提,用户之前提到12MHz[^1][^2],就以此为准。注意到用户追问"如何避免中断冲突",这其实超出了当前问题范围,但确实是实战重点。需要简要提到中断优先级寄存器IP的设置技巧,不过篇幅所限,重点还是放在用户明确要求的三个点上。</think> ### 51单片机中断号与定时器0溢出中断详解 #### **一、中断号分配规则** 在标准51架构中,每个中断源有**固定中断号**,由硬件定义(见下表): | 中断源 | 中断号 | 向量地址 | 触发条件 | |---------------------|--------|----------|---------------------------| | 外部中断0 (`INT0`) | 0 | 0003H | P3.2引脚低电平/下降沿 | | **定时器0溢出** | **1** | **000BH**| `TF0=1`(定时器0计数溢出) | | 外部中断1 (`INT1`) | 2 | 0013H | P3.3引脚低电平/下降沿 | | 定时器1溢出 | 3 | 001BH | `TF1=1` | | 串口通信 (`RI/TI`) | 4 | 0023H | 串行数据发送/接收完成 | > **定时器0溢出中断入口号是 `interrupt 1`**,必须严格对应声明: > ```c > void Timer0_ISR() interrupt 1 { // 使用interrupt 1声明 > // 中断处理代码 > } > ``` > 当定时器0计数溢出时,硬件将 `TF0` 置1并跳转到 **000BH** 地址执行[^4]。 --- #### **二、定时器0自动重装模式(模式2)** 通过 `TMOD` 寄存器设置工作模式: ```c TMOD |= 0x02; // 设置定时器0为模式2(8位自动重装)[^3] ``` ##### **核心特性**: 1. **硬件结构** - `TL0`:**8位计数器**(计数范围:0~255) - `TH0`:**重装值寄存器**(存储自动装载的初值) 2. **自动重装机制** 当 `TL0` 从255溢出到0时: - 硬件自动将 `TH0` 的值复制到 `TL0` - 置位溢出标志 `TF0=1`(触发中断) ```c TH0 = 0xFC; // 重载初值(例如定时1ms) TL0 = 0xFC; // 首次计数初值(需与TH0相同) ``` 3. **与传统模式对比** | 特性 | 模式1(16位) | **模式2(自动重装)** | |--------------|------------------------|--------------------------| | 计数器位宽 | 16位(TH0+TL0) | **8位(TL0)** | | 重装方式 | 需软件重装 | **硬件自动重装** | | 中断响应延迟 | 高(重装耗时约1μs) | **低(无软件操作)** | | 适用场景 | 长周期定时 | **高精度短定时** | ##### **定时周期计算(12MHz晶振)**: 公式: $$ T = \frac{(256 - TH0) \times 12}{f_{osc}} \quad (f_{osc}=12\text{MHz}) $$ - **最小定时周期**:`TH0=255`(计数1次) $$ T_{min} = \frac{(256-255) \times 12}{12\times10^6} = 1\,\mu\text{s} $$ - **最大定时周期**:`TH0=0`(计数256次) $$ T_{max} = \frac{(256-0) \times 12}{12\times10^6} = 256\,\mu\text{s} $$ ##### **实例代码(初始化模式2)**: ```c void Timer0_Init() { TMOD |= 0x02; // 定时器0模式2(自动重装) TH0 = 0xFC; // 重载值 = 252 TL0 = 0xFC; // 首次计数值 ET0 = 1; // 开启定时器0中断 EA = 1; // 开启总中断 TR0 = 1; // 启动定时器 } void Timer0_ISR() interrupt 1 { static u16 count = 0; if (++count >= 1000) { // 1000次中断 = 1s(1ms × 1000) count = 0; P1_0 = ~P1_0; // LED翻转 } } ``` > **优势**:避免模式1手动重装的时间误差,定时精度更高[^2][^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值