版型:正点原子 I.MX6UL MINI板
屏幕:7寸 1024*600 ATK-MD0700R V1.4
我的建议是买7寸屏幕就不要Mini板,因为Mini板太小装不下7寸屏幕,你需要一个更大的板子
简介:
算是作为一个后来者对这一现象的补充。解决方案就是在中断开启前主动清零,详情可见本篇末尾。
具体情形是,上电之后,本应不会触发中断,结果却一直疯跳,14s左右进入1400多次中断,与扫描频率100Hz相近。
启发:
看了一些博客,说0x814E这个寄存器没有清零,实际上是有清零这一步的。在测试中发现,上电后虽然中断会一直触发,但只要你在屏幕上乱摸一会儿,就可以正常了。不过这显然不是什么正经的解决方案。
cpp
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);
}
尝试:
看情形,觉得是清零不到位,于是在中断前面加了一个清零步骤,就有了双倍清零效果
cpp
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次(不同的芯片、板子可能不同)。虽然可行,但终究多了一步,感觉有些浪费
cpp
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中断开启之后,板子中断开启之前对芯片清零,于是初始化代码变成了
cpp
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);
结果没什么效果,不过转念一想中断里面是双倍清零,问题可能就出在了这里
于是发生了下面这一幕,虽然有效,但又不完全有。
本着闲着也是闲着,后面就测试了多种情况
cpp
/*----------------中断前清零--------------------*/
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次左右即可解决问题,当然具体情况具体讨论,在这个参考上调整一下。
cpp
for (uint16_t i = 0; i < 8; i++)
{
delay_ms(10);
GT911_write_byte(GT911_ADDR, GT_GSTID_REG, 0x00);
}
源码在下面,都是在正点原子代码的基础上微调一下
Touch.h源码
cpp
#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源码
cpp
#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 0x03
void 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_RST
IOMUXC_InitPin(IOMUXC_GPIO1_IO09_GPIO1_IO09, &iomuxc_init); // CT_INT
iomuxc_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_INT
GPIO_Init(GPIO1, &gpio_init);
// CT_RST
GPIO_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
cpp
#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
cpp
#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);
}
}