当前位置: 首页 > news >正文

BUG——GT911上电后中断一直触发

版型:正点原子 I.MX6UL  MINI板 

屏幕:7寸 1024*600  ATK-MD0700R V1.4

     我的建议是买7寸屏幕就不要Mini板,因为Mini板太小装不下7寸屏幕,你需要一个更大的板子

   简介:

     算是作为一个后来者对这一现象的补充。解决方案就是在中断开启前主动清零,详情可见本篇末尾,点击目录【总结】

        具体情形是,上电之后,本应不会触发中断,结果却一直疯跳,14s左右进入1400多次中断,与扫描频率100Hz相近。

 启发:

         看了一些博客,说0x814E这个寄存器没有清零,实际上是有清零这一步的。在测试中发现,上电后虽然中断会一直触发,但只要你在屏幕上乱摸一会儿,就可以正常了。不过这显然不是什么正经的解决方案。

void GT911_read_tpcoord(void)
{uint8_t buf[4];uint8_t regvalue = 0;regvalue = GT911_read_byte(GT911_ADDR, GT_GSTID_REG);GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);/*清零*/GT911_dev.point_num = regvalue & 0XF; /* 计算读取了多少个点 *//* 读取当前所有的触摸坐标值 */for (uint8_t i = 0; i < GT911_dev.point_num; ++i){GT911_read_len(GT911_ADDR, GT911_TPX_TBL[i], 4, buf); /* 读取坐标值 */GT911_dev.x[i] = ((u16)buf[1] << 8) + buf[0];GT911_dev.y[i] = (((u16)buf[3] << 8) + buf[2]);}
}volatile static uint32_t count = 0;
void GT911_irqhandler(void)
{gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */if (GT911_dev.initfalg == GT911_INIT_FINISHED){GT911_dev.intflag = 1;GT911_read_tpcoord();printf("%d\r\n", GT911_dev.point_num);for (uint8_t i = 0; i < GT911_dev.point_num; ++i){printf("X%d:%d  Y%d: %d\r\n", i, GT911_dev.x[i], i, GT911_dev.y[i]);}printf("\r\n");}printf("Interrupt:%d---------------------\r\n", ++count);
}

 尝试:

        看情形,觉得是清零不到位,于是在中断前面加了一个清零步骤,就有了双倍清零效果

volatile static uint32_t count = 0;
void GT911_irqhandler(void)
{gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);/*清零*/if (GT911_dev.initfalg == GT911_INIT_FINISHED){GT911_dev.intflag = 1;GT911_read_tpcoord();printf("%d\r\n", GT911_dev.point_num);for (uint8_t i = 0; i < GT911_dev.point_num; ++i){printf("X%d:%d  Y%d: %d\r\n", i, GT911_dev.x[i], i, GT911_dev.y[i]);}printf("\r\n");}printf("Interrupt:%d---------------------\r\n", ++count);
}

        结果居然真的停了,重启过几次,发现都是11次,没有变。

    为此,我就在结构体里面多添加了一个成员,专门用于清零计数。中断里面添加了个分支,用于判断是否清零了11次(不同的芯片、板子可能不同)。虽然可行,但终究多了一步,感觉有些浪费

struct GT911_dev_struct
{uint16_t x[5];     /* X轴坐标 	*/uint16_t y[5];     /* Y轴坐标 	*/uint8_t initfalg;  /* 触摸屏初始化状态 */uint8_t intflag;   /* 标记中断有没有发生 */uint8_t point_num; /* 触摸点 		*/uint8_t init_clear;
};/*--------------------中断处理函数---------------------------/void GT911_irqhandler(void)
{if (GT911_dev.init_clear < 12){GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);++GT911_dev.init_clear;}else{if (GT911_dev.initfalg == GT911_INIT_FINISHED){GT911_dev.intflag = 1;GT911_read_tpcoord();printf("%d\r\n", GT911_dev.point_num);for (uint8_t i = 0; i < GT911_dev.point_num; ++i){printf("X%d:%d  Y%d: %d\r\n", i, GT911_dev.x[i], i, GT911_dev.y[i]);}printf("\r\n");}}gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */printf("Interrupt:%d---------------------\r\n", ++count);
}

         于是就想着,在GT911中断开启之后,板子中断开启之前对芯片清零,于是初始化代码变成了

    delay_ms(10);GT911_write_byte(GT911_ADDR, GT911_Command_Reg, 0);/*----------------中断前清零--------------------*/for (uint16_t i = 0; i < 15; i++){GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);printf("Clear:%d---------------------\r\n", i);}
