al 发表于 2012-3-27 16:52:02

关于触摸库中代码

 
基于RC充放电原理的触摸按键检测代码是基于软件查询方式还是中断方式?库中
中断代码中根本看不到处理按键检测计时的代码,如果我的应用代码中的中断程
序中有5毫秒的代码需要执行,那么触摸按键检测还能够顺利进行吗?st 触摸应
用相关的应用笔记中描述扫描一个按键要耗时1ms,如果是基于软件查询方式的,
那么启动按键扫描后是不能被中断的,这样结构的程序库还有使用的价值吗?

al 发表于 2012-3-27 17:39:50

RE:关于触摸库中代码运行的机制

:)没人回答,因为想利用触摸库才想选STM8的,结果还是被触摸库给挡住了。

al 发表于 2012-3-28 09:04:37

RE:关于触摸库中代码

沉的厉害,居然找不到了。

al 发表于 2012-3-28 09:14:42

RE:关于触摸库中代码

找到了个中断,在stm8_tls_timebase.c里。
只是看到时钟滴答处理,并没看到按键充放电时间读取处理,郁闷。

/**
******************************************************************************
* @brief Manages the timer ticks for the whole application.
* Define as Interrupt Service Routine for HW Timer used as timebase
* (IT every 0.5ms)
* or called by a RTOS
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
#if (RTOS_MANAGEMENT > 0)
void TSL_Timer_ISR(void)
#else
#if defined(MCU_STM8L10X) || defined(MCU_STM8L15X_LD) || defined(MCU_STM8L15X_MDHD)
INTERRUPT_HANDLER(TSL_Timer_ISR, 25)
#else /* STM8S */
INTERRUPT_HANDLER(TSL_Timer_ISR, 23)
#endif
#endif
{
TIMTICK->SR1 = 0;      // clear overflow flag
TSL_Tick_Base++;
TSL_Timer_Check_10ms_Tick();
if (TSL_Tick_Flags.b.User1_Start_100ms) /* Application request */
{
    TSL_Tick_Flags.b.User1_Start_100ms = 0;
    TSL_Tick_Flags.b.User1_Flag_100ms = 0;
    TSL_Tick_User1 = (TICK_FACTOR_10MS * 10);
}
if (TSL_Tick_Flags.b.User2_Start_100ms) /* Application request */
{
    TSL_Tick_Flags.b.User2_Start_100ms = 0;
    TSL_Tick_Flags.b.User2_Flag_100ms = 0;
    TSL_Tick_User2 = (TICK_FACTOR_10MS * 10);
}
if (TSL_Tick_User1 > 0)
{
    TSL_Tick_User1--;
    if (TSL_Tick_User1 == 0)
    {
      TSL_Tick_Flags.b.User1_Flag_100ms = 1; /* Give information to Application */
    }
}
if (TSL_Tick_User2 > 0)
{
    TSL_Tick_User2--;
    if (TSL_Tick_User2 == 0)
    {
      TSL_Tick_Flags.b.User2_Flag_100ms = 1; /* Give information to Application */
    }
}
#if TIMER_CALLBACK
USER_TickTimerCallback();
#endif
}

废鱼 发表于 2012-3-28 15:28:31

RE:关于触摸库中代码

没有用过你说的这种触摸按键,我想应该是会有一个电压来产生一个上升沿或者下降沿,然后用过外部中断来获取。还有一种,好像是可以通过总线来采集的。

al 发表于 2012-3-28 18:14:20

回复:关于触摸库中代码

006回复第 5 楼 于2012-03-28 07:28:31发表:
没有用过你说的这种触摸按键,我想应该是会有一个电压来产生一个上升沿或者下降沿,然后用过外部中断来获取。还有一种,好像是可以通过总线来采集的。 

   st的触摸按键相关文档说明了原理, 触摸检测是分别检测I/O口RC充、放电达到I/O口的高、低电平门限阈值,即分别充放电到ViH和ViL,然后记取定时器的计数值,分别为充电时间和放电时间,每个按键扫描一次要进行连续8次的充放电检测。记取充放电时间要用到2个定时器,假设定时器为8位T1和16位T2,T1设为250us定时中断,在触摸按键扫描函数开始运行时启动定时器T1和T2,T1中断发生后读取的T2值即为充电或放电时间。然而stm8触摸库中并看不到这样的处理。
   既然是想利用stm8的触摸库就是为了利用它的成熟代码,又怎么会自己另选方案呢,如果自己编写代码那么就要将触摸库中的触摸代码的消抖、自动校准基准值、平滑滤波等功能都要重写一次,感觉有困难。
