подключение к USB

Подключаем наши девайсы к компьютеру. Обсуждаются: порты, протоколы, драйвера, языки программирования и т.д.
Ответить
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Вы выше писали:
Ser60 писал(а):Начите с настройки первого таймера на 50 гц и добейтесь зыдачи этой частоты на ногу МК (см. книгу Гладштейна). Когда с этим разберетесь, напишите код как-бы Вы управляли внешним ключевым транзистором и выведите соответствующие сигналы на другую ногу МК. После этого пришлите код для дальнейшего обсуждения.
Я так понимаю, что надо в теле обработчика прерывания таймера3 запускать таймер2, но как это корректно сделать - не понимаю... Можно ли это реализовать просто включением таймера 2 или разрешением прерываний от него?
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Для запуска тамера 2 надо поставить 1 в бит 2 (TR2) регистра TMR2CN. Аналогично для таймера 3 - бит 2 (ТR3) в регистре TMR3CN.

Для визуального контроля импульсов формируемых таймером, я-бы подключился осциллографом на ноги МК, контролируемые таймерами 2 и 3. И все-же рекомендую начать с одного цвета.
Реклама
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

То есть вот так будет корректно? (заменены команды P1 |=0x01; и P1 &=0xFE; на ET2=1; и ET2=0; соответственно)
Спойлер

Код: Выделить всё

if(alsn1==1)
     {if (alsn2==35)
	    {alsn1=alsn1+1;
		 ET2=0;
		 alsn2=0;}
	  else {
	         ET2=1;
			 alsn2=alsn2+1;
			 }
			 }
	else{
	    if (alsn1==2||alsn2==4)
	   {
	    if (alsn2==12)
		 {
		 ET2=1;
		 alsn1=alsn1+1;
		 alsn2=0;
		 }
		else 
		{
		 ET2=0;
		 alsn2=alsn2+1;}
		 }
		 if (alsn1==3||alsn1==5)
		 {if (alsn2==24)
		  {ET2=0;
		   alsn1=alsn1+1;
		   alsn2=0;}
		   else
		   {ET2=1;
		    alsn2=alsn2+1;}}
			else
			{if (alsn2==79)
			 {ET2=1;
			  alsn1=1;
			  alsn2=0;}
			  else
			  {ET2=0;
			  alsn2=alsn2+1;}}}}
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Команда
ET2=0;
написана верно, а все остальное уж очень неэффективно. Я все еще не понял идеи Вашего кода.

Я-бы сделал так на примере зеленого цвета: в течении периода имеются 6 подинтервалов. Завести массив из 6 чисел, соответствующих длительностям этих подинтервалов (длительности 0.35, 0.12, и т.д). В прерывании таймера (по истечении подинтервала выдержки) загружать в него следующее значение для выдержки по циклу (после 6-го идет опять первое). Будет около 5 строчек на цвет.
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Спасибо, идея с массивом мне в голову не приходила. Получается надо в начале сравнить со значением числа в массиве и в случае совпадения изменить состояние таймера, генерирующего 50 Гц и перейти к следующему числу в массиве? У меня в начале проверяется номер подинтервала, затем длительность и определяется нужно ли менять состояние таймера, генерирующего 50 Гц
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Не совсем. Сначала заводите массив длительностей. На примере для зеленого цвета пусть это будет массив из 6-ти элементов по числу генерируемых подинтервалов с длительностями 0.35, 0.12, 0.22, 0.12, 0.22, 0.57 сек.
int green[] = {*, *, *, *, *, *};
Вместо звездочек туда нужно подставить реальные числа, соответствующие длительностям. Для их нахождения примем, что частота импульсов на входе таймера 1.5 мгц (период 2/3 мксек) и используется предделитель 1:48. Для получения первой выдержки 0.35 сек = 350000 мксек таймер должен будет досчитать до числа х определяемого из равенства
(2/3)*48*х = 350000
откуда получаем x = 10937. Поскольку таймер обнуляется при переходе от 65535 в 0, для получения выдержки 0.35 сек в его счетчик следует загрузить число 65536 - х = 54599. Это и будет первый элемент массива green. Для второго элемента массива и выдержки 0.12 сек аналогично получаем x = 3750, т.е. второй эемент будет 65536 - 3750 = 61786 и т.д. Поскольку Timer3 не имеет предделителя 1:48, вместо него следует использовать Timer0 или Timer1.

