как правильно выключить таймер ( asm )

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

Сообщение uwrtey »

Всех приветствую
Всех с Наступающим

Задался вопросом:
А правильно ли я выключаю таймер ( в принципе, тут не только таймер, в обще переинициализация чего либо )
пример:

Завожу ШИМ на таймер_0

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

; Таймер_0  ( 8 бит )
				

	ldi Temp, (1<<COM0A1)|(1<<WGM01)|(1<<WGM00)
	out TCCR0A, Temp	
				
	
	ldi Temp, (1<<cs02)|(1<<cs00)	
	out TCCR0B, Temp					


	ldi Temp, 0x1E	
	out OCR0A, Temp

А затем приспичило мне отключить этот ШИИ
И делаю вот так

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

; глушим ШИМ вентилятора, что-бы мотор не "гудел"

	ldi Temp, (0<<cs02)|(0<<cs01)|(0<<cs00)	
	out TCCR0B, Temp					

А правильно ли это?

В обще можно ли так "(0<<cs02)" делать?

Я к чему спрашиваю - Обычно делают так "(1<<cs02)", а в остальные биты компилятор сам вставляет нули....

Ну и естественно, если я делаю не правильно то покажите пожалуйста свои варианты. ( как вернуть регистр к значениям по умолчанию? )

Я вижу еще один вариант:

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

; глушим ШИМ вентилятора, что-бы мотор не "гудел"

	ldi Temp, 0
	out TCCR0B, Temp					

не зная броду не лезь к вольтмоду
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

uwrtey писал(а):ldi Temp, (0<<cs02)|(0<<cs01)|(0<<cs00)   
   out TCCR0B, Temp 
это абсолютно эквивалентно
uwrtey писал(а):   ldi Temp, 0
   out TCCR0B, Temp 
ноль что там, что там.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

Сообщение uwrtey »

Я про запись (0<<cs02)
Можно ли в обще так делать?
Нет ли причин, что бы так не записывать?

Где то я слышал ( очень давно и поэтому не помню точно ) что такую запись можно делать только с единицей и записывать вместо единицы нуль нет смысла.
То ли компилятор не поймет. То ли правила "языка написания кода" это не позволяют..
это абсолютно эквивалентно
Это я понимаю.
не зная броду не лезь к вольтмоду
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Рекомендую разобраться с битовыми операциями и булевой алгеброй, тогда подобных вопросов станет куда меньше.
Запись (0<<x) с точки зрения языка корректна, но бесполезна. Результаты (0<<0), (0<<1), (0<<255) одинаковы.
Иногда такая запись имеет смысл - когда настраивается набор связанных битов, чтобы можно было изменить настройки заменой 0 на 1, а не дописыванием сдвига.
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

Сообщение uwrtey »

Спасибо, все ясно. :beer:
COKPOWEHEU писал(а):но бесполезна
Не совсем. В данном случае код становится более "читаемым" ( ИМХО )

Иначе бы код вместо такого:

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

 
   ldi Temp, (1<<cs02)|(1<<cs00)   
   out TCCR0B, Temp               
выглядел вот так:

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

         
   ldi Temp, 0b00000101   
   out TCCR0B, Temp               
или еще хуже:

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

       
   ldi Temp, 5   
   out TCCR0B, Temp               
не зная броду не лезь к вольтмоду
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Я смотрю вы мое сообщение не прочитали. Структуры (1<<x) использовать НАДО для улучшения читаемости кода. Структуры вида (0<<x) бессмысленны, но ИНОГДА МОГУТ быть использованы для улучшения читаемости кода.
Например, в записи TCCR0 = (1<<CS02 | 0<<CS01 | 1<<CS00); такая структура полезна, а в PORTB = (1<<7 | 0<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1 | 0<<0); только затрудняет понимание.
Реклама
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

Использовать запись вида для установки бита

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

ldi temp,(1<<CS01)
out TCCR0B,temp
надо только с полным пониманием того, что делаешь, потому что при этом все остальные биты регистра будут сброшены.
Возьмите, например, регистр EIMSK контроллеров мега640/1280...
Там каждый бит отвечает за разрешение "своего" внешнего прерывания. Допустим, у Вас в начале программы было разрешено прерывание INT0 (в регистре значение 0х01, установлен бит INT0), а где-то в середине Вы решили разрешить еще и прерывание INT2, для чего требуется установить бит INT2 в регистре EIMSK. Вы, ничтоже сумняшеся, пишете

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