/*----------------中断前清零--------------------*/GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);                                                                                   /* 使能GIC中对应的中断 */system_register_irqhandler(GPIO1_Combined_0_15_IRQn, (system_irq_handler_t)GT911_irqhandler, NULL); /* 注册中断服务函数 */ // 放在前面,不然gpio_enableint(GPIO1, 9);delay_ms(100);GT911_dev.initfalg = GT911_INIT_FINISHED;
done:delay_ms(10);

         结果没什么效果,不过转念一想中断里面是双倍清零,问题可能就出在了这里

 于是发生了下面这一幕,虽然有效,但又不完全有。

 

         本着闲着也是闲着,后面就测试了多种情况

/*----------------中断前清零--------------------*/for (uint16_t i = 0; i < 15; i++){GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);printf("Clear:%d---------------------\r\n", i);}
/*----------------中断前清零--------------------*/

 :把for循环里的printf去掉

        清零足足600次,才能清掉

:添加延时

        延时1ms,清零80次左右,可以正常清掉。进一步测试发现,延时越长所需清零次数越少。不过延时越少也意味着所耗费的时间越长,延时10ms与在中断里面清零的效果差不多,再往上20ms、50ms差距就不大了,都能在10次以内清零。50ms与100ms效果相同,达到500ms效果反而差了些,后面就没继续测了。

总结:

         中断开启前,以10ms左右的延时清零8次左右即可解决问题,当然具体情况具体讨论,在这个参考上调整一下。

    for (uint16_t i = 0; i < 8; i++){delay_ms(10);GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);}

        源码在下面,都是在正点原子代码的基础上微调一下

 Touch.h源码

#ifndef __BSP_TOUCH_H
#define __BSP_TOUCH_H
#include "imx6ul.h"
/* 触摸屏结构体 */
struct GT911_dev_struct
{uint16_t x[5];     /* X轴坐标 	*/uint16_t y[5];     /* Y轴坐标 	*/uint8_t initfalg;  /* 触摸屏初始化状态 */uint8_t intflag;   /* 标记中断有没有发生 */uint8_t point_num; /* 触摸点 		*/uint8_t init_clear;
};extern struct GT911_dev_struct GT911_dev;void touch_init(void);
void GT911_read_tpcoord(void);#endif // !__BSP_TOUCH_H

Touch.c源码

