Большой Воронежский Форум
»Радиолюбитель>Контроллеры AVR 8бит. Помощь друг другу.
Cheb-burashka 21:19 22.12.2011
Тема создана для обмена опытом и решения вопросов при программировании 8-битных контроллеров семейства AVR.

Кто чем пользуется для симуляции и отладки?
Написал большую программу на Сях (тьфу, на все эти компиляторы... куда как проще с асмом, но писать много... зато все четко и однозначно) для меги16, а отладить не удается. В AVRStudio (с winavr) нет периферии - нет наглядности. Протеус глючит, еще и пошагать по Си нормально не удается, то ли .elf скуден на шаги, то ли... Почитал методличку про VMLab - с периферией скудно, задавать схему руками - долго, попытался Си загнать (а у меня много файлов) - не получилось с ходу. Там еще и .cof для отладки подавать надо.

Кто чем пользуется для симуляции и отладки? [Ответ]
astahov 22:45 22.12.2011
Компилятор ImageCraft
Симулятор Proteus [Ответ]
Krivoy 08:46 23.12.2011
Компилировал IAR-ом. Отлаживается в протеусе. Cheb-burashka, не вводи людей в заблуждение. Если чего-то не работает или глючит - пиши версию продукта и конкретно, что не работает. Есть вещи априори не симулируемые в протеусе. Протеус - эхо не панацея, а удобный и наглядный иструмент для накидать поиграться. Если что-то серьезное, то полюбому надо в железе делать и смотреть. [Ответ]
-=Женек=- 09:37 23.12.2011
Пишу в CodeVision, за что себя ненавижу. Но что делать - привык.
Отлаживаю тоже как привык - вывожу промежуточную информацию либо на подключенный дисплей, либо через USART в комп.

Сообщение от :
Там еще и .cof для отладки подавать надо.

А в чем проблема-то? У меня cof Протеус требовал, когда я пару раз в нем что-то ради интереса запускал. Неудобств я не ощутил. В CodeVision cof генерит. [Ответ]
Cheb-burashka 10:27 23.12.2011
вас понял буду пробовать все подряд. [Ответ]
Cheb-burashka 12:25 23.12.2011
В прерывании по таймеру0 сделан опрос 4-х кнопок и динамическая индикация на 4-х значном семисегментном светодиодном дисплее. По четырем ножкам порта В бегает циклично один НУЛЬ.

Но, Ахринеть! Какая подлая оказалась конструкция "помахать ножкой в Сях"...
PORTB=PORTB^(1<<PB5);
Не-е, она удобна, для отладки. Втыкаешь в нужное место программы и... видишь, что порт В перестает работать как надо...

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

Все очень просто.
PORTB=PORTB^(1<<PB5);
компилируется винавром в

+0000007B: B388 IN R24,0x18 In from I/O location
+0000007C: 2782 EOR R24,R18 Exclusive OR
+0000007D: BB88 OUT 0x18,R24 Out to I/O location

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

Так что ж теперь вокруг каждого изменения порта в основной программе делать запрет и разрешение прерываний что ли? [Ответ]
pt200___dr.ON 17:26 23.12.2011

Сообщение от Cheb-burashka:
Так что ж теперь вокруг каждого изменения порта в основной программе делать запрет и разрешение прерываний что ли?

Смотря как менять. Один бит выставляется,сбрасывается без проблем.
По маске да будут проблемы, если прерывашка этот же порт использует.

P.S.
Код:
if( PORTB & (1<<PB5))
  PORTB &= ~(1<<PB5);
else
  PORTB |= (1<<PB5);
ПРи условии, что в прерывании этот же бит не используется [Ответ]
Cheb-burashka 19:06 23.12.2011

Сообщение от pt200___dr.ON:
Смотря как менять. Один бит выставляется,сбрасывается без проблем.

Особенно если в ассемблере пишешь.

pt200___dr.ON, с вашим кодом те же проблемы. В зависимости от уровня оптимизации винавра получаем

Нулевой уровень:


Код:
if( PORTB & (1<<PB5))
     1ec:	e8 e3       	ldi	r30, 0x38	; 56
     1ee:	f0 e0       	ldi	r31, 0x00	; 0
     1f0:	80 81       	ld	r24, Z
     1f2:	88 2f       	mov	r24, r24
     1f4:	90 e0       	ldi	r25, 0x00	; 0
     1f6:	80 72       	andi	r24, 0x20	; 32
     1f8:	90 70       	andi	r25, 0x00	; 0
     1fa:	00 97       	sbiw	r24, 0x00	; 0
     1fc:	41 f0       	breq	.+16     	; 0x20e <main+0xf2>
  PORTB &= ~(1<<PB5);
     1fe:	a8 e3       	ldi	r26, 0x38	; 56
     200:	b0 e0       	ldi	r27, 0x00	; 0
     202:	e8 e3       	ldi	r30, 0x38	; 56
     204:	f0 e0       	ldi	r31, 0x00	; 0
     206:	80 81       	ld	r24, Z
     208:	8f 7d       	andi	r24, 0xDF	; 223
     20a:	8c 93       	st	X, r24
     20c:	d7 cf       	rjmp	.-82     	; 0x1bc <main+0xa0>
else
  PORTB |= (1<<PB5);
     20e:	a8 e3       	ldi	r26, 0x38	; 56
     210:	b0 e0       	ldi	r27, 0x00	; 0
     212:	e8 e3       	ldi	r30, 0x38	; 56
     214:	f0 e0       	ldi	r31, 0x00	; 0
     216:	80 81       	ld	r24, Z
     218:	80 62       	ori	r24, 0x20	; 32
     21a:	8c 93       	st	X, r24
     21c:	cf cf       	rjmp	.-98     	; 0x1bc <main+0xa0>

Первый уровень:

Код:
if( PORTB & (1<<PB5))
 160:	f8 01       	movw	r30, r16
 162:	80 81       	ld	r24, Z
 164:	85 ff       	sbrs	r24, 5
 166:	04 c0       	rjmp	.+8      	; 0x170 <main+0xc4>
  PORTB &= ~(1<<PB5);
 168:	80 81       	ld	r24, Z
 16a:	8f 7d       	andi	r24, 0xDF	; 223
 16c:	80 83       	st	Z, r24
 16e:	e9 cf       	rjmp	.-46     	; 0x142 <main+0x96>
else
  PORTB |= (1<<PB5);
 170:	f8 01       	movw	r30, r16
 172:	80 81       	ld	r24, Z
 174:	80 62       	ori	r24, 0x20	; 32
 176:	80 83       	st	Z, r24
 178:	e4 cf       	rjmp	.-56     	; 0x142 <main+0x96>

Второй уровень и выше (вот тут стало нормально):
Код:
if( PORTB & (1<<PB5))
 126:	c5 9b       	sbis	0x18, 5	; 24
 128:	02 c0       	rjmp	.+4      	; 0x12e <main+0x82>
  PORTB &= ~(1<<PB5);
 12a:	c5 98       	cbi	0x18, 5	; 24
 12c:	ec cf       	rjmp	.-40     	; 0x106 <main+0x5a>
else
  PORTB |= (1<<PB5);
 12e:	c5 9a       	sbi	0x18, 5	; 24
 130:	ea cf       	rjmp	.-44     	; 0x106 <main+0x5a>
[Ответ]
Krivoy 15:07 27.12.2011
Запости на microchip.su в раздел других микроконтроллеров. Там тебе все разжуют как надо. [Ответ]
Cheb-burashka 15:23 27.12.2011
Я вообще в Си для МК не верю. АСМ - что ты написал, то он и сделал. [Ответ]
-=Женек=- 17:29 27.12.2011

Сообщение от :
Я вообще в Си для МК не верю. АСМ - что ты написал, то он и сделал.

И зря.
Есть задачи для МК, которые невозможно написать на С. Есть и другие задачи, которые на АСМе выполнить можно, но это неуважение к себе и своему времени.
Что касается "что написал, то и сделал" - тоже не соглашусь. Мне удавалось на С писать программы для задач, где нужно было дрыгать ножками с точностью до такта.
Скажу более - одно время мучил на electronix.ru народ расспросами про то как SDRAMом порулить с помощью AVR. И все как один писали - без асма не получится, С нагородит тебе такого что... Тем не менее, я написал программу для управления SDRAM на С, работает как часы.