ldi temp,(1<<INT2)
out EIMSK,temp
И Вы таки да, разрешаете внешнее прерывание INT2, но одновременно запрещаете INT0
Поэтому в таких случаях надо использовать конструкцию

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

in temp,EIMSK
ori temp,(1<<INT2)
out EIMSK,temp
А вообще, AVR Studio позволяет использовать следующие конструкции:

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

ori temp,(1<<BIT0)|(1<<BIT2)
для установки указанных бит в регистре temp и

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

andi temp,~((1<<BIT0)|(1<<BIT2))
для сброса этих же бит, при этом состояние остальных бит не изменится.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

uwrtey писал(а):Не совсем. В данном случае код становится более "читаемым" ( ИМХО )
Код был бы более читаемым, если бы inc-файлы описания периферии были сделаны как у всех нормальных систем. Типа такого:
Спойлер

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

;	TCCR0 - регистр управления таймера/счетчика 0

.equ	T0Off		=0x00	; T0 выключен
.equ	T0Clk1		=0x01	; T0Clk = ClkIO (no prescaling)
.equ	T0Clk8		=0x02	; T0Clk = ClkIO / 8
.equ	T0Clk64		=0x03	; T0Clk = ClkIO / 64
.equ	T0Clk256	=0x04	; T0Clk = ClkIO / 256
.equ	T0Clk1024	=0x05	; T0Clk = ClkIO / 1024
.equ	T0Clk10Ext	=0x06	; Внешний сигнал, срабатывание при переходе из 1 в 0
.equ	T0Clk01Ext	=0x07	; Внешний сигнал, срабатывание при переходе из 0 в 1

;	Бит для TIMSK

.equ	T0IEOfl		=0x01
Тогда да, очень наглядно. Потребовалось запустить таймер с прескалером 64 пишешь:

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

 LDI   R16,T0Clk64
 OUT   TCCR0,R16
Потребовалось выключить этот таймер, пишешь:

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

 LDI   R16,T0Off
 OUT   TCCR0,R16
Но увы, inc-файлы для AVR, похоже, сочиняли недоученные паскалянты, которые ни разу в жизни не написали на асме ни одной строчки, и вообще, кроме писюка, других компьютеров не видели. :kill:

Нет, отчасти я их понимаю. Они хотели предоставить удобное средство для манипулирования битами посредством команд SBI/CBI. И оно действительно удобно, только, во-первых, даже у самого первого AT90S1200 почти половина регистров через эти команды недоступна, а у камушков посовременнее, с Memory Mapped I/O - и все 2/3, а то и 3/4. Во-вторых, в этом варианте категорически неудобно манипулировать периферией посредством других команд (не SBI/CBI).

Более того, с таким определением битов, манипулировать периферией неудобно не только на асме. На Си все выглядит еще хуже, там не воспользуешься напрямую командами SBI/CBI (хотя компилятор и использует их по возможности), но программисту, допустим, для установки срабатывания прерывания INT1 по возрастающемы фронту сигнала на этой ноге по-любому придется писать что-то, вроде ((1<<ICS11) | (1<<ICS10)), хотя, по-хорошему, надо было определить константы Ics1Low = 0x00, Ics1Any = 0x04, Ics1FallEdg = 0x08 и Ics1RisEdg = 0x0C в соответствующей нотации (Си, Асм), и никаких вопросов бы не возникло ни при программировании, на Си, ни на Асме.

Короче, все плохо. Тем более, что AVR всё! Новых камней не будет, нынешние, вскорости, попадут в Obsolete, и до свидания!.. Короче, все идем учить STM32.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

afz писал(а):Потребовалось запустить таймер с прескалером 64 пишешь:

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

 LDI   R16,T0Clk64
 OUT   TCCR0,R16
Потребовалось выключить этот таймер, пишешь:

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

 LDI   R16,T0Off
 OUT   TCCR0,R16
Что мешает определить константы T0Clk64 и T0Off самому? Невозможно в inc-файле предусмотреть все варианты, которые могут потребоваться программисту. Никто не запрещает программисту самому определить те варианты, которые ему необходимы.
afz писал(а):Короче, все идем учить STM32.
В добрый путь
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

