将5350 i2c clk设置为gpio 中断模式的方法

5350 GPIO中断配置
本文介绍如何在5350芯片上配置特定GPIO作为中断源,包括查阅数据手册确定GPIO编号、设置GPIO模式、使能中断及配置中断触发方式等步骤。

5350和我之前用的三星和全志的芯片在中断这块有点差别,三星和全志的都是有专门的外部中断管脚,并且每个中断管脚对应一个中断号,对管脚寄存器的配置即irq_desc里chip变量,都是bsp里自带的,我们只需要用request_irq来注册irqaction就可以了。

而5350所有的gpio共用一个中断号6,所以想用哪个管脚都得自己配。有可能能用request_irq,但是驱动里已经有

setup_irq(SURFBOARDINT_GPIO,&ralink_gpio_irqaction);

所以我觉的还是在他这个基础上改比较好

 

1.  在5350 中断初始化的时候会调用ralink_gpio_init_irq函数

ralink_gpio_init_irq定义在driver/char/ralink_gpio.c

void __init ralink_gpio_init_irq(void)

{

    setup_irq(SURFBOARDINT_GPIO,&ralink_gpio_irqaction);

}

这里已经调用了setup_irq函数来给irq_desc设置了irqaction,那么我们就不用再自己来用request_irq函数来设置irqaction了。

因为5350里所有的gpio中断都共享了6号中断,那么我们如果想让哪个gpio产生中断的话,需要自己来对相关的gpio进行配置。


2. 现在我们想让i2c clk管脚配置为中断模式的话,需要以下几个步骤

1) 查看datasheet 第1.3节  pin sharing scheme

确定I2C_SCLK 为2号GPIO

 

 

2) 查看datasheet第3.4节 system control


将GPIOMODE寄存器的第0位设置为1,即将I2C设置为gpio模式。

代码如下:

gpiotmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));

gpiotmp |= 0x1;

*(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiotmp);

3) 查看datasheet 第3.6节  interrupt controller


将INTENA寄存器的第6位设置为1,即使能PIO中断。

代码如下:

gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_INTENA));

gpiotmp |= (0x01 << 6);

*(volatile u32 *)(RALINK_REG_INTENA) =cpu_to_le32(gpiotmp);

4) 查看datasheet 第3.10节  programmable I/O

将GPIO21_00_RENA和GPIO21_00_FENA这两个寄存器的第2位设置为1,即2号GPIO的上升沿和下降沿的中断使能。


代码如下:

gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIORENA));

gpiotmp |= (0x01 << 2);

*(volatile u32 *)(RALINK_REG_PIORENA) =cpu_to_le32(gpiotmp);

   

gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIOFENA));

gpiotmp |= (0x01 << 2);

*(volatile u32 *)(RALINK_REG_PIOFENA) =cpu_to_le32(gpiotmp);

 

将GPIO21_00_DIR寄存器的第2位设置为0,即为输入模式。


代码如下

gpiotmp = le32_to_cpu(*(volatile u32*)(RALINK_REG_PIODIR));

gpiotmp &= ~cpu_to_le32(0x01<< 2);

*(volatile u32 *)(RALINK_REG_PIODIR) =cpu_to_le32(gpiotmp);

 

以上代码都是放置在ralink_gpio_init函数中

3. 通过上面的设置,ralink_gpio_irq_handler这个中断处理函数就可以被调用了。

### I2C通信使用GPIO引脚 在嵌入式系统开发中,I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,用于连接微控制器和低速外围设备。当微控制器的硬件I2C已被占用或不存在时,可以通过软件实现I2C通信,利用普通的GPIO(General Purpose Input/Output)引脚模拟I2C时序[^2]。 #### 配置GPIO引脚为开漏输出 为了通过GPIO引脚模拟I2C通信,首先需要将相关的GPIO引脚配置为开漏输出模式。这种配置允许引脚既能够作为输出驱动信号,也能够在不使用时释放总线,让其他设备控制它。例如,在STM32系列微控制器上,可以使用如下代码片段来配置SCL(串行时钟线)和SDA(串行数据线)引脚: ```c void Simulate_IIC_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能SCL和SDA引脚所在的GPIO时钟 SL_IIC_SCL_APBxClock_FUN(SL_IIC_SCL_CLK, ENABLE); SL_IIC_SDA_APBxClock_FUN(SL_IIC_SDA_CLK, ENABLE); // 设置GPIO初始化结构体 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置GPIO速度 GPIO_InitStructure.GPIO_Pin = SL_IIC_SCL_PINS; // SCL引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 开漏输出模式 GPIO_Init(SL_IIC_SCL_PORT, &GPIO_InitStructure); // 初始化SCL引脚 GPIO_InitStructure.GPIO_Pin = SL_IIC_SDA_PINS; // SDA引脚 GPIO_Init(SL_IIC_SDA_PORT, &GPIO_InitStructure); // 初始化SDA引脚 } ``` 此函数`Simulate_IIC_Config`负责初始化两个GPIO引脚作为开漏输出,为后续的I2C通信做好准备[^1]。 #### 实现软件I2C通信 一旦GPIO引脚被正确配置,就可以开始编写软件I2C通信的函数了。这通常包括起始条件、停止条件、发送字节、接收字节以及确认应答等基本操作。每个操作都需要精确地控制SCL和SDA的状态变化,以符合I2C协议的要求。 #### 解决硬件I2C忙等待问题 如果使用的是硬件I2C并且遇到了总线繁忙的问题,即调用`I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)`总是返回忙状态,那么可能需要检查是否正确释放了总线或者是否有外部设备持续拉低了SCL或SDA线。解决这类问题的方法之一是确保在每次通信结束后释放总线资源,并且在初始化过程中正确配置I2C外设参数[^3]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值