Вопросы по С/С++ (СИ)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
ну сами поглядите:
1. calibrate у вас равно 0xF420
2. так как операции больше и меньше имеют одинаковый приоритет, выполняются они слева направо, т.е. как бы вот так ((0xF618<calibrate)<OxF230)
3. 0xF618<calibrate ----> 0xF618 < 0xF420. это выражение ЛОЖНО, т.е. имеет результат 0
4. теперь этот результат сравнивается с другим пределом: 0 < 0xF230 - это выражение всегда истинно, т.е. есть условие для срабатывания if
5. if срабатывает и перезаписывает вашу переменную...
1. calibrate у вас равно 0xF420
2. так как операции больше и меньше имеют одинаковый приоритет, выполняются они слева направо, т.е. как бы вот так ((0xF618<calibrate)<OxF230)
3. 0xF618<calibrate ----> 0xF618 < 0xF420. это выражение ЛОЖНО, т.е. имеет результат 0
4. теперь этот результат сравнивается с другим пределом: 0 < 0xF230 - это выражение всегда истинно, т.е. есть условие для срабатывания if
5. if срабатывает и перезаписывает вашу переменную...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- levaclaus
- Потрогал лапой паяльник
- Сообщения: 302
- Зарегистрирован: Пн янв 07, 2008 16:56:28
- Откуда: Минск
Re: Вопросы по С/С++ (СИ)
простоARV писал(а):ну сами поглядите:
1. calibrate у вас равно 0xF420
2. так как операции больше и меньше имеют одинаковый приоритет, выполняются они слева направо, т.е. как бы вот так ((0xF618<calibrate)<OxF230)
3. 0xF618<calibrate ----> 0xF618 < 0xF420. это выражение ЛОЖНО, т.е. имеет результат 0
4. теперь этот результат сравнивается с другим пределом: 0 < 0xF230 - это выражение всегда истинно, т.е. есть условие для срабатывания if
5. if срабатывает и перезаписывает вашу переменную...
Когда-то давно и не правда я писал так, девайс работает и сейчас.
if (1500<calibrate_eeprom<500) {
calibrate_eeprom=1000;
};
calibrate=calibrate_eeprom;
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
тогда в чем вопрос? если работает, значит, вы все правильно делаете. а если не работает - не правильно.
только если делаете правильно, то работает всегда, а когда не правильно - иной раз, как фишка ляжет. чувствуете разницу?
только если делаете правильно, то работает всегда, а когда не правильно - иной раз, как фишка ляжет. чувствуете разницу?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- acckyiboxxx
- Нашел транзистор. Понюхал.
- Сообщения: 182
- Зарегистрирован: Ср янв 25, 2012 07:26:40
Re: Вопросы по С/С++ (СИ)
Здравствуйте где-бы мне почитать про следующие способы записи кода :
пользоваться такой записью умею тупо зазубрив ее но хотелось-бы еще понимать , а на данный момент такая запись вызывает в моем мозгу следующий бред "порт б или равно лапа5=0 или равно лапа6=0 или равно лапа7=0 " хотя на самом деле это просто установка нужных бит порта, в данном случае в нули
и второй вопрос , почему когда я использую преобразование типов переменных размер скомпиленного файла увеличиваеться просто баснословно не стану приводить весь код но когда регистру присваиваю значение следующим образом :
то размер скомпиленного бинаря 350 байт
но когда пытаюсь работать с процентами и переволить тип float в char слкдующим образом
то получаю аж 3130 байт при этом ничего кроме этой строчки в коде не меняю (перменная hot имеет тип float)
для своих проектов юзаю avr-gcc
Код: Выделить всё
PORTB |= (0<<PB5)|(0<<PB6)|(0<<PB7);и второй вопрос , почему когда я использую преобразование типов переменных размер скомпиленного файла увеличиваеться просто баснословно не стану приводить весь код но когда регистру присваиваю значение следующим образом :
Код: Выделить всё
OCR3C = 0xff;то размер скомпиленного бинаря 350 байт
но когда пытаюсь работать с процентами и переволить тип float в char слкдующим образом
Код: Выделить всё
OCR3C = (char) (hot * 2.55);для своих проектов юзаю avr-gcc
- Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Запись абсолютно бессмысленная, поэтому Вы ее не понимаете. Приведенная строчка не делает ровным счетом ничего - логическое "или" с нулем не меняет значения.acckyiboxxx писал(а):хотя на самом деле это просто установка нужных бит порта, в данном случае в нули
А чему тут удивляться? Подключаются библиотечные функции работы с плавающей точкой.acckyiboxxx писал(а):то получаю аж 3130 байт при этом ничего кроме этой строчки в коде не меняю (перменная hot имеет тип float
- Реклама
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Стоит добавить, что AVR - это всё-таки восьмибитный целочисленный контроллер. Операции с другими числами - 16-битнными и 32-битными целыми и, особенно, дробными - разворачиваются компилятором в довольно сложные и выполняющиеся гораздо дольше конструкции над теми же целыми 8-битными. Так что размер кода вырастает катастрофически.
Кстати, подобное наблюдается и при использовании многих функций из той же stdlib (разные printf-ы и прочие).
Кстати, подобное наблюдается и при использовании многих функций из той же stdlib (разные printf-ы и прочие).
- acckyiboxxx
- Нашел транзистор. Понюхал.
- Сообщения: 182
- Зарегистрирован: Ср янв 25, 2012 07:26:40
Re: Вопросы по С/С++ (СИ)
Леонид Иванович, не могли-бы вы ткнуть меня носом в хороший мануал по работе с такими конструкциями , а еще лучше в учебник в котором все изложено доступным языком
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
а можно я ткну?
вообще-то, книг по языку Си - воз и маленькая тележка, если в гугле не забанили, то найти проще, чем нос утереть...
однако, если книжки искать и читать лень, могу предложить небольшие краткие советы лично от себя: http://arv.radioliga.com/content/category/6/33/49/
вообще-то, книг по языку Си - воз и маленькая тележка, если в гугле не забанили, то найти проще, чем нос утереть...
однако, если книжки искать и читать лень, могу предложить небольшие краткие советы лично от себя: http://arv.radioliga.com/content/category/6/33/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Добрый день подскажите пожалуйста, что означает данные предупреждения
Warning pointer targets in passing argument 1 of 'strlen_P' differ in signedness [-Wpointer-sign]
Warning passing argument 6 of 'show_string' from incompatible pointer type [enabled by default]
Warning pointer targets in passing argument 1 of 'strlen_P' differ in signedness [-Wpointer-sign]
Warning passing argument 6 of 'show_string' from incompatible pointer type [enabled by default]
Re: Вопросы по С/С++ (СИ)
char может быть знаковым и беззнаковым - смотрите что от вас ожидают, и что вы на самом деле передаёте в strlen. И какой тип char у используемого компилятора задан по умолчанию.baghear писал(а):Warning pointer targets in passing argument 1 of 'strlen_P' differ in signedness [-Wpointer-sign]
Опять-же ожидаемый тип указателя в шестом параметре функции show_string не соответствует тому, что в него передаёте. Код покажете - можно будет сказать точнее.baghear писал(а):Warning passing argument 6 of 'show_string' from incompatible pointer type [enabled by default]
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Есть такая функция
void show_string (unsigned char size,unsigned int start_x,unsigned int start_y,unsigned int color,unsigned int phone,const unsigned char *string)
последним параметром надо передать указатель
const unsigned char string_1 [] PROGMEM = "hello";
передаю вот так
show_string(3,4,2,0XAAAA,0XEEEE, &string_1);
а ошибки не выдает когда передаю так
show_string(3,4,2,0XAAAA,0XEEEE, string_1);
Прочитал что при передаче массива по сути передаю указатель на первый элемент.
Спасибо.
void show_string (unsigned char size,unsigned int start_x,unsigned int start_y,unsigned int color,unsigned int phone,const unsigned char *string)
последним параметром надо передать указатель
const unsigned char string_1 [] PROGMEM = "hello";
передаю вот так
show_string(3,4,2,0XAAAA,0XEEEE, &string_1);
а ошибки не выдает когда передаю так
show_string(3,4,2,0XAAAA,0XEEEE, string_1);
Прочитал что при передаче массива по сути передаю указатель на первый элемент.
Спасибо.
Re: Вопросы по С/С++ (СИ)
Такой подход с легкой правкой имеет право на жизнь, можно использовать если требуется передавать строке начиная не с первого символа:baghear писал(а):Есть такая функция
void show_string (unsigned char size,unsigned int start_x,unsigned int start_y,unsigned int color,unsigned int phone,const unsigned char *string)
последним параметром надо передать указатель
const unsigned char string_1 [] PROGMEM = "hello";
передаю вот так
show_string(3,4,2,0XAAAA,0XEEEE, &string_1);
Код: Выделить всё
show_string(3,4,2,0XAAAA,0XEEEE, &string_1[3]);Код: Выделить всё
show_string(3,4,2,0XAAAA,0XEEEE, string_1 + 3);да,а прибавление к указателю целого числа N - суть смещение в массиве на N-ое количество элементов.baghear писал(а): а ошибки не выдает когда передаю так
show_string(3,4,2,0XAAAA,0XEEEE, string_1);
Прочитал что при передаче массива по сути передаю указатель на первый элемент.
А если написать для эксперимента так:
Код: Выделить всё
show_string(3,4,2,0XAAAA,0XEEEE, "hello");Удачи!
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Спасибо большое, стало понятнее!!!!
Почему строковый литерал по дефолту signed char?
разве есть смысл учитывать знак при кодировке?
Еще возник вопрос, есть хэдер, который содержит один массив
static unsigned char const Font8x16[95][16] = {.....}
для чего он объявлен как static?
Почему строковый литерал по дефолту signed char?
разве есть смысл учитывать знак при кодировке?
Еще возник вопрос, есть хэдер, который содержит один массив
static unsigned char const Font8x16[95][16] = {.....}
для чего он объявлен как static?
Re: Вопросы по С/С++ (СИ)
Точно не скажу, но навскидку это настройка компилятора - будет дефолтный char со знаком или без. А вот зачем - этим я как-то не задумывался. Что-то в памяти рядом с триграфами и прочей жуткой легаси болтается - но утверждать не возьмусь.baghear писал(а):Спасибо большое, стало понятнее!!!!
Почему строковый литерал по дефолту signed char?
разве есть смысл учитывать знак при кодировке?
При включении хидеров в сишник - препроцессор формирует один большой файл который и скармливается компилятору. Т.е. выделив массив прямо в хидере - автор выделил его во всех сишниках в которые он будет включен. Компилятор эти массивы так и вставит в результирующие объектные файлы - ведь он работает с одним сишником за проход. После компилятора, как д'Артаньян на белом коне подъезжает линкер и начинает вязать объектники в единое целое. И тут он находит в различных файлах объекты с одинаковыми именами Font8x16 - и резонно начинает нудить про дубликаты символов и отказываться от своей миссии - ему и на самом деле непонятно какие ссылки идут к "тому" экземпляру, а какие к "этому". Но автор, умная голова, объявляет массив в хидере как static и теперь линкер вяжет ссылки из "этого" файла к его собственной копии массива, а из "того" файла - к "той" копии. Вуаля! Автор удовлетворён, счастливы все кроме процессора, ресурсы которого потрачены на несколько копий одних и тех-же данных. Вот где-то так, по моим ощущениям всё и происходило.baghear писал(а):Еще возник вопрос, есть хэдер, который содержит один массив
static unsigned char const Font8x16[95][16] = {.....}
для чего он объявлен как static?
Чтобы избежать дубликации - нужно либо не включать хидер в несколько c-файлов, а если нужны ссылки между модулями - в хидере объявить его как extern вместо static, а тельце с инициализацией поместить в одном из c-шников.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Спасибо, большое!!!!
- acckyiboxxx
- Нашел транзистор. Понюхал.
- Сообщения: 182
- Зарегистрирован: Ср янв 25, 2012 07:26:40
Re: Вопросы по С/С++ (СИ)
непонятно почему единоразово самопроизвольно срабатывает прерывание int7 (судя по симуляции в протеусе)
так вот PE7 подтянут резюком к земле а энкодер может подавать на него лог единицу , после чего прерывания должны отключиться и PORTB должен выдать лог единицу на все свои 8 лап , только вот при симуляции в протеусе прерывание уже прилетает еще до того как я начинаю "крутить энкодер"
энкодер запилен по этой статье http://diymicro.ru/sozdanie-ierarxiches ... odera.html вирт. осциллографом проверял от него самопроизвольно лог единица прилетать не может
да и настройки тоже вроде как правильно сделал http://www.gaw.ru/html.cgi/txt/doc/micr ... h128/8.htm
вопрос в том почему прерывание все-же срабатывает первый раз ?
ps: если убираю вызов disable_int7(); из обработчика прерываний то при запуске оно срабатывает 1 раз а затем когда я "работаю энкодером" PORTB переключает состояние своих выводов что говорит о том что прерывание отрабатывает
Код: Выделить всё
ISR(INT7_vect){
disable_int7();
PORTB = ~PORTB; // для того что-бы глянуть что прерывание отработало
}
void init_encoders(void){
//disable_int7(); // РУБИМ ПРЕРЫВАНИЕ ПО INT7
cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
DDRE &= (1<<DDE7);
PORTE &= (1<<PE7);
EICRB |= (1<<ISC71) | (1<<ISC70) | (1<<ISC61) | (1<<ISC60); // INT6 И INT7 СРАБОТАЮТ ПО 2-М ВЫБОРКАМ ВЫСОКОГО УРОВНЯ
sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
}
void enable_int7(void){
cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
EIMSK = (1<<INT7); // РАЗРЕШАЕМ ПРЕРЫВАНИЕ НА INT7
sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
}
void disable_int7(void){
cli(); // ВЫРУБАЕМ ПРЕРЫВАНИЯ ГЛОБАЛЬНО
EIMSK &= (1<<INT7); // ЗАПРЕЩАЕМ ПРЕРЫВАНИЕ НА INT7
sei(); // ГЛОБАЛЬНО РАЗРЕШАЕМ ПРЕРЫВАНИЯ
PORTB = 0x00;
}
int main(){
init_encoders(); // НАСТРАИВАЕМ РАБОТУ ЭНКОДЕРОВ
disable_int7();
enable_int7();
while (1)
{
};
return 0;
}
энкодер запилен по этой статье http://diymicro.ru/sozdanie-ierarxiches ... odera.html вирт. осциллографом проверял от него самопроизвольно лог единица прилетать не может
да и настройки тоже вроде как правильно сделал http://www.gaw.ru/html.cgi/txt/doc/micr ... h128/8.htm
вопрос в том почему прерывание все-же срабатывает первый раз ?
ps: если убираю вызов disable_int7(); из обработчика прерываний то при запуске оно срабатывает 1 раз а затем когда я "работаю энкодером" PORTB переключает состояние своих выводов что говорит о том что прерывание отрабатывает
Re: Вопросы по С/С++ (СИ)
acckyiboxxx, вы уверены что правильно биты в регистрах сбрасываете?
Обычно нужно инвертирование
Обычно нужно инвертирование
Код: Выделить всё
EIMSK &= ~(1<<INT7);
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Разъясните пожалуйста про перечислители.
Допустим, перечислитель _flags:
Какой смысл в названии перечислителя _flags, если оно напрямую не используется?
Обращение в коде происходит к самим константам(_READ,_WRITE и т.д.).
Допустим, перечислитель _flags:
Код: Выделить всё
enum _flags {
_READ =01, /* файл открыт на чтение */
_WRITE = 02, /* файл открыт на запись */
_UNBUF = 04, /* файл не буферизуется */
_EOF = 010, /* в данном файле встретился EOF */
_ERR = 020 /* в данном файле встретилась ошибка */
};Обращение в коде происходит к самим константам(_READ,_WRITE и т.д.).
Re: Вопросы по С/С++ (СИ)
enum _flags это определение типа и если нужно определить функцию принимающую, к примеру, параметр этого типа - вот тут имя и пригодится. Но по характерным признакам данного конкретного случая мы имеем дело с битами в маске - и попытка передать комбинацию битов выдаст предупреждение компиляции. Впрочем использование безымянных перечислений также не возбраняется современными стандартами и было-бы тут уместно.uk8amk писал(а):Какой смысл в названии перечислителя _flags, если оно напрямую не используется?Код: Выделить всё
enum _flags { _READ =01, /* файл открыт на чтение */ [...] };
Обращение в коде происходит к самим константам(_READ,_WRITE и т.д.).
Программы имеют свой жизненный цикл развития и за время разработки этот еnum _flag мог быть изначально запланирован к использованию в качестве типа, а затем по мере развития выродился в набор битов в маске. Ну а имя или забыто, либо, скорее всего, вставлено изначально, чтобы избежать проблем с портированием этого кода на компиляторы не понимающие безымянный enum.
PS: Кстати, использование подчёркивания в начале имён - прерогатива стандартной библиотеки и в своих программах такой нотации рекомендуется избегать.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Пытался ранее докопаться до истины, но везде в интернетах и учебниках только общие слова.
Например объявление типа, относящегося к контроллеру прерываний:
И далее функция, употребляющая этот параметр:
При создании объекта и передачи параметра этого типа в функцию по идее должно резервироваться какое-то кол-во памяти для хранения в ОЗУ или стеке.
Но что выделяется под enum IRQn_Type IRQn ? Ведь это всего лишь набор возможных числовых констант, которые можно было тупо заменить #define-ами. Вот это не понятно.
Например объявление типа, относящегося к контроллеру прерываний:
Код: Выделить всё
typedef enum IRQn
{
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
бла-бла-бла
} IRQn_Type;Код: Выделить всё
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}Но что выделяется под enum IRQn_Type IRQn ? Ведь это всего лишь набор возможных числовых констант, которые можно было тупо заменить #define-ами. Вот это не понятно.