afz писал(а):Ics1Low = 0x00, Ics1Any = 0x04, Ics1FallEdg = 0x08 и Ics1RisEdg = 0x0C в соответствующей нотации (Си, Асм), и никаких вопросов бы не возникло ни при программировании, на Си, ни на Асме.
Как Вы представляете применение таких определений для бит ориентированных команд? Например sbi , sbrc и прочее.
afz писал(а):Короче, все плохо. Тем более, что AVR всё! Новых камней не будет, нынешние, вскорости, попадут в Obsolete, и до свидания!.. Короче, все идем учить STM32.
Мне кажется выбор несколько шире, чем красная и синяя пилюля. Кстати, атмеломикрочип уже выпустил новую линейку МК, о чем товарищ ВОВ51 запостил пару тем в "разных вопросов по МК".
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Alkul писал(а):Что мешает определить константы T0Clk64 и T0Off самому?
Если делаешь проект в гордом одиночестве - ничего. Кроме самой необходимости написать все это, раз производитель МК не сделал этого нормально. Ну, может быть, при переносе проекта на другой камушек, понадобится написать то же самое еще и для него. При этом надо подавить свое желание скопипастить по-простому, поскольку у нового камушка что-то может отличаться, в каком-нибудь малозаметном месте. Был у меня подобный прецедент при переносе проекта с 8-й Меги на Мегу 8515.

А вот если работать в команде, то добавляется необходимость согласования.
Z_h_e писал(а):Как Вы представляете применение таких определений для бит ориентированных команд?
Для бит-ориентированных команд (и только для тех битов, для которых это имеет смысл) - путем добавления к этому определению префикса или суффикса, указывающего, что это не значение бита, а его номер. Возьмем, например, регистр ADCSRA (ADC). По=хорошему бы задать ADEN=0x80, а, допустим, Bit_ADEN=7. Ну, и, соответственно, ADSC=0x40, Bit_ADSC=6 и т.д. А вот USART'овские биты (UPM1, UPM0) и (USZ2-USZ0) - это не отдельные 2 и 3 бита, а двух- и трехбитовые поля, манипулировать их отдельными битами нет никакого смысла, несмотря на то, что они доступны для адресации командами SBI/CBI. Равно, как и с полями ADC - (REFS1,REFS0) и (MUX3-MUX0). Ну, и для всех регистров с адресом, бОльшим 0x1F, номера битов вообще малополезны, напрямую ими не воспользуешься, их бы, как раз, описать только значениями.
Alkul писал(а):Невозможно в inc-файле предусмотреть все варианты, которые могут потребоваться программисту
Так все варианты и не нужны. Вернее, их всего два: определять значения битов или определять их номера. И, как я только что изложил, даже не для всех для регистров с адресами 0-0x1F полезны именно номера битов, для всех полей в несколько битов, значения явно полезнее перечисления номеров битов, входящих в эти поля. А для регистров с адресом больше, чем 0x1F номера битов вообще бесполезны, значений же нам не предложили - пишите сами!..
Z_h_e писал(а):Кстати, атмеломикрочип уже выпустил новую линейку МК
Скорее всего, это то, что Атмел разработал непосредственно перед самопродажей, а выпустить не успел. Так, что выпустил эти камушки уже Микрочип - не пропадать же добру!.. А дальнейшие разработки, наверняка свернут, все новые наработки пойдут на усовершенствование ПИКов, а не АВР-ок.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

afz писал(а):Для бит-ориентированных команд (и только для тех битов, для которых это имеет смысл) - путем добавления к этому определению префикса или суффикса, указывающего, что это не значение бита,
Приведите рабочий пример.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Z_h_e писал(а): Приведите рабочий пример.
Перечитал все внимательно и понял, что я в прошлый раз ответил немного не на тот вопрос.
Z_h_e писал(а):Как Вы представляете применение таких определений для бит ориентированных команд? Например sbi , sbrc и прочее.
Таких определений - никак. Производитель должен был предоставить отдельный набор определений для этих команд, в дополнение к определеням со значением битов и полей. Самым простым решением было бы использовать то же самое имя бита с дополнительным префиксом или суффиксом. То есть, допустим, определить для того же ADC бит разрешения ADC как ADEN=0x80, а для бит-ориентированных команд дополнительно определить Bit_ADEN=7. Причем такое дополнительное определение имеет смысл делать только для отдельных самостоятельных битов, которыми имеет смысл манипулировать битовыми командами. В многобитовых полях оно бесполезно - тот же мультиплексор ADC, выбор источника опорного напряжения, выбор прескалера... Даже отдельное описание номера одинокого бита ADLAR (включить "левое" представление результатов ADC) не особенно нужно, поскольку эта фенечка сделана для использования ADC в 8-битном режиме и я сильно сомневаюсь, что кто-то в одной программе будет одновременно пользовать и 8-битный и 10-битный режимы ADC. Впрочем, на последнем утверждении я сильно не настаиваю... :)

