Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Похоже я прогневал кого-то из программистских богов.
Пытался выделить функцию hc595send() в отдельный файл, чтоб спокойно потестить логические функции - она отказалась работать. Притащил осциллограф, чтоб посмотреть чего выдает аттини13, а после измерений он отказался прошиваться через усбасп. Сходил за большим программатором (top-3000), вставил тиньку, сбросил на заводские фузы, все шьется, все хорошо. Подключил к усбасп - не шьется. Опять в большой программатор, подключаю его к компу - венда выдает синего.
Кажется, на сегодня хватит.
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Добрый день!
Возникла проблема. Компилятор опять ругается:

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

D:\avr>make func_test.c attiny13a
func_test.c: In function 'main':
func_test.c:123:2: warning: '__progmem__' attribute ignored [-Wattributes]
  const unsigned char lcd_data[] PROGMEM = "Hello, Radiokot";
  ^
func_test.c:125:7: warning: assignment discards 'const' qualifier from pointer t
arget type [enabled by default]
  dptr = lcd_data;
       ^
Явно что-то не так, но при этом (что необычно) все работает так, как хотел. :shock: Догадываюсь, накосячил с указателем, но как?

Функция main():

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

	{
	setup();
	lcd_init();
	lcd_setup();	
	const unsigned char lcd_data[] PROGMEM = "Hello, Radiokot";
	char *dptr;
	dptr = lcd_data;
	int i;
		for (i = 0; i < 14; i ++)
		{
		send_data(*dptr);
		dptr++;
		}
	}
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Shuspano писал(а):Явно что-то не так, но при этом (что необычно) все работает так, как хотел.
работает - потому что не ошибка, а варнинг.
а не так то, что dptr у вас "указатель на символ" (т.е. на ОЗУ), а массив lcd_data - это "массив неизменяемых символов во FLASH", то есть типы указателей не одинаковы, вот и предупреждает.

совет вам: избавляйтесь от PROGMEM, заменяйте это на корректное и правильное const __flash (вы ж не WinAVR используете? новые версии так могут):

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

const __flash unsigned char lcd_data[] = "Hello, Radiokot";

const __flash char *dptr;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Спасибо!
Не, у меня блокнот, avr-gcc, и дудка. Я просто знаю как это делать на ассемблере: строка размещается директивой DB, адрес строки в16-битный регистр-указатель, а там - MOVC или LPM. Я погуглил, нашел кое что у DI HALT, и решил что PROGMEM - это аналог этой директивы.
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Shuspano писал(а):Не, у меня блокнот, avr-gcc, и дудка.
и чо? WinAVR - это довольно древняя версия avr-gcc. если у вас свежая версия - пользуйтесь тем, что я рекомендовал.
Shuspano писал(а):Я просто знаю как это делать на ассемблере
забудьте! если взялись за Си, пользуйтесь средствами Си, чтобы быстрее войти в струю. разумеется, запаситесь справочником каким-нибудь по основным определениям, правилам, функциям и т.п. для Си. и реализовывайте свои алгоритмы уже этими средствами.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

[uquote="Shuspano",url="/forum/viewtopic.php?p=3841042#p3841042"]Догадываюсь, накосячил с указателем, но как?[/uquote]
можно попрбовать

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

const char *dptr;
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Не, так не компиляется

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

D:\avr>make func_test.c attiny13a
func_test.c: In function 'main':
func_test.c:123:2: error: '__flash' specified for auto variable 'lcd_data'
  const __flash unsigned char lcd_data[] = "Hello, Radiokot";
  ^
avr-objcopy: 'func_test.elf': No such file
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Добавлено after 1 minute 15 seconds:
кстати, для символьных строк правильнее применять просто char, а не unsigned char - все стандартные функции рассчитаны именно на char - будете ловить варнинги...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

[uquote="Shuspano",url="/forum/viewtopic.php?p=3841090#p3841090"]Не, так не компиляется[/uquote]
так норм.
Изображение
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

В общем, это сделать невозможно. Как только не пробовал, засыпает ошибками. Потому, буду использовать первоначальный рабочий вариант.
Простых понятных примеров рабочего прогмема класса хеллворлд найти не могу, везде либо простынки где непонятно что к чему, либо еще менее понятные какие-то двухкоординатные char[j]
Хочу допилить и сделать покрасивше подпрограммы для индикатора. В связи с тем вопрос: а как ставить и снимать биты в unsigned char в одной строке одновременно?
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

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

a |= (1<3); // установить бит 3 переменной a
a &= ~(1<<3); // очистить бит 3 переменной a
Ну или макрос _BV есть
Контактная информация:
Грызет канифоль
Аватара пользователя
Сообщения: 270
Зарегистрирован: Вс окт 20, 2019 13:03:56

Сообщение Shuspano »

Так я знаю. Но вроде как можно в одну строку... или нет?
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

А чем это не в одну строку? Или нужно и то и другое сразу? Если так, то можно тое накрутить каким-нибудь макросом, но стандартного простого способа вроде как нет.

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

a = (a | ((1<<2) | (1<<0))) & ~((1<<4) | (1<<1));
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Нуу.... проще и нагляднее в 2 строки написать, если не все биты меняются. А то получается хрень, вроде такой:

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

a = (a | (1 << 0)) & (a & ~(1 << 1));
Добавлено after 4 minutes 39 seconds:
А, ну да, WiseLord правильнее написал, у меня лишний шаг И.
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

NStorm писал(а):Нуу.... проще и нагляднее в 2 строки написать

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

a = (a | (1 << 0)) 
  & (a & ~(1 << 1));
Так нагляднее, а с точки зрения компилятора это одна строка.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

[uquote="Shuspano",url="/forum/viewtopic.php?p=3841172#p3841172"]Но вроде как можно в одну строку...[/uquote]

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

a |= (1<3); a &= ~(1<<3);
:)
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Господа, не забыаайте, что вы с AVR имеете дело. При работе с портами такие директивы компилятор в CBI и SBI транслирует. Одним выражением (не строкой конечно же, тут вас Аlex круто подколол) будет "чтение - модификация - запись".
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

При работе с портами такие директивы компилятор в CBI и SBI транслирует
Только если будет меняться всего 1 бит. Если больше 1го, всё-равно будет R-M-W с OR/AND.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18682
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

[uquote="Shuspano",url="/forum/viewtopic.php?p=3841172#p3841172"]Так я знаю. Но вроде как можно в одну строку... или нет?[/uquote]
В Си нет прямой связи между количеством строк и чем-то ещё, размером кода, например, или скоростью его исполнения. Зато часто прослеживается связь "меньше строк - менее понятно - больше вероятность ошибки".

Добавлено after 2 minutes 14 seconds:
[uquote="NStorm",url="/forum/viewtopic.php?p=3841259#p3841259"]Только если будет меняться всего 1 бит. Если больше 1го, всё-равно будет R-M-W с OR/AND.[/uquote]так вроде и SBI тоже RMW... Или я путаю?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Не, SBI/CBI - одна инструкция на асме.
Зато часто прослеживается связь "меньше строк - менее понятно - больше вероятность ошибки".
Ну это имеет смысл, если по какой-то причине установку и снятие бита надо проводить атомарно, при этом не весь регистр писать. За всё время в реальности ни разу такой необходимости не встречал...
Ответить

Вернуться в «Разные вопросы по МК»