#include "bsp_touch.h"
#include "bsp_gpio.h"
#include "delay.h"
#include "bsp_i2c.h"
#include "myDebug.h"
#include "bsp_int.h"#define GT911_ADDR 0x28 // 0xBA/*GT911寄存器*/
// W
// 0:读坐标状态 1:差值原始值 2:软件复位3:基准更新(内部测试) 4:基准校准(内部测试) 5 : 关屏其余值无效
#define GT911_Command_Reg 0x8040// R/W
#define GT911_Config_Version_Reg 0x8047
#define GT911_XL_Reg 0x8048
#define GT911_YL_Reg 0x8049
#define GT911_YH_Reg 0x804A
#define GT911_Touch_Number_Reg 0x804C
#define GT911_Module_Switch1_Reg 0x804D
#define GT911_Module_Switch2_Reg 0x804E
#define GT911_Shake_Count_Reg 0x804F // 手指按下/松开去抖次数
#define GT911_Filter_Reg 0x8050
#define GT911_Large_Touch_Reg 0x8051
#define GT911_Noise_Reduction_Reg 0x8052 // 噪声消除值(系数为 1,0-15 有效)#define GT911_Screen_Touch_Level_Reg 0x8053 // bit 7-0 屏上触摸点从无到有的阈值
#define GT911_Screen_Leave_Level_Reg 0x8054 // bit 7-0 屏上触摸点从有到无的阈值
#define GT911_Low_Power_Control_Reg 0x8055  // bit 3-0 进低功耗时间(0~15s)#define GT_PID_REG 0x8140
#define GT911_ID1_Reg 0x8140
#define GT911_ID2_Reg 0x8141
#define GT911_ID3_Reg 0x8142
#define GT911_ID4_Reg 0x8143#define GT_GSTID_REG 0X814E /* GT911当前检测到的触摸情况 */
#define GT_TP1_REG 0X8150   /* 第一个触摸点数据地址 */
#define GT_TP2_REG 0X8158   /* 第二个触摸点数据地址 */
#define GT_TP3_REG 0X8160   /* 第三个触摸点数据地址 */
#define GT_TP4_REG 0X8168   /* 第四个触摸点数据地址  */
#define GT_TP5_REG 0X8170   /* 第五个触摸点数据地址   */#define GT911_XYCOORDREG_NUM 30  /* 触摸点坐标寄存器数量 */
#define GT911_INIT_FINISHED 1    /* 触摸屏初始化完成 			*/
#define GT911_INIT_NOTFINISHED 0 /* 触摸屏初始化未完成 			*/// GT911模块开关寄存器
// bit 5-4  Stretch_rank
// bit 3    X2Y(X,Y坐标交换)// bit 1-0 INT输出极性选择
#define GT911_Module_Switch1_INT_RisingEdge 0x00
#define GT911_Module_Switch1_INT_FallingEdge 0x01
#define GT911_Module_Switch1_INT_LowLevel 0x02
#define GT911_Module_Switch1_INT_HighLevel 0x03void GT911_irqhandler(void);
uint8_t GT911_read_byte(uint8_t addr, uint32_t reg);
uint8_t GT911_write_byte(uint8_t addr, uint32_t reg, uint8_t data);
void GT911_write_len(uint8_t addr, uint32_t reg, uint32_t len, uint8_t *buf);
void GT911_read_len(uint8_t addr, uint32_t reg, uint32_t len, uint8_t *buf);/*变量定义*/
struct GT911_dev_struct GT911_dev;/*触摸屏初始化*/
void touch_init(void)
{IOMUXC_InitTypeDef iomuxc_init = {0};iomuxc_init.SPEED = IOMUXC_SPEED_MEDIUM;iomuxc_init.SRE = IOMUXC_SRE_Fast_Slew_Rate;iomuxc_init.DSE = IOMUXC_DSE_R0_6;iomuxc_init.HYS = IOMUXC_HYS_Enable;iomuxc_init.SION = IOMUXC_SION_Disable;IOMUXC_InitPin(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09, &iomuxc_init); // CT_RSTIOMUXC_InitPin(IOMUXC_GPIO1_IO09_GPIO1_IO09, &iomuxc_init);        // CT_INTiomuxc_init.PULL = IOMUXC_PULL_PUS_47K_UP | IOMUXC_PULL_PKE_Keeper_Enable | IOMUXC_PULL_PUE_Pull;iomuxc_init.HYS = IOMUXC_HYS_Disable;iomuxc_init.SION = IOMUXC_SION_Enable;IOMUXC_InitPin(IOMUXC_UART5_TX_DATA_I2C2_SCL, &iomuxc_init);IOMUXC_InitPin(IOMUXC_UART5_RX_DATA_I2C2_SDA, &iomuxc_init);GPIO_InitTypeDef gpio_init = {0};gpio_init.Pin = GPIO_PIN_9;gpio_init.Direction = GPIO_DIR_Output;gpio_init.Output = GPIO_OUTPUT_High;// CT_INTGPIO_Init(GPIO1, &gpio_init);// CT_RSTGPIO_Init(GPIO5, &gpio_init);i2c_init(I2C2);// 0xBA设备地址的复位// GPIO_ClearPin(GPIO5, GPIO_PIN_9);// GPIO_ClearPin(GPIO1, GPIO_PIN_9);// delay_ms(10);                   // 大于100us即可// GPIO_SetPin(GPIO5, GPIO_PIN_9); // 停止复位// delay_ms(100);                  // 大于5ms即可GPIO_ClearPin(GPIO5, GPIO_PIN_9);delay_ms(10);GPIO_SetPin(GPIO5, GPIO_PIN_9); // 停止复位delay_ms(10);GPIO_ClearPin(GPIO1, GPIO_PIN_9); /* 拉低INT引脚 */delay_ms(100);/***********GT911内部配置初始化**************/GT911_dev.initfalg = GT911_INIT_NOTFINISHED;GT911_dev.point_num = 0;GT911_dev.init_clear = 0;for (uint8_t i = 0; i < 5; ++i){ /* 避免编译器自动赋值 */GT911_dev.x[i] = 0;GT911_dev.y[i] = 0;}volatile uint8_t temp[7];                                   // 一不留神就被编译器优化死了GT911_read_len(GT911_ADDR, GT_PID_REG, 6, (uint8_t *)temp); /* 读取产品ID */temp[6] = temp[4];temp[4] = 0;printf("CTP ID:%s\r\n", temp);                             /* 打印ID */printf("Default Ver:%#x\r\n", ((temp[5] << 8) | temp[6])); /* 打印固件版本 *//* 重新设置中断IO,配置为中断功能 */IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09, 0x0080);gpio_init.Direction = GPIO_DIR_Input;gpio_init.InterruptMode = GPIO_INT_RisingEdge;gpio_init.Output = GPIO_OUTPUT_Low;if (temp[0] != 0x31){temp[0] = GT911_read_byte(GT911_ADDR, 0x804D) & 0x3; /* 获取中断模式 */printf("9xx\r\n");}else{temp[0] = GT911_read_byte(GT911_ADDR, 0x8056) & 0x3;}switch (temp[0]){case 0x0:printf("InterruptMode:IntRisingEdge\r\n");gpio_init.InterruptMode = GPIO_INT_RisingEdge;break;case 0x1:printf("InterruptMode:IntFallingEdge\r\n");gpio_init.InterruptMode = GPIO_INT_FallingEdge;break;case 0x2:printf("InterruptMode:IntLowLevel\r\n");gpio_init.InterruptMode = GPIO_INT_Low;break;case 0x3:printf("InterruptMode:IntHighLevel\r\n");gpio_init.InterruptMode = GPIO_INT_High;break;default:printf("InterruptMode: Error\r\n");gpio_init.InterruptMode = GPIO_INT_BothEdge;break;}GPIO_Init(GPIO1, &gpio_init);if (GT911_write_byte(GT911_ADDR, GT911_Command_Reg, 0x2)){GT911_dev.initfalg = GT911_INIT_NOTFINISHED;goto done;}delay_ms(10);GT911_write_byte(GT911_ADDR, GT911_Command_Reg, 0);for (uint16_t i = 0; i < 8; i++){delay_ms(10);GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);// printf("Clear:%d---------------------\r\n", i);}GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);                                                                                   /* 使能GIC中对应的中断 */system_register_irqhandler(GPIO1_Combined_0_15_IRQn, (system_irq_handler_t)GT911_irqhandler, NULL); /* 注册中断服务函数 */ // 放在前面,不然gpio_enableint(GPIO1, 9);delay_ms(100);GT911_dev.initfalg = GT911_INIT_FINISHED;
done:delay_ms(10);
}/** @description			: GPIO1_IO9最终的中断处理函数* @param				: 无* @return 				: 无*/
volatile static uint32_t count = 0;
void GT911_irqhandler(void)
{gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */// printf("Interrupt:%d---------------------\r\n", ++count);if (GT911_dev.init_state == GT911_INIT_FINISHED){GT911_read_tpcoord();if (GT911_dev.point_num)GT911_dev.int_flag = 1;// printf("%d\r\n", GT911_dev.point_num);// for (uint8_t i = 0; i < GT911_dev.point_num; ++i)// {//     printf("X%d:%d  Y%d: %d\r\n", i, GT911_dev.x[i], i, GT911_dev.y[i]);// }// printf("\r\n");}
}/** @description	: 向GT911写入数据* @param - addr: 设备地址* @param - reg : 要写入的寄存器* @param - data: 要写入的数据* @return 		: 操作结果*/
uint8_t GT911_write_byte(uint8_t addr, uint32_t reg, uint8_t data)
{uint8_t status = 0;uint8_t writedata = data;struct i2c_transfer masterXfer;/* 配置I2C xfer结构体 */masterXfer.slaveAddress = addr;    /* 设备地址 				*/masterXfer.direction = kI2C_Write; /* 写入数据 				*/masterXfer.subaddress = reg;       /* 要写入的寄存器地址 			*/masterXfer.subaddressSize = 2;     /* 地址长度一个字节 			*/masterXfer.data = &writedata;      /* 要写入的数据 				*/masterXfer.dataSize = 1;           /* 写入数据长度1个字节			*/if (i2c_master_transfer(I2C2, &masterXfer))status = 1;return status;
}/** @description	: 从GT911读取一个字节的数据* @param - addr: 设备地址* @param - reg : 要读取的寄存器* @return 		: 读取到的数据。*/
uint8_t GT911_read_byte(uint8_t addr, uint32_t reg)
{uint8_t val = 0;struct i2c_transfer masterXfer;masterXfer.slaveAddress = addr;   /* 设备地址 				*/masterXfer.direction = kI2C_Read; /* 读取数据 				*/masterXfer.subaddress = reg;      /* 要读取的寄存器地址 			*/masterXfer.subaddressSize = 2;    /* 地址长度一个字节 			*/masterXfer.data = &val;           /* 接收数据缓冲区 				*/masterXfer.dataSize = 1;          /* 读取数据长度1个字节			*/i2c_master_transfer(I2C2, &masterXfer);return val;
}/** @description	: 从GT911读取多个字节的数据* @param - addr: 设备地址* @param - reg : 要读取的开始寄存器地址* @param - len : 要读取的数据长度.* @param - buf : 读取到的数据缓冲区* @return 		: 无*/
void GT911_read_len(uint8_t addr, uint32_t reg, uint32_t len, uint8_t *buf)
{struct i2c_transfer masterXfer;masterXfer.slaveAddress = addr;   /* 设备地址 				*/masterXfer.direction = kI2C_Read; /* 读取数据 				*/masterXfer.subaddress = reg;      /* 要读取的寄存器地址 			*/masterXfer.subaddressSize = 2;    /* 地址长度一个字节 			*/masterXfer.data = buf;            /* 接收数据缓冲区 				*/masterXfer.dataSize = len;        /* 读取数据长度1个字节			*/i2c_master_transfer(I2C2, &masterXfer);
}/** @description	: 向GT911多个寄存器写入数据* @param - addr: 设备地址* @param - reg : 要写入的开始寄存器地址* @param - len : 要写入的数据长度.* @param - buf : 写入到的数据缓冲区* @return 		: 无*/
void GT911_write_len(uint8_t addr, uint32_t reg, uint32_t len, uint8_t *buf)
{struct i2c_transfer masterXfer;masterXfer.slaveAddress = addr;    /* 设备地址         */masterXfer.direction = kI2C_Write; /* 读取数据 	    */masterXfer.subaddress = reg;       /* 要读取的寄存器地址 */masterXfer.subaddressSize = 2;     /* 地址长度一个字节     */masterXfer.data = buf;             /* 接收数据缓冲区 	    */masterXfer.dataSize = len;         /* 读取数据长度1个字节  */i2c_master_transfer(I2C2, &masterXfer);
}const uint16_t GT911_TPX_TBL[5] = {GT_TP1_REG, GT_TP2_REG, GT_TP3_REG, GT_TP4_REG, GT_TP5_REG};
/** @description	: 读取当前所有触摸点的坐标* @param 		: 无* @return 		: 无*/
void GT911_read_tpcoord(void)
{uint8_t buf[4];uint8_t regvalue = 0;regvalue = GT911_read_byte(GT911_ADDR, GT_GSTID_REG);GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);GT911_dev.point_num = regvalue & 0XF; /* 计算读取了多少个点 *//* 读取当前所有的触摸坐标值 */for (uint8_t i = 0; i < GT911_dev.point_num; ++i){GT911_read_len(GT911_ADDR, GT911_TPX_TBL[i], 4, buf); /* 读取坐标值 */GT911_dev.x[i] = ((u16)buf[1] << 8) + buf[0];GT911_dev.y[i] = (((u16)buf[3] << 8) + buf[2]);}
}

