XRA1403扩展IO编程

XRA1403是一款带有SPI接口的16位GPIO扩展器。上电后,XRA1403在每个I / O引脚上都有内部100K欧姆上拉电阻,可以单独使能。
官网数据下载https://www.alldatasheet.com/datasheetpdf/pdf/839979/EXAR/XRA1403.html
1.封装图
在这里插入图片描述
2.引脚功能图
在这里插入图片描述
3.硬件设计注意点
IRQ#引脚是开漏,必须接上拉电阻,不然一直为低电平,不能检测中断的到来!
实际使用51K电阻上拉3.3V能正常检测到中断信号。
4.读写命令操作
在这里插入图片描述
写命令:
命令格式为16位,前8位是命令,后八位写入数据;
命令如F IGURE 3. SPI W RITE所示,控制命令需要向左移一位(<<1);如写引脚控制状态命令0x06变为0x0c;后面数据如实际情况填写。
读命令:
命令格式为16位,前8位是命令,后八位写入数据;
命令如F IGURE 4. SPI R EAD所示,第一位数据为1,控制命令需要向左移一位(<<1);如读引脚状态命令0x00变为0x80;后面数据如实际情况填写。

命令字节寄存器描述读/写默认数值
0x00 0x01GSR -GPIO状态只读0xXX
0x02 0x03OCR – 输出控制读/写0xff
0x04 0x05PIR -输入极性反转读/写0x00
0x06 0x07GCR- GPIO 组态/构造读/写0xFF
0x08 0x09PUR-输入内部上拉电阻启用/禁用读/写0x00
0x0a 0x0bIER-输入中断使能读/写0x00
0x0c 0x0dTSCR - 输出三态控制读/写0x00
0x0e 0x0fISR -输入中断状态0x00
0x10 0x11REIR - 输入上升沿中断使能读/写0x00
0x12 0x13FEIR - 输入下降沿中断使能读/写0x00
0x14 0x15IFR - 输入滤波器启用/禁用读/写0xFF

5.程序
输出、输入、输入上拉等比较简单就直接按照指令操作即可,需要主要引脚状态要使用静态变量,否则下一次使用会覆盖上一次写入的内容。
下面的程序是引脚的配置,实现与主控芯片引脚一样的中断功能,使用的是rt-thread操作系统,其中会涉及到系统定义的相关的结构体和函数调用。
思路:创建一个中断表,把中断注册函数的内容写入表内,当发生中断时,IRQ#引脚低电平,使用主控芯片引脚中断进入扩展IO中断引脚的读取,进入扩展IO中断调用,查找中断引脚的中断服务函数进行调用。

struct rt_pin_irq_hdr ex_pin_irq_hdr_tab[] =   //中断表
{
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
    { -1, 0, RT_NULL, RT_NULL},
};
    /** \brief xra1403引脚中断注册函数
 * \param pin[in]     pin     引脚号200-215
 * \param mode[in]    mode    中断触发模式  上升沿触发,PIN_IRQ_MODE_RISING;下降沿触发,PIN_IRQ_MODE_FALLING;
 * \param hdr[in]     hdr     引脚中断服务函数
 * \param args[in]    args    传入数组参数
 * \return 错误代码: RT_EOK,成功;否则失败
 *
 */
rt_err_t vv_rt_ex_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,void (*hdr)(void *args), void  *args)
{
		static int io_irq_mode_rising_0 = 0x00;
		static int io_irq_mode_rising_1 = 0x00;
		static int io_irq_mode_falling_0 = 0x00;
		static int io_irq_mode_falling_1 = 0x00;
    rt_uint16_t gpio_pin;
    rt_int32_t irqindex = -1;
		attach_irq_pin[pin_cnt] = pin;
		pin_cnt++;
    gpio_pin = pin-200;
    irqindex = gpio_pin & 0x00FF;
    if (ex_pin_irq_hdr_tab[irqindex].pin == pin &&
        ex_pin_irq_hdr_tab[irqindex].hdr == hdr &&
        ex_pin_irq_hdr_tab[irqindex].mode == mode &&
        ex_pin_irq_hdr_tab[irqindex].args == args)
    {
        return RT_EOK;
    }
    if (ex_pin_irq_hdr_tab[irqindex].pin != -1)
    {
        return RT_EBUSY;
    }
    ex_pin_irq_hdr_tab[irqindex].pin = pin;
    ex_pin_irq_hdr_tab[irqindex].hdr = hdr;
    ex_pin_irq_hdr_tab[irqindex].mode = mode;
    ex_pin_irq_hdr_tab[irqindex].args = args;
		switch (ex_pin_irq_hdr_tab[irqindex].mode)
        {
        case PIN_IRQ_MODE_RISING:
		    if(199 < pin&&pin < 208){
						io_irq_mode_rising_0 = ex_pin_switch_mode(pin, XRA1403_REIR1, io_irq_mode_rising_0);
				}else if(207 < pin&&pin < 216){
						io_irq_mode_rising_0 = ex_pin_switch_mode(pin, XRA1403_REIR2, io_irq_mode_rising_1);
				}else __nop;
            break;
        case PIN_IRQ_MODE_FALLING:
            if(199 < pin&&pin < 208){
						io_irq_mode_falling_0 = ex_pin_switch_mode(pin, XRA1403_FEIR1, io_irq_mode_falling_0);
				}else if(207 < pin&&pin < 216){
						io_irq_mode_falling_1 = ex_pin_switch_mode(pin, XRA1403_FEIR2, io_irq_mode_falling_1);
				}else __nop;
            break;
        }
    return RT_EOK;
} 
/** \brief xra1403引脚中断读取
 *
 * \return IO_interrupt_pin 发生中断引脚号
 *
 */
