Перейти к содержанию
    

TSC (Touch sensing controller) на STM32F051

Выполняю проект по разработке устройства. Нужно реализовать управление сенсорными кнопками. Всего кнопок 14. Контроллер использую только STM32F051.

Вот схема данного устройства: http://www.picshare.ru/view/2993892/

Кнопки расположены вот так: http://www.picshare.ru/view/2993980/

Скачал библиотеку "STM32F0xx_STMTouch_Lib_V1.0.1" на сайте ST, но как с ней работать ума не приложу. Непонятен сам алгоритм работы, что зачем вызывать. Информации по данному контроллеру очень мало.

Прошу помощи по работе с TSC под STM32F051. Кто работал с данной периферией? Есть ли рабочие примеры или документация (желательно на русском, а то с английским не очень дружу)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делал сенсорные кнопки на TSC в STM32F3xx. Думаю, это одно и то же.

С UserManual без каких-либо библиотек запускается с пол оборота, но осциллограф желателен.

Изменено пользователем IgorKossak
избыточное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Могу. Но вопросов будет еще больше.

Библиотек не использую, работаю напрямую с регистрами.

Приду домой - выложу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы и не создавал эту тему если бы не было вопросов :) Мне хотя бы понять алгоритм работы, как и что инициализировать, что запускать. Я кстати сам предпочитаю работать напрямую с регистрами, но в последнее время пристрастился к библиотекам и функциям.

Буду ждать... ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Буду ждать... ;)

//-----------------------------------------------------------------------------
//	void __inline init_TSC(void)
//-----------------------------------------------------------------------------
void __inline init_TSC(void)
{
//TSC_CR_TSCE_bit = 1;

TSC->CR = (1 << TSC_CR_TSCE);

TSC->CR =
		(2 << TSC_CR_CTPH)
	| (6 << TSC_CR_CTPL)
	| (9 << TSC_CR_SSD)
	| (0 << TSC_CR_SSE)
	| (1 << TSC_CR_SSPSC)
	| (0 << TSC_CR_PGPSC)
	| (6 << TSC_CR_MCV)
	| (0 << TSC_CR_IODEF)
	| (0 << TSC_CR_SYNCPOL)
	| (0 << TSC_CR_AM)
	| (0 << TSC_CR_START)
	| (1 << TSC_CR_TSCE);

TSC->IER =
		(1 << TSC_IER_EOAIE)
	| (1 << TSC_IER_MCEIE);

TSC->IOSCR = (1 << TSC_G1_IO4);	// Cs
TSC->IOCCR = (1 << TSC_G1_IO3);
TSC->IOGCSR = (1 << 0);

}

Кроме этого:

NVIC->ISER[0] = (1 << NVIC_ISER0_TSC) | (1 << NVIC_ISER0_TIM2);

RCC->AHBENR =
	  (1 << RCC_AHB_IOPA)
	| (1 << RCC_AHB_IOPB)
	| (1 << RCC_AHB_IOPC)
	| (1 << RCC_AHB_IOPD)
	| (1 << RCC_AHB_IOPE)
	| (1 << RCC_AHB_TSC)
	| (1 << RCC_AHB_FLITF)
	| (1 << RCC_AHB_SRAM)
	| (1 << RCC_AHB_DMA1)
	| (0 << RCC_AHB_DMA2);

GPIOA->MODER =
	  (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN1)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN2)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN3)
	| (GPIO_MODE_ANALOG		<< GPIO_MODER_PIN4)
	| (GPIO_MODE_OUTPUT		<< GPIO_MODER_PIN8)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN9)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN10)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN13)
	| (GPIO_MODE_ALTERNATE	<< GPIO_MODER_PIN14)
	| (GPIO_MODE_OUTPUT		<< GPIO_MODER_PIN15);

GPIOA->OTYPER = (1 << 3);

GPIOA->AFR[0] =
	  (AF_PA1_TSC_G1_IO2		<< GPIO_AFR0_PIN1)
	| (AF_PA2_TSC_G1_IO3		<< GPIO_AFR0_PIN2)
	| (AF_PA3_TSC_G1_IO4		<< GPIO_AFR0_PIN3);