После того как массив сформирован, в основной программе перед запуском генерации зеленого цвета заводите переменную
int index = 0;
в которой хранится индекс элемента массива green отрабатываемой в таймере задержки. После этого запускаете таймер и искусственно инициируете его переполнение путем записи 1 в его флаг прерывания. Это вызовет обработчик прерывания для отработки первой задержки.

Теперь в обработчике прерывания делаете следующее:
1. Загружаете в счетчик таймера очередной элемент green[index]:
TMR0 = green[index];
2. Для четных значений индекса следует запускать генерацию 50 гц, для нечетных гасить. В последнем случае следует насильственно заисать 0 в пин порта, чтобы при остановке таймера 50гц на выходе пина был 0.
if (index & 1) // нечетные значения index
{
Stop timer 50 Hz;
P0.* = 0; // вместо * должен стоять конкретный номер пина.
}
else // четные значения index
Start Timer 50 Hz;
3. Увеличиваете индекс массива по модулю 6:
if (++index == 6)
index = 0;

Флаги прерывания от таймеров 0 и 1 автоматически сбрасываются при обработке прерывания.
Реклама
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Большое спасибо!
Контактная информация:
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Сейчас сделал то, что Вы написали. компилятор ругается на "TMR0 = green[index];" пишет *** ERROR C202 IN LINE 313 OF USB_MAIN.C: 'TMR0': undefined identifier . Я так понимаю, что число из массива надо разбить на 2 части и по отдельности записать в TMR0H и TMR0L? Если да, то как это можно сделать?
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Да, Вы правы. Загрузить побайтно переменную period типа int в счетчик таймера можно, например, так:
TH0 = *((char*)&period+1);
TL0 = *(char*).
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Прошу прощения, не понял: что обозначает * после оператора присвоения и после char, и что обозначает period?
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Вместо period в Вашем случае следует подставить элемент массива green[index].
A звездочки нужны для того, чтобы заставить компилятор С обратиться к байтам переменной типа int, занимающей 2 байта. Конструкцией &period получает адрес переменной period, затем (char*)&period преобразует адрес (pointer) на переменную типа int в адрес на 1-байтовую переменную типа char (по-английски это называется casting). После того как получен адрес на байт, еще одна здездочка в *(char*)&period нужна для доставания переменной по этому адресу (по англ. это dereferencing the pointer). Также и в загрузке TH0, но там следует перед dereferencing добавить к адресу 1 для доступа к старшему байту числа. Все эти ухищрения нужны для генерации кода типа такого:
mov A, period
mov TH0, A
mov A, period+1
mov TL0, A
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Все, разобрался, спасибо! Еще появился вопрос: в книжке Николайчука упоминается, что интерфейс C2 является одной из версий JTAG, и что МК семейства С8051 можно прошивать через JTAG. Это относится ко всему семейству, или только к отдельным МК? (спрашиваю, так как фирменный программатор еще не купил)
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

JTAG поддерживают только очень немногие модели семейства C8051. В частности, F340 программируется только через C2.
Открыл глаза
Сообщения: 61
Зарегистрирован: Вт авг 14, 2012 21:13:42
Откуда: Санкт-Петербург

Сообщение PetrB09 »

Понятно, жаль... А с обработчиком прерывания я правильно понимаю, что для того, что бы завести другие сигналы, надо сделать такой же алгоритм обработчика как и с зеленым, только исправив название массива и условие обнуления переменной index?
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3784
Зарегистрирован: Ср дек 24, 2008 09:58:58

Сообщение Ser60 »

Да, Вы все правильно поняли. Еще следует завести переменную, например, color, в которой будет код генерируемого цвета и в обработчике прерываний устроить case соответствующий ее значением с кодами для генерации соответствующих цветов.

Кстати, я давно хотел написать, что по-видимому эта дискуссия никого более не интересует. Что если мы передем на общение через личные сообщения, дабы не засорять форум? Если согласны - в следующий раз пишите сразу туда.
Ответить

Вернуться в «Интеграция с ПК»