int vv_rt_ex_pin_interrupt_read(void)
{
	int IO_interrupt_pin = 0;//发生中断的引脚
	int io_cmd1[2] = {XRA1403_ISR1};
	int io_cmd2[2] = {XRA1403_ISR2};
	int i;
	if(io_data_flag == 1){
		io_data_flag = 0;
		expander_gpio_control(&spi_expander_gpio_device.xra1403_parente,1,io_cmd2);
//		rt_kprintf("p1:%x\t\n",io_data);
		if(io_data == 0){
			expander_gpio_control(&spi_expander_gpio_device.xra1403_parente,1,io_cmd1);
//			rt_kprintf("p0:%x\t\n",io_data);
			if     (((io_data>>7)&0x01) ==1) IO_interrupt_pin=207;
			else if(((io_data>>6)&0x01) ==1) IO_interrupt_pin=206;
			else if(((io_data>>5)&0x01) ==1) IO_interrupt_pin=205;
			else if(((io_data>>4)&0x01) ==1) IO_interrupt_pin=204;
			else if(((io_data>>3)&0x01) ==1) IO_interrupt_pin=203;
			else if(((io_data>>2)&0x01) ==1) IO_interrupt_pin=202;
			else if(((io_data>>1)&0x01) ==1) IO_interrupt_pin=201;
			else if((io_data&0x01) == 1) IO_interrupt_pin=200;
			else __nop;			
		}else{
			if     (((io_data>>7)&0x01) ==1) IO_interrupt_pin=215;
			else if(((io_data>>6)&0x01) ==1) IO_interrupt_pin=214;
			else if(((io_data>>5)&0x01) ==1) IO_interrupt_pin=213;
			else if(((io_data>>4)&0x01) ==1) IO_interrupt_pin=212;
			else if(((io_data>>3)&0x01) ==1) IO_interrupt_pin=211;
			else if(((io_data>>2)&0x01) ==1) IO_interrupt_pin=210;
			else if(((io_data>>1)&0x01) ==1) IO_interrupt_pin=209;
			else if((io_data&0x01) == 1) IO_interrupt_pin=208;
			else __nop;
		}   			
	} 
	io_data_flag = 1;	
	for(i=0;i<pin_cnt;i++){
		  if(IO_interrupt_pin == attach_irq_pin[i] ){
				return IO_interrupt_pin;
			}
	}	
	return RT_ERROR;
} 
/** \brief xra1403引脚中断函数调用
 * \param pin[in]     pin     引脚号200-215
 *
 */
void vv_ex_pin_irq_hdr(uint16_t GPIO_Pin)
{
    int16_t ex_irqno;
	  ex_irqno=GPIO_Pin-200;
	if(0<=ex_irqno&&ex_irqno<=15){
    if (ex_pin_irq_hdr_tab[ex_irqno].hdr)
    {
        ex_pin_irq_hdr_tab[ex_irqno].hdr(ex_pin_irq_hdr_tab[ex_irqno].args);
    }
	}
}
/** \brief xra1403引脚中断函数检测调用
 * \param 无
 *
 */
void vv_ex_pin_irq_call(void)
{
	  int io_pin = 0;
		if(XRA1403_inter == 1){
						io_pin=vv_rt_ex_pin_interrupt_read();
//						rt_kprintf("%d\r\n",io_pin);
			      if(199 < io_pin&&io_pin < 216) vv_ex_pin_irq_hdr(io_pin);
						vv_rt_ex_pin_read(202);//清除IC中断标志
						vv_rt_ex_pin_read(208);//清除IC中断标志
						XRA1403_inter = 0;
				}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值