А производитель предоставил символические наименования только для номеров битов, из-за чего мы, для получения значений вынуждены корячиться со сдвигами единиц. :kill: В результате начинающие часто не могут въехать в смысл написанного.
Alkul писал(а):Что мешает определить константы T0Clk64 и T0Off самому?
В прошлый раз тоже ответил немного не на тот вопрос.

Просто эту работу должен был сделать производитель, один раз и для всех. Ладно, для отдельных битов еще кое-как сгодится и сдвиг единицы, хоть это и коряво, но набирать из этих сдвинутых единиц число, например, для номера канала аналогового мультиплексора или для прескалера таймера - верх идиотизма!

Ладно, на асме эти атмеловские определения хоть в бит-ориентированных командах годятся, а на Си нет вообще никаких средств ими воспользоваться, кроме этих дурацких сдвигов единиц. Расстрелять! Из крупнокалиберного пулемета! (с) АБС :kill:
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

afz писал(а):из-за чего мы, для получения значений вынуждены корячиться со сдвигами единиц.
чтобы меньше корячиться, я сделал универсальный файлик и теперь без него ни одного проекта не делаю.

прилагаю его - поглядите, покритикуйте. если будут добавления - предлагайте. хотите - пользуйтесь.

P.S. Для полной полезности в этот файл надо добавить селекторы по типам МК, т.к. некоторые вещи отличаются у разных моделей. но это очень трудоемко... я не стал тратить время и определил максимум общего.
Вложения
avr_helper.h
(4.86 КБ) 513 скачиваний
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Неплохо. Но главного недостатка это не отменяет. Это самопал. И при попытке использования нового для себя камешка, никто не гарантирует, что все пойдет, запросто может найтись какая-нибудь мелочь, которая у этого камешка в другом месте. Или при попытке использования какой-то периферии, которой раньше не пользовался...

И это никоим образом не отменяет того факта, что исходные материалы от Атмел сделаны коряво и косоруко! :kill:
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

afz писал(а):А производитель предоставил символические наименования только для номеров битов, из-за чего мы, для получения значений вынуждены корячиться со сдвигами единиц. В результате начинающие часто не могут въехать в смысл написанного.
Возможно было бы и неплохо, если бы были определения и того и того, но запутаться будет так же легко и с ними, если нет четкого представления что делаешь.

Вот например одно из определений для STM8

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

#define MASK_PA_ODR_ODR7         0x80
Если бы он был определен как

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

#define PA_ODR_ODR7         0x07
Вам был пришлось использовать сдвиг. В обоих случаях такие записи были бы Вам понятны, количество символов одинаковое для набивки текста, так что я не вижу какой-то особого косяка со стороны Атмел.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Z_h_e писал(а):Вам был пришлось использовать сдвиг. В обоих случаях такие записи были бы Вам понятны, количество символов одинаковое для набивки текста, так что я не вижу какой-то особого косяка со стороны Атмел.
Так я и сказал: для одиночных битов это еще терпимо, хоть и коряво. Но набирать из сдвинутых единиц двоичное число для какого-нибудь прескалера - РРРРР! Убивать!

Можно, конечно, сочинить что-то свое, подобно тому, как это сделал ARV, но это резко ограничивает мобильность. Крайне неохотно переходишь с одной АВР-ки на другую. Я вот сочинил себе что-то в том же духе для 8-й Меги, потом однажды не хватило ног, пришлось переделывать это сочинение под 8515. Сейчас пребываю в тяжких раздумьях: делать то же самое для 64-й Меги, или таки плюнуть на АВР и заняться освоением STM32...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Модератор
Аватара пользователя
Сообщения: 19077
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

afz писал(а): Но набирать из сдвинутых единиц двоичное число для какого-нибудь прескалера
а зачем набирать из сдвинутых единиц двоичное число?
лично я такую запись ненавижу. если известны положения каждого бита, проще сразу двоичное число, с единицами в нужных местах.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Starichok51 писал(а):проще сразу двоичное число,
И имена регистров тоже можно так писать. Вот только насколько этот исходник читаемый и какая вероятность ошибок?
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Starichok51 писал(а):если известны положения каждого бита, проще сразу двоичное число
дык беда в том, что у AVR некоторые вещи конфигурируются битами в разных регистрах - поубивал бы! когда речь идет о предделителе таймера - да, можно задать константу с тремя битами, которая и определит нужный коэффициент деления. но вот так просто задать константу для режима Fast PWM уже не получится - надо менять 2 регистра, и как тогда вы назовете две "полуконстанты"? отсюда и проистекает необходимость побитового наименования констант
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

Вернуться в «AVR»