iomuxc.h

#ifndef __BSP_IOMUX_H
#define __BSP_IOMUX_H
#include "fsl_iomuxc.h"// 用于简化寄存器位域的配置
#define configBits(data, bits, pos) ((data & bits) << pos)
#define ConfigBits(data, pos) (data << pos)// 迟滞功能
#define IOMUXC_HYS_POS 16
#define IOMUXC_HYS_BITS 0x1
#define IOMUXC_HYS_Disable 0x0
#define IOMUXC_HYS_Enable 0x1// 上拉/下拉功能
#define IOMUXC_PULL_POS 12
#define IOMUXC_PULL_BITS 0xF
#define IOMUXC_PULL_PUS_100K_DOWN 0x0 // 上下拉电阻配置
#define IOMUXC_PULL_PUS_47K_UP 0x4
#define IOMUXC_PULL_PUS_100K_UP 0x8
#define IOMUXC_PULL_PUS_22K_UP 0xC
#define IOMUXC_PULL_PUE_Keeper 0x0         // bit 13
#define IOMUXC_PULL_PUE_Pull 0x2           // bit 13
#define IOMUXC_PULL_PKE_Keeper_Disable 0x0 // bit 12
#define IOMUXC_PULL_PKE_Keeper_Enable 0x1  // bit 12// 开漏功能
#define IOMUXC_ODE_POS 11
#define IOMUXC_ODE_BITS 0x1
#define IOMUXC_ODE_Disable 0x0
#define IOMUXC_ODE_Enable 0x1// 速度功能
#define IOMUXC_SPEED_POS 6
#define IOMUXC_SPEED_BITS 0x3
#define IOMUXC_SPEED_LOW 0x0 // 速度配置官方手册比较模糊,就凑合配了一下
#define IOMUXC_SPEED_LOWPlus 0x1
#define IOMUXC_SPEED_MEDIUM 0x2
#define IOMUXC_SPEED_HIGH 0x3// 驱动强度功能
#define IOMUXC_DSE_POS 3
#define IOMUXC_DSE_BITS 0x7
#define IOMUXC_DSE_Output_Driver_Disable 0x0
#define IOMUXC_DSE_R0_260Ohm 0x1
#define IOMUXC_DSE_R0_2 0x2 // R0/2
#define IOMUXC_DSE_R0_3 0x3
#define IOMUXC_DSE_R0_4 0x4
#define IOMUXC_DSE_R0_5 0x5
#define IOMUXC_DSE_R0_6 0x6
#define IOMUXC_DSE_R0_7 0x7// 转换速率功能
#define IOMUXC_SRE_POS 0
#define IOMUXC_SRE_BITS 0x1
#define IOMUXC_SRE_Slow_Slew_Rate 0x0
#define IOMUXC_SRE_Fast_Slew_Rate 0x1// 复用功能
#define IOMUXC_MUX_MODE_POS 0
#define IOMUXC_MUX_MODE_BITS 0x7
#define IOMUXC_ALT_0 0x0
#define IOMUXC_ALT_1 0x1
#define IOMUXC_ALT_2 0x2
#define IOMUXC_ALT_3 0x3
#define IOMUXC_ALT_4 0x4
#define IOMUXC_ALT_5 0x5
#define IOMUXC_ALT_6 0x6
#define IOMUXC_ALT_7 0x7
#define IOMUXC_ALT_8 0x8// 软件输入功能
#define IOMUXC_SION_POS 4
#define IOMUXC_SION_BITS 0x1
#define IOMUXC_SION_Disable 0x0 // 输入路径由功能决定
#define IOMUXC_SION_Enable 0x1  // 强制输入路径typedef struct
{uint8_t PULL : 4;  // 上拉/下拉uint8_t DSE : 3;   // 驱动强度uint8_t HYS : 1;   // 迟滞uint8_t SPEED : 2; // 速度uint8_t ODE : 1;   // 开漏uint8_t SRE : 1;   // 转换速率uint8_t SION : 1;  // 软件输入
} IOMUXC_InitTypeDef;void IOMUXC_InitPin(uint32_t muxRegister,uint32_t muxMode,uint32_t inputRegister,uint32_t inputDaisy,uint32_t configRegister,IOMUXC_InitTypeDef *IOMUXC_ConfigStruct);#endif // !__BSP_IOMUX_H

