CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Извините, мне сегодня ещё есть что делать.
Интересующиеся могут посмотреть немного о массивах да указателях на электрониксе. Я там достаточно и примеров, и цитат из стандартов привёл.
Может, на днях ещё что-то напишу тут.

p.s[0] Да, [3] для одномерного массива там вообще ничего не означает. Аргумент имеет тип указателя на int. Скобки так, для приятствия чтения, чтобы читающий знал, чего функция ждёт. Всё же int arr[3] информативнее, чем int *arr (кстати, main(int argc, char *argv[]) и main(int argc, char **argv) тоже эквивалентны).
Для многомерных индексаций foo(int arr[3][7][TUZ]) все размеры, кроме первого, важны -- для вычисления правильных смещений.

p.s[1] Мне бы терпение и талант писательства Леонида Ивановича, у меня уже сайт забит был бы красиво оформленными толкованиями стандарта для тех, кто морально не готов сам продираться сквозь это :-) А так для ответов на форумах терпения иногда хватает, а оформить это...
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

отлично! сразу все стало на свои места!

int arg[3], указанный в параметре функции абсолютно соответствует int *arg, указанному там же.
далее: в описании переменных int *ptr совсем не то же самое, что int ptr[3]. гм...

рискну задать еще вопрос: ну а в случае с foo(int arg[3][2][5]); каков смысл [2][5]? как по-русски описать их назначение? что же такое передается в функцию - указатель на....????
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Эти [2][5] указывают соответствующие размерности для вычисления смещения.
Точнее, задают тип указателя arg -- он указывает на массивы int [2][5]

int arg[3] был эквивалентен int *arg (и его можно было записать как int arg[])

int arg[3][2][5] эквивалентен int (*arg)[2][5] (и его можно записать как int arg[][2][5])

Теперь при работе с arg известно какой тип имеют выражения *arg либо arg, на сколько инкрементировать по ++arg (на 2*5 int-ов, перейти к следующему массиву int [2][5]).
Соответственно, известен тип выражения **arg (либо, что эквивалентно, arg[0][0]) -- это тип "массив int [5]".
И этот тип под sizeof даёт соответствующий размер, а в выражениях автоматически приводится к указателю на int.

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

void foo(int arg[3][2][5])
{
    // sizeof(arg) == sizeof(void*)
    // а вот следующие два sizeof дают результаты для массивов,
    // так как разименования arg дают типы int [2][5] и int[5] соответственно
    // sizeof(*arg) == 2*5*sizeof(int)
    // sizefo(**arg) == 5*sizeof(int)
}
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

avreal писал(а):Эти [2][5] указывают соответствующие размерности для вычисления смещения.
Точнее, задают тип указателя arg -- он указывает на массивы int [2][5]

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

void foo(int arg[][2][5]);
int array3[3][2][5];
int array2[2][5];
...
    foo( array3 );  // корректно, передали указатель на три подряд массива int [2][5]
    foo( & array2 ); // корректно, передали указатель на один массив int [2][5]
    foo( array2 ); // НЕкорректно, передали указатель на первый элемент array2 -- на массив int [5]
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

Сообщение Valek87 »

Реклама
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

Valek87 писал(а):http://radiokot.ru/forum/viewtopic.php?p=958365#p958365 Помогите
Сгенерте настройки таймера визардом.
Может кварц не тот поставили...
Реклама
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Valek87 писал(а):Помогите пожалуйста. Вот написал программу - мигание светодиода с периодом 1с. Только почему-то у меня идет период не 1с, а 1,675с.

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

// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0b00000100;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x98;
OCR1AL=0x96;
Нет ни малейшего желания лезть в документацию и смотреть, какой бит какого регистра что означает, какой прескалер при таких битах.
А наизусть помнить тоже желания нет -- это пусть гении делают (но они такие вопросы не задают :-)
Есть же имена у битов, есть комментарии, можно и для OCR константу в виде
F_CPU / JA_POSTAVIL_TAKOJ_PRESCALER / JA_HOCHU_TAKUJU_CHASTOTU
написать.
Может, потому никто и не спешит отвечать -- хотите получить ответ, так потрудитесь облегчить работу отвечающему.

Но включив режим «телепатия» могу предположить, что не включен бит CTC (режим CTC в битах WGM). Итого период-то занесён, но деление идёт на 65536 (больно похоже соотношение чисел 1 : 1.675 и вон-та-HEX-фигня-0x9896 : 65536)
Вот надо было мне глянуть в документацию и написать в духе «что не добавлена маска 0x04» вместо имён битов. Было бы «какой вопрос, такой ответ».
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

Сообщение Valek87 »