И наконец:
//-----------------------------------------------------------------------------
//	void EXTI2_TSC_IRQHandler(void)
//-----------------------------------------------------------------------------
void EXTI2_TSC_IRQHandler(void) __attribute__((interrupt("IRQ")));
void EXTI2_TSC_IRQHandler(void)
{

int	i;

static int ff = 0;
#define	FF_SIZE	(5)
static int point = 0;
static int	delta = 0;
static int	updown = 0;

if(TSC->ISR & (1 << TSC_ISR_MCEF))
{
	// max
	TSC->ICR = (1 << TSC_ICR_MCEIC);
	//TSC_CR_START_bit = 1;
}
if(TSC->ISR & (1 << TSC_ISR_EOAF))
{
	// done
	TSC->ICR = (1 << TSC_ICR_EOAIC);
	tsc_val = TSC->IOGXCR[0];
	val[state][count] = tsc_val;

	cap_sensor_data(item, tsc_val);

	value[item] = tsc_val;
	switch(item)
	{
		case 0:
			pos[item] = (cap[item].val - cap[item].t_min) * 100 / (cap[item].t_max - cap[item].t_min);
			break;

		case 1:
			pos[item] = (cap[item].val - cap[item].t_min) * 100 / (cap[item].t_max - cap[item].t_min);
			break;
	}

	delta = delta + pos[0] + pos[1] - (delta / DELTA_N);

	if(((delta / DELTA_N) - (pos[0] + pos[1])) > 20)
	{
		if(updown == 0)
		{
			//con_str("{UPDOWN=1}\n\r");
			//con_start();
		}
		updown = 1;
	}
	else if(((delta / DELTA_N) - (pos[0] + pos[1])) < -20)
	{
		if(updown == 1)
		{
			//con_str("{UPDOWN=0}\n\r");
			//con_start();
		}
		updown = 0;
	}

	if(updown)
	{
		i = (pos[0] - pos[1]) / 2;
		if(i < p_min) p_min = i;
		if(i > p_max) p_max = i;
	}
	else
	{
		if((p_min != 1000) && (p_max != -1000))
		{
			i = (p_min + p_max) / 2;

			if(i < -5) v = 0;
			else if(i > 5) v = 900;
			else if((-5 <= p_min) && (p_max <= 5)) v = 450;

		}
		p_min = 1000;
		p_max = -1000;
		i = -1000;
	}

	if(i != -1000)
	{
		if(l == -1000) l = i;
		v += (i - l) * 10;
		l = i;

		v += i / 5;

		if(v < 0) v = 0;
		else if(v > 900) v = 900;

	}
	else l = -1000;

	fv = fv + v - (fv / F_MUL);
	i = (1 << ((fv / F_MUL) / 100)) - 1;
	GPIOE->BSRR = (i << 8) | (((i ^ 0xFF) << 8) << 16);
}
}

И вызываем с частотой 100Гц:

//count++;
//if(count >= 100) count = 0;

count = 27;

switch(item)
{
	case 0:
		item = 1;
		TSC->IOCCR = (1 << TSC_G1_IO3);
		break;

	case 1:
	default:
		item = 0;
		TSC->IOCCR = (1 << TSC_G1_IO2);
		break;
}

TSC->CR =
	  ((1 + (count / 10)) << TSC_CR_CTPH)
	| ((1 + (count % 10)) << TSC_CR_CTPL)
	| (6 << TSC_CR_MCV)
	| (1 << TSC_CR_START)
	| (1 << TSC_CR_TSCE);

 

Код в большей части отладочный, но рабочий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да уж... тут без пол литра не разобраться :smile3046: А зачем осциллограф нужен?

Если выкинуть матан из обработчика прерывания, то инициализация простейшая.

С осциллографом работа ускоряется в разы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какой кварц использовали внешний или внутренний, на какой частоте тактировали шину AHB?

 

Какие библиотеки нужно подключить для работы с TSC? А то у меня при компиляции миллион ошибок. Работаю в Coocox IDE

Подключил как основную

#include "stm32f0xx.h"

 

а также для удобства

#include "stm32f0xx_rcc.h"

#include "stm32f0xx_gpio.h"

#include "stm32f0xx_exti.h"

 

Я так понимаю нужен файл с расписанной адресацией регистров:

TSC_CR_CTPH

TSC_CR_CTPL

TSC_CR_SSD

TSC_CR_SSE

TSC_CR_SSPSC

TSC_CR_PGPSC

TSC_CR_MCV

и т.д.

 

Как у вас с этим дело обстоит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так понимаю CMSIS файл вы сами доделывали?

Я ж говорю: "библиотек чужих не использую".

Описывал номера битов самостоятельно на основе UM.

Вы не пытайтесь скомпиллировать пример - лучше попробуйте написать свой, взяв пример для демонстрации ключевых моментов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я ж говорю: "библиотек чужих не использую".

Описывал номера битов самостоятельно на основе UM.

Вы не пытайтесь скомпиллировать пример - лучше попробуйте написать свой, взяв пример для демонстрации ключевых моментов.

ОК попробую :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то я не могу запустить TSC, тактирование подаю:

RCC->AHBENR |= RCC_AHBENR_TSEN;

Смотрю на состояние регистров RCC - тактирование TSC идёт.

Но когда пытаюсь запустить TSC:

TSC->CR = 0x01;

Состояние бита не меняется :wacko: Тактирую чип от внутреннего кварца HSI с умножителем на 48 МГц, шину AHB тоже на 48 МГц.

Может что-то не то делаю? :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то я не могу запустить TSC, тактирование подаю:

RCC->AHBENR |= RCC_AHBENR_TSEN;

Смотрю на состояние регистров RCC - тактирование TSC идёт.

Но когда пытаюсь запустить TSC:

TSC->CR = 0x01;

Состояние бита не меняется :wacko: Тактирую чип от внутреннего кварца HSI с умножителем на 48 МГц, шину AHB тоже на 48 МГц.

Может что-то не то делаю? :help:

Попробуйте подождать перед чтением TSC->CR.

А лучше запишите TSC->CR два раза.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте подождать перед чтением TSC->CR.

А лучше запишите TSC->CR два раза.

Попробовал, не помогло. Уже смотрю напрямую в память - там тоже нули ((( Даже в бесконечном цикле не устанавливается. Может я спалил его когда паял, хотя АЦП, порты, таймеры и часы работают.

Даже не знаю что делать, тупик какой-то...

Попробую в Keil-е собрать и отдебажить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...