:)

al 发表于 2012-3-28 20:15:46

RE:关于触摸库中代码

终于找到早期的触摸库了,天啊,真是软件查询方式,充放电都是死等的,坑爹啊。
:D:D
/**
******************************************************************************
* @brief Local sub function to wait for vil on RC structure.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
* @warning
* This function must be aligned in memory (start at an even address). This is
* done automatically when pragma "section" is used.
******************************************************************************
*/
void TSL_IO_SW_Burst_Wait_Vil(void)
{
#asm
nop
ld a, _AcquisitionBitMask
ldw x, _sTouchIO   // Input data register ...
incw x
// Loop = 1 + 1 + 2 + 2 + 2 cycles = 8 cycles
WaitForVil:
bcp a, (x)// 1 cycles
jreq EndWaitForVil
ldw y, _TIMACQ_CNTR // 2 cycles; hw counter also used for timeout ...
cpw y, #0x0E00    // 2 cycles; Timeout compare
jrult WaitForVil
EndWaitForVil:
#endasm
}

/**
******************************************************************************
* @brief Local sub function to wait for vih on RC structure.
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
* @warning
* This function must be aligned in memory (start at an even address). This is
* done automatically when pragma "section" is used.
******************************************************************************
*/
void TSL_IO_SW_Burst_Wait_Vih(void)
{
#asm
nop
ld a, _AcquisitionBitMask
ldw x, _sTouchIO   // Input data register ...
incw x
// Loop = 1 + 1 + 2 + 2 + 2 cycles = 8 cycles
WaitForVih:
bcp a, (x)// 1 cycles
jrne EndWaitForVih
ldw y, _TIMACQ_CNTR // 2 cycles; hw counter also used for timeout ...
cpw y, #0x0E00    // 2 cycles; Timeout compare
jrult WaitForVih
EndWaitForVih:
#endasm
}

al 发表于 2012-3-30 16:40:45

RE:关于触摸库中代码