Clock от внешнего генератора. Всё, что сгенерил визардом, было указано в программе.

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

TCCR1B=0b00000100;
Прескаллер на СК/256.

Вообще я весь расчет выполнял в соответствии с инструкцией http://radiokot.ru/start/mcu_fpga/avr/11/. Какие значения получил, те и вписал.
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 78,125 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

Вот так генерит визард.

Как вы собираетесь набрать 1с? Если за 65536 тиков( по 256/20000000 c) вы наберете только 0,83 с ...
Увеличивайте деление например на частоту 19531, тогда в регистр OCR1A вводите число 4С4B(19531) и не забывайте обнулять счётный регистр в прерывании.
Встал на лапы
Сообщения: 136
Зарегистрирован: Пн июл 12, 2010 16:03:11

Сообщение Valek87 »

demiurg301 писал(а):не забывайте обнулять счётный регистр в прерывании.
как его обнулять?
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

TCNT1H=0x00;
TCNT1L=0x00;

ВОт тАК :)))
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

А зачем его обнулять вручную, если при включении режима CTC он по сравнению с OCR1A обнулитcя аппаратно ??? (для базового CTC, в расширенных -- по сравнению с ICR и тогда OCR1A для еще чего-то аппаратного можно использовать).
Ну только в режиме CTC надо прерывание не по OVF делать, а по COMPA (тоже для базового, который с нулевым старшим битом WGM).
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

Для таймера проще вручную без всяких режимов. Чтобы менять отмеряемое время на лету... Хотя я привык просто наверно "обнулять" всегда таймеры - ещё с mcs51 повелось...
Опытный кот
Аватара пользователя
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна

Сообщение avreal »

Менять время можно, перезаписывая OCR. Всякие там плавные старты и корректные остановки шаговых движков на ура получаются.

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

Вручную тоже можно аккуратнее (не обнулять, а вычитать желаемый период из того, что накопилось на момент обработки), но зачем?
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Контактная информация:
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

Да, вы правы. С OCR красивее... и ножкой дёргать аппаратно можно... :beer:
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1451
Зарегистрирован: Пт фев 19, 2010 19:39:28
Откуда: Москва

Сообщение Сериг »

Кто может подсказать два индикатора сдвоенных,7-ми сегментника общие аноды,кто может подсказать как таким управлять?
Держит паяльник хвостом
Аватара пользователя
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

Сообщение Apparatchik »

Сериг писал(а):Кто может подсказать два индикатора сдвоенных,7-ми сегментника общие аноды,кто может подсказать как таким управлять?
Обычная динамическая индикация
«И всё-таки она вертится!»
Опытный кот
Сообщения: 812
Зарегистрирован: Ср мар 18, 2009 21:14:33

Сообщение demiurg301 »

Подскажите где можно почитать про исользование Boot Loader Lock Bits в CVAVR. Никак не разберусь с BLB битами...
Родился
Сообщения: 8
Зарегистрирован: Пн июл 26, 2010 20:28:36
Откуда: из озера глубокого

Сообщение Рыбеха »

Здравствуйте! Всю ночь бьюсь в поисках ответа на вопрос.
В программировании новичок, не получается выделить 32 бита под переменную( Может меня клинит уже, конечно..
Кусок кода:

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

//Глобальные переменные
char mmc_data[512];//512 байт, считанных с карты памяти помещаются в этот буфер
...
//Локальные переменные
long int fat_adr;//адрес таблицы fat
...
fat_adr=(mmc_data[0xF]*0x100+mmc_data[0xE])*0x200;//получаем 4-хбайтный адрес.

выдает на последнюю строку два предупреждения:

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

Warning: C:\Documents and Settings\Ðèðàíèÿ\Ðàáî÷èé ñòîë\Íîâàÿ ïàïêà (3)\cvavr\prj\MMC-SD\MMC-SD.c(109): overflow is possible in 16 bit multiplication, casting to 'long' may be required
Warning: C:\Documents and Settings\Ðèðàíèÿ\Ðàáî÷èé ñòîë\Íîâàÿ ïàïêà (3)\cvavr\prj\MMC-SD\MMC-SD.c(109): overflow is possible in 16 bit addition, casting to 'long' may be required
В результате операции должно получиться 0x310800, но выходит просто - 0x800. Почему он для fat_adr не выделяет 32 бита? Спасибо.
[size=85]Вам не съесть меня, коты![/size]
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Честно предупреждает о разных разрядностях. Действия производятся над байтной величиной(которая у вас в установках надо полагать определена как двухбайтная), лишнее отсекается и результат пересылается в long. Определитесь с длинной переменной mmc_data.
Docendo discimus
Контактная информация:
Ответить

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