iomuxc.c

#include "iomuxc.h"
void IOMUXC_InitPin(uint32_t muxRegister,uint32_t muxMode,uint32_t inputRegister,uint32_t inputDaisy,uint32_t configRegister,IOMUXC_InitTypeDef *IOMUXC_ConfigStruct)
{*((volatile uint32_t *)muxRegister) = configBits(muxMode, IOMUXC_MUX_MODE_BITS, IOMUXC_MUX_MODE_POS) |configBits(IOMUXC_ConfigStruct->SION, IOMUXC_SION_BITS, IOMUXC_SION_POS);if (inputRegister){*((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy);}if (configRegister){*((volatile uint32_t *)configRegister) = configBits(IOMUXC_ConfigStruct->DSE, IOMUXC_DSE_BITS, IOMUXC_DSE_POS) |configBits(IOMUXC_ConfigStruct->HYS, IOMUXC_HYS_BITS, IOMUXC_HYS_POS) |configBits(IOMUXC_ConfigStruct->ODE, IOMUXC_ODE_BITS, IOMUXC_ODE_POS) |configBits(IOMUXC_ConfigStruct->PULL, IOMUXC_PULL_BITS, IOMUXC_PULL_POS) |configBits(IOMUXC_ConfigStruct->SPEED, IOMUXC_SPEED_BITS, IOMUXC_SPEED_POS) |configBits(IOMUXC_ConfigStruct->SRE, IOMUXC_SRE_BITS, IOMUXC_SRE_POS);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • RK3588——网口实时传输视频
  • 什么是深拷贝
  • ubuntu20 vmware硬盘空间不够,进行扩容,实操成功!
  • 通俗易懂 serverless 架构、微服务架构和云原生架构,并简单代码
  • UltraISO制作Centos7.X系统U盘启动
  • 2024年入职/转行网络安全,该如何规划?_网络安全职业规划
  • Docker的介绍、保姆级安装和使用
  • 数据库学习(进阶)
  • LoginFormDTO
  • iOS18 Beta7 最终测试版推送:苹果的又一次技术飞跃
  • HTTP 之 HTTP/1.0、HTTP/1.1和HTTP2的缓存策略(六)
  • [数据集][目标检测]起子检测数据集VOC+YOLO格式1215张1类别
  • 在Excel中“直接引用”字符串地址
  • 【实战教程】用scikit-learn玩转KNN:鸢尾花数据集的分类之旅
  • leetcode371. 两整数之和,位运算
  • ----------
  • 2017-09-12 前端日报
  • C# 免费离线人脸识别 2.0 Demo
  • exports和module.exports
  • golang 发送GET和POST示例
  • Java 内存分配及垃圾回收机制初探
  • jquery cookie
  • k8s 面向应用开发者的基础命令
  • Netty源码解析1-Buffer
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • quasar-framework cnodejs社区
  • rc-form之最单纯情况
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • vue-router 实现分析
  • 官方解决所有 npm 全局安装权限问题
  • 前端知识点整理(待续)
  • 移动端唤起键盘时取消position:fixed定位
  • 正则表达式小结
  • puppet连载22:define用法
  • ​插件化DPI在商用WIFI中的价值
  • #define 用法
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (黑马C++)L06 重载与继承
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (四)js前端开发中设计模式之工厂方法模式
  • (一)为什么要选择C++
  • (转载)OpenStack Hacker养成指南
  • .NET Standard 的管理策略
  • .NET 反射的使用
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net的socket示例
  • .net和php怎么连接,php和apache之间如何连接
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • @Data注解的作用
  • @RestControllerAdvice异常统一处理类失效原因
  • [20171102]视图v$session中process字段含义
  • [AIGC] Spring Interceptor 拦截器详解