/**
******************************************************************************
* @brief Acquisition function for the 1st Channel IO of each group
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void TSL_IO_Acquisition_P1(u16 MaxAcqNumber)
{
u16 MeasurementCounter;
/*reset the counter values*/
MeasurementCounter = 0x0000;
Channel_P1.Measure = 0x0000;
Channel_P1.Measure = 0x0000;
Channel_P1.State.whole = 0x00;
/*open the analog switches*/
COMP->CCS &= (u8)(~(SAMP_CAP_COMP_MASK | P1_COMP_MASK));
/*All IO to pushpull LOW for discharging all capacitors (Ctouch and Csense)*/
/*discharging Csample*/
#ifdef PROTECT_IO_ACCESS
disableInterrupts();
#endif
SAMP_CAP_PORT->DDR |= SAMP_CAP_IO_MASK;
SAMP_CAP_PORT->CR1 |= SAMP_CAP_IO_MASK;
SAMP_CAP_PORT->ODR &= (u8)(~(SAMP_CAP_IO_MASK));
/*discharging Ctouch*/
P1_PORT->DDR |= P1_IO_MASK;
P1_PORT->CR1 |= P1_IO_MASK;
P1_PORT->ODR &= (u8)(~(P1_IO_MASK));
#ifdef PROTECT_IO_ACCESS
enableInterrupts();
#endif
/*wait a while for good discharging of all capacitors*/
wait(200);
/*All IO in input floating*/
#ifdef PROTECT_IO_ACCESS
disableInterrupts();
#endif
P1_PORT->DDR &= (u8)(~(P1_IO_MASK));
P1_PORT->CR1 &= (u8)(~(P1_IO_MASK));
#ifdef PROTECT_IO_ACCESS
enableInterrupts();
#endif
//close the Channel #1 analog switches (COMP1 CHA and COMP2 CH1 ie PB0 and PB2)
COMP->CCS |= SAMP_CAP_COMP_MASK;
/*loop while all the 1st channel of each group have not reach the VIH level*/
do
{
    /*Close the sampling capacitor analog switch*/
    COMP->CCS |= SAMP_CAP_COMP_MASK;
    /*charging Ctouch with connecting the IO to Vdd (io in push-pull HIGH)*/
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    P1_PORT->DDR |= P1_IO_MASK;//output push pull config
    P1_PORT->CR1 |= P1_IO_MASK;
    P1_PORT->ODR |= P1_IO_MASK; //HIGH level
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif
    /*wait a while for good charging*/
    CLWHTA; //wait(5);
    /*All IO in input */
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    P1_PORT->DDR &= (u8)(~(P1_IO_MASK));
    P1_PORT->CR1 &= (u8)(~(P1_IO_MASK));
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif
    MeasurementCounter++;
    /*charging the Csense cap with connecting it to Ctouch by closing the analog switch*/
    COMP->CCS |= P1_COMP_MASK;
    /*wait a while for good charge transfering*/
    CLWLTA; //wait(5);
#if SPREAD_SPECTRUM
    TSL_SW_Spread_Spectrum();
#endif
    /*open the analog switches to allow checking of the inputs*/
    COMP->CCS &= (u8)(~(SAMP_CAP_COMP_MASK | P1_COMP_MASK));
    /*Sampling capacitor IOs in input floating*/
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    SAMP_CAP_PORT->DDR &= (u8)(~(SAMP_CAP_IO_MASK));
    SAMP_CAP_PORT->CR1 &= (u8)(~(SAMP_CAP_IO_MASK));
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif

    if ((Channel_P1.State.b.Grp1 == 0) && ((SAMP_CAP_PORT->IDR&SAMP_CAP_IO_MASK_1) == SAMP_CAP_IO_MASK_1))
    {
      Channel_P1.Measure += MeasurementCounter;
      Channel_P1.State.whole |= Group1;
    }
    if ((Channel_P1.State.b.Grp2 == 0) && ((SAMP_CAP_PORT->IDR&SAMP_CAP_IO_MASK_2) == SAMP_CAP_IO_MASK_2))
    {
      Channel_P1.Measure += MeasurementCounter;
      Channel_P1.State.whole |= Group2;
    }
    /*it's better to implement this like that because it's much more faster than to put this test in the "while test" below and only the MSByte is tested in order to speed up the code execution*/
    if ((u8)(MeasurementCounter >> 8) > (u8)(MaxAcqNumber >> 8))
    {
      break;
    }
}
while (((Channel_P1.State.whole & Channel_P1.EnabledChannels) != Channel_P1.EnabledChannels));
}

al 发表于 2012-3-30 16:40:13

RE:关于触摸库中代码