Не спорю, что АСМ рациональнее, но я в "С для МК" верю. [Ответ]
Cheb-burashka 21:25 27.12.2011
ды писал я на Сях не раз. И с точностью до такта: термостат с программным 1Wire червертый год на балконе теплицу с кактусами обслуживает. Но в Си приходится все время как-то извращаться чтобы компилятор сделал так так ты хочешь. Сделал изменения в одном куске программы, скомпилил, а компилятор посмотрел на всю программу, подумал и соптимизировал так, что другой кусок программы перестал работать. и приходится кругом волатиле вставлять и т.д. У МЕНЯ это какая-то ловля блох получается.
В асме это только кажется, что писать много, на самом деле, там много копи-пасты. Надо только сесть и один раз хорошо подумать про распределение регистров и память для нужд программы. [Ответ]
-=Женек=- 07:02 30.12.2011

Сообщение от :
Но в Си приходится все время как-то извращаться чтобы компилятор сделал так так ты хочешь. Сделал изменения в одном куске программы, скомпилил, а компилятор посмотрел на всю программу, подумал и соптимизировал так, что другой кусок программы перестал работать. и приходится кругом волатиле вставлять и т.д. У МЕНЯ это какая-то ловля блох получается.

ПРиведи примеры, когда программа написанная на С, с алгоритмом, отвечающим логике и здравому смыслу, не работает только потому, что она на С, а не на асме. Вот я обыкновенный любитель, знаю АВР и С неплохо, но изучал их "хватая верхушки". ПО идее я уже сто раз должен был столкнуться с ситуацией, когда программа по идее должна работать но не работает, и кроме асма ничто помочь не может. [Ответ]
Krivoy 11:55 30.12.2011
Женек, писать на С для контроллеров надо правильно, а это не всегда очевидно - учиться надо, в том числе и под конкретный компилятор. асм дуболомный, что написал - то и получил, поэтому иногда он более наглядный получается, но там своих заморочек выше крышы, особенно если что-то нетивиальное или большое надо изобразить. [Ответ]
-=Женек=- 15:21 30.12.2011
Krivoy,
Я все понимаю, но я мыслю прагматически. На Си пишется быстрее (особенно сложные приложения с графикой), а время - это деньги. Если я напишу проект с картинками, менеюшками на асме, то есть затрачу время (приравненное к деньгам), то что я получу, кроме субъективного ощущения, что контроллер делает то что надо?

Окститесь господа, современный рынок диктует такие запросы, что в среде профессионалов идут дискуссии о том, что лучше (круче) использовать библиотеки на С (и экономить время, зато получать избыточный код), либо писать все самому с нуля и экономить память контроллера, а также ощущать невъ...нную длину своей пичужки.
Все зависит от задачи. Еслу нужно на самом мелком контроллере написать самую быстроу прогорамму, тогда асм в руки. А если память позволяет, если время поджимает, если дороги свои нервы, то ЛЮБУЮ работающую программу на Си написать можно. [Ответ]
Cheb-burashka 16:35 30.12.2011
-=Женек=-, если я делаю единичное устройство, то вопрос не стоит, а если я производитель неких устройств в большом количестве, то мне выгоднее затратить один раз время на написание "правильной" программы для меги16, и дальше клепать устройства в большом количестве с дешевой микросхемой, чем я за полчаса напишу код на Си с использованием "универсальных" библиотек, только он с трудом влезает в мегу256.

Есть два подхода к созданию устройства, радикально различающихся:
1. подход проектировщика железа, который стремится удешевить железку и сделать плату удобной в разводке. Например, отказываемся от всяких преобразователей интерфейсов (1Wire, USB), будем писать их программно. Разводим порт с внешней памятью так, чтобы адресные дорожки меньше пересекались, а в программе надо будет перетасовать биты адреса. ну и т.д.
2. подход программера, для которого писать что-то свое (программые интерфейсы, перетасовка битов и т.д.), это как серпом по яйцам. Ему бы готовое универсальное взять и только числа поменять на свои.

Столкновение этих двух подходов я наблюдаю уже несколько лет. У каждого своя правда.

Мне не хотелось бы, чтобы тема переосла в ASM vs C

А я все о своих баранах...

Имеем кусок на Си:
Код:
uint8_t Convert_T1(void) 
{

	uint8_t result = 1;					// результат опроса датчика

if (OW1_GetBit()){						// слушаем шину, если на шине не нуль, то общаемся с устройствами, иначе данные не меняются.
 	OW1_Reset();						// сброс 1-wire
	OW1_WriteByte(OW_SKIP_ROM_CMD);		// команда "пропустить адрес"
	OW1_WriteByte(CMD_START_CONV);		// команда "начать измерение"
}
else 
	result=0;
	return result;
}
После компиляции винавром имеем следующую хрень
Код:
000005ba <Convert_T1>:
 5ba:	88 e1       	ldi	r24, 0x18	; 24
 5bc:	8a 95       	dec	r24
 5be:	f1 f7       	brne	.-4      	; 0x5bc <Convert_T1+0x2>
 */
