Драйвер STMicro STMTouch Использование 5-канальной конструкции моно электродов для решения проблем линейного датчика
Я работаю с пользовательской платой, которая имеет 8 каналов, состоящих из трех сенсорных кнопок и 1 линейного датчика.
Есть 8 каналов ввода-вывода, три дискретных ввода-вывода и нет настроек экрана. Три канала предназначены для трех сенсорных клавиш. Пять каналов предназначены для линейного датчика.
Я работал с платой STM3270B Discovery, где она имеет три канала, настроенных на конструкцию с половинным концом электрода (LIN_H). Я работал с примером, предоставленным этой платой для реализации без прерываний.
Я работал с платой STM3207 Eval, в которой два канала настроены как две сенсорные клавиши.
На моей заказной доске сенсорные клавиши работают без нареканий. Пятиканальный линейный датчик не работает полностью. Все пять пэдов действительно обнаруживают прикосновение, но с точки зрения положения данных оно терпит неудачу. В примере все ios находятся в одном канале. Я не знаю ни одного примера, который бы использовал 5 каналов, разделенных на две группы TSC. Он упоминается в Руководстве пользователя драйвера STMTouch, но мне придется еще раз поискать пример кода.
Проблема в том, что макрос, который определяет значение датчика LINEAR_POSITION = MyLinRots[0].p_Data->Position, имеет два результата. При касании любой из двух площадок, связанных с IO группы 1, макрос DETECT срабатывает правильно, но значение LINEAR_POSITION равно 0x2. Аналогично, если трогать три пэда, связанные с IOS группы 2, макрос DETECT срабатывает правильно, но значение LINEAR_POSITION равно 0xC.
Я думал, что значение будет варьироваться от 0 до 255 разделить 5 способов для каждого пэда. Я посмотрел на исходную позицию вместо масштабированной, но она ведет себя аналогично.
Вот мое расположение каналов, банков, сенсорных клавиш, линейных / поворотных и объектов, разделенных на файл заголовка и исходный файл.
Заголовок:
/* Channel IOs definition */
// The three touchkey channels
#define CHANNEL_0_IO_MSK (TSC_GROUP6_IO2)
#define CHANNEL_0_GRP_MSK (TSC_GROUP6)
#define CHANNEL_0_SRC (TSC_GROUP6_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_0_DEST (0) /* Index in destination result array */
#define CHANNEL_1_IO_MSK (TSC_GROUP6_IO3)
#define CHANNEL_1_GRP_MSK (TSC_GROUP6)
#define CHANNEL_1_SRC (TSC_GROUP6_IDX)
#define CHANNEL_1_DEST (1)
#define CHANNEL_2_IO_MSK (TSC_GROUP6_IO4)
#define CHANNEL_2_GRP_MSK (TSC_GROUP6)
#define CHANNEL_2_SRC (TSC_GROUP6_IDX)
#define CHANNEL_2_DEST (2)
// The five linrot channels
#define CHANNEL_3_IO_MSK (TSC_GROUP1_IO3)
#define CHANNEL_3_GRP_MSK (TSC_GROUP1)
#define CHANNEL_3_SRC (TSC_GROUP1_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_3_DEST (3) /* Index in destination result array */
#define CHANNEL_4_IO_MSK (TSC_GROUP1_IO4)
#define CHANNEL_4_GRP_MSK (TSC_GROUP1)
#define CHANNEL_4_SRC (TSC_GROUP1_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_4_DEST (4) /* Index in destination result array */
#define CHANNEL_5_IO_MSK (TSC_GROUP2_IO2)
#define CHANNEL_5_GRP_MSK (TSC_GROUP2)
#define CHANNEL_5_SRC (TSC_GROUP2_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_5_DEST (5) /* Index in destination result array */
#define CHANNEL_6_IO_MSK (TSC_GROUP2_IO3)
#define CHANNEL_6_GRP_MSK (TSC_GROUP2)
#define CHANNEL_6_SRC (TSC_GROUP2_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_6_DEST (6) /* Index in destination result array */
#define CHANNEL_7_IO_MSK (TSC_GROUP2_IO4)
#define CHANNEL_7_GRP_MSK (TSC_GROUP2)
#define CHANNEL_7_SRC (TSC_GROUP2_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_7_DEST (7) /* Index in destination result array */
/* Shield IOs definition */
#define SHIELD_IO_MSK (0) // orig (TSC_GROUP7_IO3) we dont have a shield
/* Banks definition */
// The touch key bank
#define BANK_0_NBCHANNELS (1)
#define BANK_0_MSK_CHANNELS (CHANNEL_0_IO_MSK | SHIELD_IO_MSK)
#define BANK_0_MSK_GROUPS (CHANNEL_0_GRP_MSK)
#define BANK_1_NBCHANNELS (1)
#define BANK_1_MSK_CHANNELS (CHANNEL_1_IO_MSK | SHIELD_IO_MSK)
#define BANK_1_MSK_GROUPS (CHANNEL_1_GRP_MSK)
#define BANK_2_NBCHANNELS (1)
#define BANK_2_MSK_CHANNELS (CHANNEL_2_IO_MSK | SHIELD_IO_MSK)
#define BANK_2_MSK_GROUPS (CHANNEL_2_GRP_MSK)
// The linrot bank
#define BANK_3_NBCHANNELS (5)
#define BANK_3_MSK_CHANNELS (CHANNEL_3_IO_MSK | CHANNEL_4_IO_MSK | CHANNEL_5_IO_MSK | CHANNEL_6_IO_MSK| CHANNEL_7_IO_MSK | SHIELD_IO_MSK)
#define BANK_3_MSK_GROUPS (CHANNEL_3_GRP_MSK | CHANNEL_4_GRP_MSK | CHANNEL_5_GRP_MSK | CHANNEL_6_GRP_MSK | CHANNEL_7_GRP_MSK )
Исходный файл с настройками определений
/* define for the linear */
#define LINEAR_DETECT ((MyLinRots[0].p_Data->StateId == TSL_STATEID_DETECT) || \
(MyLinRots[0].p_Data->StateId == TSL_STATEID_DEB_RELEASE_DETECT))
#define LINEAR_POSITION (MyLinRots[0].p_Data->Position)
/*============================================================================*/
/* Channels */
/*============================================================================*/
/* Source and Configuration (ROM) */
CONST TSL_ChannelSrc_T MyChannels_Src[TSLPRM_TOTAL_CHANNELS] = {
// The three touchkey channels
{ CHANNEL_0_SRC, CHANNEL_0_IO_MSK, CHANNEL_0_GRP_MSK },
{ CHANNEL_1_SRC, CHANNEL_1_IO_MSK, CHANNEL_1_GRP_MSK },
{ CHANNEL_2_SRC, CHANNEL_2_IO_MSK, CHANNEL_2_GRP_MSK },
// The five linrot channels
{ CHANNEL_3_SRC, CHANNEL_3_IO_MSK, CHANNEL_3_GRP_MSK },
{ CHANNEL_4_SRC, CHANNEL_4_IO_MSK, CHANNEL_4_GRP_MSK },
{ CHANNEL_5_SRC, CHANNEL_5_IO_MSK, CHANNEL_5_GRP_MSK },
{ CHANNEL_6_SRC, CHANNEL_6_IO_MSK, CHANNEL_6_GRP_MSK },
{ CHANNEL_7_SRC, CHANNEL_7_IO_MSK, CHANNEL_7_GRP_MSK }
};
/* Destination (ROM) */
CONST TSL_ChannelDest_T MyChannels_Dest[TSLPRM_TOTAL_CHANNELS] = {
// The three touchkey channels
{ CHANNEL_0_DEST },
{ CHANNEL_1_DEST },
{ CHANNEL_2_DEST },
// The five linrot channels
{ CHANNEL_3_DEST },
{ CHANNEL_4_DEST },
{ CHANNEL_5_DEST },
{ CHANNEL_6_DEST },
{ CHANNEL_7_DEST },
};
/* Data (RAM) */
TSL_ChannelData_T MyChannels_Data[TSLPRM_TOTAL_CHANNELS];
/*============================================================================*/
/* Banks */
/*============================================================================*/
/* List (ROM) */
CONST TSL_Bank_T MyBanks[TSLPRM_TOTAL_BANKS] = {
// The three touchkey bankss
{&MyChannels_Src[0], &MyChannels_Dest[0], MyChannels_Data, BANK_0_NBCHANNELS, BANK_0_MSK_CHANNELS, BANK_0_MSK_GROUPS},
{&MyChannels_Src[1], &MyChannels_Dest[1], MyChannels_Data, BANK_1_NBCHANNELS, BANK_1_MSK_CHANNELS, BANK_1_MSK_GROUPS},
{&MyChannels_Src[2], &MyChannels_Dest[2], MyChannels_Data, BANK_2_NBCHANNELS, BANK_2_MSK_CHANNELS, BANK_2_MSK_GROUPS},
// The one linrot bank
{&MyChannels_Src[3], &MyChannels_Dest[3], MyChannels_Data, BANK_3_NBCHANNELS, BANK_3_MSK_CHANNELS, BANK_3_MSK_GROUPS}
};
/*============================================================================*/
/* Touchkey sensors */
/*============================================================================*/
/* Data (RAM) */
TSL_TouchKeyData_T MyTKeys_Data[TSLPRM_TOTAL_TKEYS];
/* Parameters (RAM) */
TSL_TouchKeyParam_T MyTKeys_Param[TSLPRM_TOTAL_TKEYS];
/* State Machine (ROM) */
void MyTKeys_ErrorStateProcess(void);
void MyTKeys_OffStateProcess(void);
CONST TSL_State_T MyTKeys_StateMachine[] = {
/* Calibration states */
/* 0 */ { TSL_STATEMASK_CALIB, TSL_tkey_CalibrationStateProcess },
/* 1 */ { TSL_STATEMASK_DEB_CALIB, TSL_tkey_DebCalibrationStateProcess },
/* Release states */
/* 2 */ { TSL_STATEMASK_RELEASE, TSL_tkey_ReleaseStateProcess },
#if TSLPRM_USE_PROX > 0
/* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, TSL_tkey_DebReleaseProxStateProcess },
#else
/* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, 0 },
#endif
/* 4 */ { TSL_STATEMASK_DEB_RELEASE_DETECT, TSL_tkey_DebReleaseDetectStateProcess },
/* 5 */ { TSL_STATEMASK_DEB_RELEASE_TOUCH, TSL_tkey_DebReleaseTouchStateProcess },
#if TSLPRM_USE_PROX > 0
/* Proximity states */
/* 6 */ { TSL_STATEMASK_PROX, TSL_tkey_ProxStateProcess },
/* 7 */ { TSL_STATEMASK_DEB_PROX, TSL_tkey_DebProxStateProcess },
/* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, TSL_tkey_DebProxDetectStateProcess },
/* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, TSL_tkey_DebProxTouchStateProcess },
#else
/* 6 */ { TSL_STATEMASK_PROX, 0 },
/* 7 */ { TSL_STATEMASK_DEB_PROX, 0 },
/* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, 0 },
/* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, 0 },
#endif
/* Detect states */
/* 10 */ { TSL_STATEMASK_DETECT, TSL_tkey_DetectStateProcess },
/* 11 */ { TSL_STATEMASK_DEB_DETECT, TSL_tkey_DebDetectStateProcess },
/* Touch state */
/* 12 */ { TSL_STATEMASK_TOUCH, TSL_tkey_TouchStateProcess },
/* Error states */
/* 13 */ { TSL_STATEMASK_ERROR, MyTKeys_ErrorStateProcess },
/* 14 */ { TSL_STATEMASK_DEB_ERROR_CALIB, TSL_tkey_DebErrorStateProcess },
/* 15 */ { TSL_STATEMASK_DEB_ERROR_RELEASE, TSL_tkey_DebErrorStateProcess },
/* 16 */ { TSL_STATEMASK_DEB_ERROR_PROX, TSL_tkey_DebErrorStateProcess },
/* 17 */ { TSL_STATEMASK_DEB_ERROR_DETECT, TSL_tkey_DebErrorStateProcess },
/* 18 */ { TSL_STATEMASK_DEB_ERROR_TOUCH, TSL_tkey_DebErrorStateProcess },
/* Other states */
/* 19 */ { TSL_STATEMASK_OFF, MyTKeys_OffStateProcess }
};
/* Methods for "extended" type (ROM) */
CONST TSL_TouchKeyMethods_T MyTKeys_Methods = {
TSL_tkey_Init,
TSL_tkey_Process
};
/* TouchKeys list (ROM) */
CONST TSL_TouchKey_T MyTKeys[TSLPRM_TOTAL_TKEYS] = {
{ &MyTKeys_Data[0], &MyTKeys_Param[0], &MyChannels_Data[CHANNEL_0_DEST], MyTKeys_StateMachine, &MyTKeys_Methods },
{ &MyTKeys_Data[1], &MyTKeys_Param[1], &MyChannels_Data[CHANNEL_1_DEST], MyTKeys_StateMachine, &MyTKeys_Methods },
{ &MyTKeys_Data[2], &MyTKeys_Param[2], &MyChannels_Data[CHANNEL_2_DEST], MyTKeys_StateMachine, &MyTKeys_Methods }
};
/*============================================================================*/
/* Linear and Rotary sensors */
/*============================================================================*/
/* Data (RAM) */
TSL_LinRotData_T MyLinRots_Data[TSLPRM_TOTAL_LINROTS];
/* Parameters (RAM) */
TSL_LinRotParam_T MyLinRots_Param[TSLPRM_TOTAL_LINROTS];
/* State Machine (ROM) */
void MyLinRots_ErrorStateProcess(void);
void MyLinRots_OffStateProcess(void);
CONST TSL_State_T MyLinRots_StateMachine[] = {
/* Calibration states */
/* 0 */ { TSL_STATEMASK_CALIB, TSL_linrot_CalibrationStateProcess },
/* 1 */ { TSL_STATEMASK_DEB_CALIB, TSL_linrot_DebCalibrationStateProcess },
/* Release states */
/* 2 */ { TSL_STATEMASK_RELEASE, TSL_linrot_ReleaseStateProcess },
#if TSLPRM_USE_PROX > 0
/* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, TSL_linrot_DebReleaseProxStateProcess },
#else
/* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, 0 },
#endif
/* 4 */ { TSL_STATEMASK_DEB_RELEASE_DETECT, TSL_linrot_DebReleaseDetectStateProcess },
/* 5 */ { TSL_STATEMASK_DEB_RELEASE_TOUCH, TSL_linrot_DebReleaseTouchStateProcess },
#if TSLPRM_USE_PROX > 0
/* Proximity states */
/* 6 */ { TSL_STATEMASK_PROX, TSL_linrot_ProxStateProcess },
/* 7 */ { TSL_STATEMASK_DEB_PROX, TSL_linrot_DebProxStateProcess },
/* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, TSL_linrot_DebProxDetectStateProcess },
/* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, TSL_linrot_DebProxTouchStateProcess },
#else
/* 6 */ { TSL_STATEMASK_PROX, 0 },
/* 7 */ { TSL_STATEMASK_DEB_PROX, 0 },
/* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, 0 },
/* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, 0 },
#endif
/* Detect states */
/* 10 */ { TSL_STATEMASK_DETECT, TSL_linrot_DetectStateProcess },
/* 11 */ { TSL_STATEMASK_DEB_DETECT, TSL_linrot_DebDetectStateProcess },
/* Touch state */
/* 12 */ { TSL_STATEMASK_TOUCH, TSL_linrot_TouchStateProcess },
/* Error states */
/* 13 */ { TSL_STATEMASK_ERROR, MyLinRots_ErrorStateProcess },
/* 14 */ { TSL_STATEMASK_DEB_ERROR_CALIB, TSL_linrot_DebErrorStateProcess },
/* 15 */ { TSL_STATEMASK_DEB_ERROR_RELEASE, TSL_linrot_DebErrorStateProcess },
/* 16 */ { TSL_STATEMASK_DEB_ERROR_PROX, TSL_linrot_DebErrorStateProcess },
/* 17 */ { TSL_STATEMASK_DEB_ERROR_DETECT, TSL_linrot_DebErrorStateProcess },
/* 18 */ { TSL_STATEMASK_DEB_ERROR_TOUCH, TSL_linrot_DebErrorStateProcess },
/* Other states */
/* 19 */ { TSL_STATEMASK_OFF, MyLinRots_OffStateProcess }
};
/* Methods for "extended" type (ROM) */
CONST TSL_LinRotMethods_T MyLinRots_Methods = {
TSL_linrot_Init,
TSL_linrot_Process,
TSL_linrot_CalcPos
};
/* Delta Normalization Process
The MSB is the integer part, the LSB is the real part
Examples:
- To apply a factor 1.10:
0x01 to the MSB
0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
- To apply a factor 0.90:
0x00 to the MSB
0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
*/
CONST uint16_t MyLinRot0_DeltaCoeff[3] = {0x0100, 0x0100, 0x0100};
/* LinRots list (ROM)*/
CONST TSL_LinRot_T MyLinRots[TSLPRM_TOTAL_LINROTS] = {
{
/* LinRot sensor 0 = S1 */
&MyLinRots_Data[0],
&MyLinRots_Param[0],
&MyChannels_Data[CHANNEL_3_DEST], // first channel data
5, /* Number of channels */ //
MyLinRot0_DeltaCoeff,
// discovery
// (TSL_tsignPosition_T *)TSL_POSOFF_3CH_LIN_H,
// GP board
(TSL_tsignPosition_T *)TSL_POSOFF_5CH_LIN_M1,
// Discovery
// TSL_SCTCOMP_3CH_LIN_H,
// GP board
TSL_SCTCOMP_5CH_LIN_M1,
// Discovery
// TSL_POSCORR_3CH_LIN_H,
// GP board
TSL_POSCORR_5CH_LIN_M1,
MyLinRots_StateMachine,
&MyLinRots_Methods
}
};
/*============================================================================*/
/* Generic Objects */
/*============================================================================*/
/* List (ROM) */
CONST TSL_Object_T MyObjects[TSLPRM_TOTAL_OBJECTS] = {
// touchkeys
{ TSL_OBJ_TOUCHKEY, (TSL_TouchKey_T *)&MyTKeys[0] },
{ TSL_OBJ_TOUCHKEY, (TSL_TouchKey_T *)&MyTKeys[1] },
{ TSL_OBJ_TOUCHKEY, (TSL_TouchKey_T *)&MyTKeys[2] },
// lin rot
{ TSL_OBJ_LINEAR, (TSL_LinRot_T *)&MyLinRots[0] }
};
/* Group (RAM) */
TSL_ObjectGroup_T MyObjGroup = {
&MyObjects[0], /* First object */
TSLPRM_TOTAL_OBJECTS, /* Number of objects */
0x00, /* State mask reset value */
TSL_STATE_NOT_CHANGED /* Current state */
};
/*============================================================================*/
/* TSL Common Parameters placed in RAM or ROM */
/* --> external declaration in tsl_conf.h */
/*============================================================================*/
TSL_Params_T TSL_Params = {
TSLPRM_ACQ_MIN,
TSLPRM_ACQ_MAX,
TSLPRM_CALIB_SAMPLES,
TSLPRM_DTO,
#if TSLPRM_TOTAL_TKEYS > 0
MyTKeys_StateMachine, /* Default state machine for TKeys */
&MyTKeys_Methods, /* Default methods for TKeys */
#endif
#if TSLPRM_TOTAL_LNRTS > 0
MyLinRots_StateMachine, /* Default state machine for LinRots */
&MyLinRots_Methods /* Default methods for LinRots */
#endif
};
/* Private functions prototype -----------------------------------------------*/
/* Global variables ----------------------------------------------------------*/
__IO TSL_tTick_ms_T ECSLastTick; /* Hold the last time value for ECS */
/**
* @brief Initialize the STMTouch Driver
* @param None
* @retval None
*/
void tsl_user_Init(void) {
TSL_obj_GroupInit(&MyObjGroup); /* Init Objects */
TSL_Init(MyBanks); /* Init acquisition module */
tsl_user_SetThresholds(); /* Init thresholds for each object individually (optional) */
}
/**
* @brief Execute STMTouch Driver main State machine
* @param None
* @retval status Return TSL_STATUS_OK if the acquisition is done
*/
tsl_user_status_t tsl_user_Exec(void)
{
static uint32_t idx_bank = 0;
static uint32_t config_done = 0;
tsl_user_status_t status = TSL_USER_STATUS_BUSY;
/* Configure and start bank acquisition */
if (!config_done)
{
TSL_acq_BankConfig(idx_bank);
TSL_acq_BankStartAcq();
config_done = 1;
}
/* Check end of acquisition (polling mode) and read result */
if (TSL_acq_BankWaitEOC() == TSL_STATUS_OK) {
TSL_acq_BankGetResult(idx_bank, 0, 0);
idx_bank++; /* Next bank */
config_done = 0;
}
/* Process objects, DxS and ECS
Check if all banks have been acquired
*/
if (idx_bank > TSLPRM_TOTAL_BANKS-1)
{
/* Reset flags for next banks acquisition */
idx_bank = 0;
config_done = 0;
/* Process Objects */
TSL_obj_GroupProcess(&MyObjGroup);
/* DxS processing (if TSLPRM_USE_DXS option is set) */
TSL_dxs_FirstObj(&MyObjGroup);
/* ECS every 100ms */
if (TSL_tim_CheckDelay_ms(100, &ECSLastTick) == TSL_STATUS_OK)
{
if (TSL_ecs_Process(&MyObjGroup) == TSL_STATUS_OK)
{
status = TSL_USER_STATUS_OK_ECS_ON;
}
else
{
status = TSL_USER_STATUS_OK_ECS_OFF;
}
}
else
{
status = TSL_USER_STATUS_OK_NO_ECS;
}
}
else
{
status = TSL_USER_STATUS_BUSY;
}
return status;
}
/**
* @brief Set thresholds for each object (optional).
* @param None
* @retval None
*/
void tsl_user_SetThresholds(void)
{
/* Example: Decrease the Detect thresholds for the TKEY 0
MyTKeys_Param[0].DetectInTh -= 10;
MyTKeys_Param[0].DetectOutTh -= 10;
*/
}
/**
* @brief Executed when a sensor is in Error state
* @param None
* @retval None
*/
void MyTKeys_ErrorStateProcess(void)
{
/* Add here your own processing when a sensor is in Error state */
}
/**
* @brief Executed when a sensor is in Off state
* @param None
* @retval None
*/
void MyTKeys_OffStateProcess(void)
{
/* Add here your own processing when a sensor is in Off state */
}
/**
* @brief Executed when a sensor is in Error state
* @param None
* @retval None
*/
void MyLinRots_ErrorStateProcess(void)
{
/* Add here your own processing when a sensor is in Error state */
}
/**
* @brief Executed when a sensor is in Off state
* @param None
* @retval None
*/
void MyLinRots_OffStateProcess(void)
{
/* Add here your own processing when a sensor is in Off state */
}
/**
* @brief This function handles a tick.
* @param None
* @retval None
*/
void User_Tick_Management(void) {
// tick counters set to zero first time this routine is called
static uint32_t tempo_50ms=0;
static uint32_t tempo_100ms=0;
static uint32_t tempo_200ms=0;
static uint32_t tempo_300ms=0;
static uint32_t tempo_400ms=0;
static uint32_t tempo_500ms=0;
// increment each counter, but bound to max count for each
tempo_50ms++;
tempo_100ms++;
tempo_200ms++;
tempo_300ms++;
tempo_400ms++;
tempo_500ms++;
tempo_50ms%=50;
tempo_100ms%=100;
tempo_200ms%=200;
tempo_300ms%=300;
tempo_400ms%=400;
tempo_500ms%=500;
// LINEAR_POSITION = MyLinRots[0].p_Data->Position
// above is a "scaled" position
// MyLinRots[0].p_Data->RawPosition
if (LINEAR_DETECT) {
// Now we just adjust when we are touching.
if (LINEAR_POSITION < 4) {
if (tempo_500ms==0) {
BSP_LED_Toggle(LED2);
}
} else if (LINEAR_POSITION < 8) {
if (tempo_300ms==0) {
BSP_LED_Toggle(LED2);
}
} else if (LINEAR_POSITION < 12) {
if (tempo_100ms==0) {
BSP_LED_Toggle(LED2);
}
} else { // pos >= 12
if (tempo_50ms==0) {
BSP_LED_Toggle(LED2);
}
}
}
}
/**
* @brief Display sensors information on LEDs and LCD
* @param status TSL user status
* @retval None
*/
void Process_Sensors(tsl_user_status_t status) {
/* LED1 is ON when TS1 on board is touched */
if (MyTKeys[0].p_Data->StateId == TSL_STATEID_DETECT){
BSP_LED_On(LED3);
} else {
BSP_LED_Off(LED3);
}
/* LED2 is ON when TS2 on board is touched */
if (MyTKeys[1].p_Data->StateId == TSL_STATEID_DETECT) {
BSP_LED_On(LED4);
} else {
BSP_LED_Off(LED4);
}
/* LED3 is ON when TS3 on board is touched */
if (MyTKeys[2].p_Data->StateId == TSL_STATEID_DETECT) {
BSP_LED_On(LED5);
} else {
BSP_LED_Off(LED5);
}
#ifdef isthisused
/* ECS information */
switch (status){
case TSL_USER_STATUS_OK_ECS_OFF:
BSP_LED_Off(LED5);
break;
case TSL_USER_STATUS_OK_ECS_ON:
BSP_LED_Toggle(LED5);
break;
default:
break;
}
#endif
if (LINEAR_DETECT) {
BSP_LED_On(LED1);
} else{
BSP_LED_Off(LED1);
}
}
Любая помощь приветствуется.
1 ответ
Оказывается, для линейных датчиков требуется один вход в паре с одним конденсатором выборки для каждого компонента датчика. Проблема выше заключалась в том, что hw был разработан с пятью входами в две группы с двумя конденсаторами выборки. Колпачок для выборки в одной группе имел 3 иоса, а в другой - 2 иоса.
Я изменил две три группы каналов, каждая группа каналов имела один ввод и одну пробную пробку. После этого код работал нормально.
// The three linrot channels
#define CHANNEL_0_IO_MSK (TSC_GROUP1_IO3)
#define CHANNEL_0_GRP_MSK (TSC_GROUP1)
#define CHANNEL_0_SRC (TSC_GROUP1_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_0_DEST (0) /* Index in destination result array */
#define CHANNEL_1_IO_MSK (TSC_GROUP2_IO4)
#define CHANNEL_1_GRP_MSK (TSC_GROUP2)
#define CHANNEL_1_SRC (TSC_GROUP2_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_1_DEST (1) /* Index in destination result array */
#define CHANNEL_2_IO_MSK (TSC_GROUP3_IO2)
#define CHANNEL_2_GRP_MSK (TSC_GROUP3)
#define CHANNEL_2_SRC (TSC_GROUP3_IDX) /* Index in source register (TSC->IOGXCR[]) */
#define CHANNEL_2_DEST (2) /* Index in destination result array */
Я столкнулся с этой ситуацией и пытался найти решение в программном обеспечении, а не в оборудовании. Эта проблема не связана с оборудованием, потому что, если вы попытаетесь прочитать каналы, которые находятся в одной группе, а также в одном банке, значения дельты будут совпадать друг с другом.
Я думаю, ваши чтения в STMStudio следующие: MyChannels_Data[3].Delta = MyChannels_Data[4].Delta
а также MyChannels_Data[5].Delta = MyChannels_Data[6].Delta = MyChannels_Data[7].Delta
.
Чтобы решить эту проблему, вам следует разделить свой BANK_3 (LinRot Bank) следующим образом:
Заголовочный файл:
// The linrot banks
// Channel 3 is a Group1_IO
#define BANK_3_NBCHANNELS (1)
#define BANK_3_MSK_CHANNELS (CHANNEL_3_IO_MSK | SHIELD_IO_MSK)
#define BANK_3_MSK_GROUPS (CHANNEL_3_GRP_MSK)
// Channel 4 is a Group1_IO, so I have to separate it from Bank 3, because Channel 3 is also a Group1_IO.
// Channel 5 is a Group2_IO, so I can combine it with Channel 4 in same Bank.
#define BANK_4_NBCHANNELS (2)
#define BANK_4_MSK_CHANNELS (CHANNEL_4_IO_MSK | CHANNEL_5_IO_MSK | SHIELD_IO_MSK)
#define BANK_4_MSK_GROUPS (CHANNEL_4_GRP_MSK | CHANNEL_5_GRP_MSK )
// Channel 6 is a Group2_IO, so I have to separate it from Bank 4 because Channel 5 is also a Group2_IO.
#define BANK_5_NBCHANNELS (1)
#define BANK_5_MSK_CHANNELS (CHANNEL_6_IO_MSK | SHIELD_IO_MSK)
#define BANK_5_MSK_GROUPS (CHANNEL_6_GRP_MSK)
// Channel 7 is a Group2_IO, so I have to separate it from Bank 6,
// because Channel 6 is also a Group2_IO.
#define BANK_6_NBCHANNELS (1)
#define BANK_6_MSK_CHANNELS (CHANNEL_7_IO_MSK | SHIELD_IO_MSK)
#define BANK_6_MSK_GROUPS (CHANNEL_7_GRP_MSK)
Исходный файл:
/*============================================================================*/
/* Banks */
/*============================================================================*/
/* List (ROM) */
CONST TSL_Bank_T MyBanks[TSLPRM_TOTAL_BANKS] = {
// The three touchkey bankss
{&MyChannels_Src[0], &MyChannels_Dest[0], MyChannels_Data, BANK_0_NBCHANNELS, BANK_0_MSK_CHANNELS, BANK_0_MSK_GROUPS},
{&MyChannels_Src[1], &MyChannels_Dest[1], MyChannels_Data, BANK_1_NBCHANNELS, BANK_1_MSK_CHANNELS, BANK_1_MSK_GROUPS},
{&MyChannels_Src[2], &MyChannels_Dest[2], MyChannels_Data, BANK_2_NBCHANNELS, BANK_2_MSK_CHANNELS, BANK_2_MSK_GROUPS},
// The one linrot bank
{&MyChannels_Src[3], &MyChannels_Dest[3], MyChannels_Data, BANK_3_NBCHANNELS, BANK_3_MSK_CHANNELS, BANK_3_MSK_GROUPS},
{&MyChannels_Src[4], &MyChannels_Dest[4], MyChannels_Data, BANK_4_NBCHANNELS, BANK_4_MSK_CHANNELS, BANK_4_MSK_GROUPS},
{&MyChannels_Src[6], &MyChannels_Dest[6], MyChannels_Data, BANK_5_NBCHANNELS, BANK_5_MSK_CHANNELS, BANK_5_MSK_GROUPS},
{&MyChannels_Src[7], &MyChannels_Dest[7], MyChannels_Data, BANK_6_NBCHANNELS, BANK_6_MSK_CHANNELS, BANK_6_MSK_GROUPS},
};
Конфигурационный файл:
#define TSLPRM_TOTAL_BANKS (7)
Примечание: количество банков в библиотеке ограничено. В моем случае количество банков, требуемых в моем приложении, было больше лимита, тогда я просто меняю значение, и у меня не было никаких проблем.
Ответ немного запоздал. Но я надеюсь, что это поможет.
Изменить: я нашел подсказку для определения банка на странице 122 документа "UM1606 - руководство пользователя драйвера STMTouch". Это объясняется следующим образом:
Для оптимальной чувствительности и определения местоположения все каналы, составляющие линейный или поворотный датчик касания, должны регистрироваться одновременно. Это означает, что все каналы должны принадлежать одному банку.
Примечание: библиотека позволяет определять линейный или поворотный датчик касания с каналами, принадлежащими разным банкам. Такая конфигурация вызывает потерю чувствительности и более высокий уровень шума. Более того, в зависимости от времени сбора данных можно также наблюдать изменение положения при удалении пальца от датчика.
Для оптимальной работы линейного или поворотного датчика все каналы такого датчика должны регистрироваться одновременно. Следовательно, все каналы должны принадлежать к одному банку, что означает, что входы / выходы должны выбираться из разных групп аналоговых входов / выходов. Пожалуйста, обратитесь к таблице данных для получения дополнительной информации о группах ввода / вывода и доступных емкостных датчиках GPIO.
Резюме: Если входы / выходы одной группы не могут находиться в одном банке и если все каналы датчика должны быть в одном банке, то все каналы датчика должны принадлежать разным группам. Допустим, датчик представляет собой 6-канальный линейный датчик, тогда каналы могут быть подключены следующим образом: 1-Ch = Group1_IO1, 2-Ch = Group2_IO1, 3-Ch = Group3_IO1, 4-Ch = Group4_IO1, 5-Ch = Group5_IO1, 6-канальный = Group6_IO1. Таким образом, можно легко сказать, что аппаратное решение - лучшее решение. Но не забывайте, что программное обеспечение тоже существует. Однако он не такой уж чувствительный.