/**
******************************************************************************
* @brief Acquisition function for the 2nd Channel IO of each group
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
#if (NUMBER_OF_ACQUISITION_PORTS > 1)
void TSL_IO_Acquisition_P2(u16 MaxAcqNumber)
{
u16 MeasurementCounter;
/*reset the counter values*/
MeasurementCounter = 0x0000;
Channel_P2.Measure = 0x0000;
Channel_P2.Measure = 0x0000;
Channel_P2.State.whole = 0x00;
/*open the analog switches*/
COMP->CCS &= (u8)(~(SAMP_CAP_COMP_MASK | P2_COMP_MASK));
/*All IO to pushpull LOW for discharging all capacitors (Ctouch and Csense)*/
/*discharging Csample*/
#ifdef PROTECT_IO_ACCESS
disableInterrupts();
#endif
SAMP_CAP_PORT->DDR |= SAMP_CAP_IO_MASK;
SAMP_CAP_PORT->CR1 |= SAMP_CAP_IO_MASK;
SAMP_CAP_PORT->ODR &= (u8)(~(SAMP_CAP_IO_MASK));
/*discharging Ctouch*/
P2_PORT->DDR |= P2_IO_MASK;
P2_PORT->CR1 |= P2_IO_MASK;
P2_PORT->ODR &= (u8)(~(P2_IO_MASK));
#ifdef PROTECT_IO_ACCESS
enableInterrupts();
#endif
/*wait a while for good discharge of all capacitors*/
wait(200);
/*All IO in input floating*/
#ifdef PROTECT_IO_ACCESS
disableInterrupts();
#endif
P2_PORT->DDR &= (u8)(~(P2_IO_MASK));
P2_PORT->CR1 &= (u8)(~(P2_IO_MASK));
#ifdef PROTECT_IO_ACCESS
enableInterrupts();
#endif
//close the Chanel #1 analog switches (COMP1 CHA and COMP2 CH1 ie PB0 and PB2)
COMP->CCS |= SAMP_CAP_COMP_MASK;
/*loop while all the 1st channel of each group have not reach the VIH level*/
do
{
    /*Close the sampling capacitor analog switch*/
    COMP->CCS |= SAMP_CAP_COMP_MASK;
    /*charging Ctouch with connecting the IO to Vdd (io in push-pull HIGH)*/
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    P2_PORT->DDR |= P2_IO_MASK;//output push pull config
    P2_PORT->CR1 |= P2_IO_MASK;
    P2_PORT->ODR |= P2_IO_MASK; //HIGH level
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif
    /*wait a while for good charging*/
    CLWHTA; //wait(5);
    /*All IO in input */
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    P2_PORT->DDR &= (u8)(~(P2_IO_MASK));
    P2_PORT->CR1 &= (u8)(~(P2_IO_MASK));
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif
    MeasurementCounter++;
    /*charging the Csense cap with connecting it to Ctouch by closing the analog switch*/
    COMP->CCS |= P2_COMP_MASK;
    /*wait a while for good charge transfering*/
    CLWLTA; //wait(5);
#if SPREAD_SPECTRUM
    TSL_SW_Spread_Spectrum();
#endif
    /*open the analog switches to allow checking of the inputs*/
    COMP->CCS &= (u8)(~(SAMP_CAP_COMP_MASK | P2_COMP_MASK));
    /*Sampling capacitor IOs in input folating */
#ifdef PROTECT_IO_ACCESS
    disableInterrupts();
#endif
    SAMP_CAP_PORT->DDR &= (u8)(~(SAMP_CAP_IO_MASK));
    SAMP_CAP_PORT->CR1 &= (u8)(~(SAMP_CAP_IO_MASK));
#ifdef PROTECT_IO_ACCESS
    enableInterrupts();
#endif
    if ((Channel_P2.State.b.Grp1 == 0) && ((SAMP_CAP_PORT->IDR&SAMP_CAP_IO_MASK_1) == SAMP_CAP_IO_MASK_1))
    {
      Channel_P2.Measure += MeasurementCounter;
      Channel_P2.State.whole |= Group1;
    }
    if ((Channel_P2.State.b.Grp2 == 0) && ((SAMP_CAP_PORT->IDR&SAMP_CAP_IO_MASK_2) == SAMP_CAP_IO_MASK_2))
    {
      Channel_P2.Measure += MeasurementCounter;
      Channel_P2.State.whole |= Group2;
    }
    /*it's better to implement this like that because it's much more faster than to put this test in the "while test" belowand only the MSByte is tested in order to speed up the code execution*/
    if ((u8)(MeasurementCounter >> 8) > (u8)(MaxAcqNumber >> 8))
    {
      break;
    }
}
while (((Channel_P2.State.whole & Channel_P2.EnabledChannels) != Channel_P2.EnabledChannels));
}
#endif

sssdd 发表于 2016-10-27 09:01:10

所以我觉得这个可以用碎片中断。中断里面只处理标志位。
减少中断开销时间。
把本来5ms的事情搞到主程序里面。
刚玩这个触摸库。来挖个坟。
页: [1]
查看完整版本: 关于触摸库中代码