uint8_t OW1_GetBit(void) 
{
    uint8_t result;
	ow_delay;			// ???
	cli();
 5c0:	f8 94       	cli
	wire1_0;
 5c2:	be 9a       	sbi	0x17, 6	; 23
 5c4:	8e e0       	ldi	r24, 0x0E	; 14
 5c6:	8a 95       	dec	r24
 5c8:	f1 f7       	brne	.-4      	; 0x5c6 <Convert_T1+0xc>
	_delay_us(6);		// начало тайм-слота
	wire1_1;
 5ca:	be 98       	cbi	0x17, 6	; 23
 5cc:	81 e1       	ldi	r24, 0x11	; 17
 5ce:	8a 95       	dec	r24
 5d0:	f1 f7       	brne	.-4      	; 0x5ce <Convert_T1+0x14>
	_delay_us(7);		// опрос на 14-й микросекунде
	result = (OW1_PIN << (7-OW1_P)) & 0b100000000;
 5d2:	86 b3       	in	r24, 0x16	; 22
	sei();
 5d4:	78 94       	sei
 5d6:	8d ed       	ldi	r24, 0xDD	; 221
 5d8:	8a 95       	dec	r24
 5da:	f1 f7       	brne	.-4      	; 0x5d8 <Convert_T1+0x1e>
	OW1_WriteByte(CMD_START_CONV);		// команда "начать измерение"
}
else 
	result=0;
	return result;
}
 5dc:	80 e0       	ldi	r24, 0x00	; 0
 5de:	08 95       	ret
Возникают вопросы
куда делся ресет, куда делась команда "прокинуть адрес", куда делась команда "конвертировать температуру", и почему читая на строке 5d2 в R24 из порта, он напрочь забывает об этом на строке 5d6, записывая в R24 уже 0xDD... [Ответ]
-=Женек=- 22:23 30.12.2011

Сообщение от :
1. подход проектировщика железа, который стремится удешевить железку и сделать плату удобной в разводке. Например, отказываемся от всяких преобразователей интерфейсов (1Wire, USB), будем писать их программно. Разводим порт с внешней памятью так, чтобы адресные дорожки меньше пересекались, а в программе надо будет перетасовать биты адреса. ну и т.д.
2. подход программера, для которого писать что-то свое (программые интерфейсы, перетасовка битов и т.д.), это как серпом по яйцам. Ему бы готовое универсальное взять и только числа поменять на свои.

Ну так хорошо если один и тот же человек занимается и разводкой и программерством. Мне практически в каждом проекте приходится искать компромисы между вещами на которые ты указал. А вообще что программер, что железячник должны знать работу друг друга. К примеру, про перестановку битов - в SDRAM биты данных можно переставлять совершенно безболезненно. Грамотный железячник это знает, а вменяемый программер, которому принесут такую плату, на эту операцию не обидится. [Ответ]
-=Женек=- 22:29 30.12.2011
Я просто, сказать по правде, под впечатлением. Разбираюсь с STM32, в тихом ужасе от его навороченности. И просто в шоке от одной мысли, что кто-то умудряется писать под этот камень на асме... [Ответ]
@MO:ZG@ 18:20 10.01.2012
А я извращенец, пишу в 5й студии, там же проводу предварительную отладку, а потом заливаю в свои отладочные платы, когда то понаделал их, теперь помогают Кстати всё работает отлично [Ответ]
Krivoy 20:24 11.01.2012
Народ, на самом деле для особых эстетов асемблерные вставки рулят, почти всегда, только в настоящее время для 80% случаев даже они не нужны. Случай миллионных тиражей не будем рассматривать... Лучше то что лучше знаешь и чем лучше умеешь пользоваться. Человек в совершенстве владеющий асмом и С будет писать на С (заставляя компилятор правильно работать, в том числе и с помощью вставок и директив) исходя чисто из прагматических соображения. Просто есть всякие разные извращенные случае, когда может оказаться проще на чистом асме наваять, чем победить конкретную версию компилятора под конкретный камень. Короче спор не о чем... [Ответ]
Вверх