АЦП ATmega16 |
us4ilq | Дата: Понедельник, 16.11.2009, 20:47 | Сообщение # 41 |
Группа: Пользователи
Сообщений: 48
Статус: Offline
|
Здравствуйте Евгений! Изменения внес - все отлично! Я тут подумал: измерение через 0,5 секунды слишком медленно , (такой шаг оправдан при отладке) и к тому же (как я уже упоминал раньше) я хочу заменить кварц 8 мгц. на 4х мегагерцевый . В связи с этим нужно изменить параметры инициализации таймера Т1. Просто прошу Вас проверить - правильно ли я сделал это вот так: Code // Кварцевый резонатор 4 мегагерц. TCCR1B|=(1<<CS12); // Предделитель для T1 = 256. Начать счёт. TCNT1H=(0xFF-0x12); // Старший байт счётчика. Инициализация на 0,2 сек. TCNT1L=(0xFF-0x53); // Младший байт счётчика. TIMSK|=(1<<TOIE1); // Разрешить прерывание по переполнению Т1. ...
// Подпрограмма обработки прерывания по переполнению T1
interrupt [TIM1_OVF] void timer1_ovf_isr(void) { TCNT1H=0xFF-0x12; TCNT1L=0xFF-0x53; // Переинициализация счётчика на 500 мс. //PORTA^=(1<<LED); Status=1; // Начать измерение. } А также наверное придется это учесть при инициализации АЦП, но с этим позже. Спасибо Сергей.
| |
|
|
|
eugenemcu | Дата: Понедельник, 16.11.2009, 22:16 | Сообщение # 42 |
Группа: Администраторы
Сообщений: 89
Статус: Offline
|
Здравствуйте, Сергей. Нет, немного неправильно. Я так понимаю цифры 12 и 53 взяты с моей страницы расчета числа тактов... дак там они выводятся в десятичном выражении. В шестнадцатеричном виде это будет 0x0C и 0x35. Что касается увеличения частоты отображения, то слишком часто тоже не надо, а то получится неприятное глазу мельтешение цифр при изменении напряжения. Наверное, стоит попробовать разные значения и выбрать по восприятию. С инициализацией АЦП при этом делать ничего не нужно. Хочу вам подкинуть другую идею. Польза от неё скорее обучающая, чем практическая. Бытует мнение, что из-за влияния помех показания АЦП при каждом вычислении получаются разные. У нас это всё сглаживается округлением результата до сотых. Однако для тренировки можно организовать накопление скажем четырёх значений, вычисление по ним среднего арифметического и уже его родимого выводить на экран.
| |
|
|
|
us4ilq | Дата: Вторник, 17.11.2009, 21:27 | Сообщение # 43 |
Группа: Пользователи
Сообщений: 48
Статус: Offline
|
Здравствуйте Евгений! Наверное я безнадежно дремучий Но я никак немогу понять, как разложить число 49911 на два (в десятичной системе счисления) для записи в TCNT1H и TCNT1L с последующим их преобразованием в шестнадцатеричную систему? Вы писали в одной из своих статей: 2. Вычисляем начальное значение содержимого таймера, которое через N тактов приведёт к его переполнению: M= 2^16 – 15625 = 65536 – 15625 = 49911 = 0xC2F7; Но ведь C2 это 194, а F7 это 247. Я понимаю - в Ваших статьях есть калькулятор для этих целей. Но мне хотелось бы знать как это можно посчитать на бумажке? Может существует какая то формула для такого рассчета? Спасибо Сергей.
| |
|
|
|
eugenemcu | Дата: Вторник, 17.11.2009, 22:45 | Сообщение # 44 |
Группа: Администраторы
Сообщений: 89
Статус: Offline
|
Расчтывать всё это удобно в виндосовском калькуляторе в инженерном виде. В режиме Dec введите число тактов, например, 49911, выберите режим Hex и число отобразится в шестнадцатеричном виде - C2F7. Каждые два знака в такой записи - это байт, правые два - младший, левые старший, то есть 0xC2 и 0xF7. Кстати говоря, никто не мешает записывать байты в десятичном виде: TCNT1H=0xFF-61; TCNT1L=0xFF-9;
| |
|
|
|
us4ilq | Дата: Среда, 18.11.2009, 04:19 | Сообщение # 45 |
Группа: Пользователи
Сообщений: 48
Статус: Offline
|
Вы писали: Кстати говоря, никто не мешает записывать байты в десятичном виде: TCNT1H=0xFF-61; TCNT1L=0xFF-9; Вот как раз про это я и подумал , но постеснялся спросить т.к. Вы написали вот это: Нет, немного неправильно. Я так понимаю цифры 12 и 53 взяты с моей страницы расчета числа тактов... дак там они выводятся в десятичном выражении. В шестнадцатеричном виде это будет 0x0C и 0x35. Но теперь я понял что можно и в десятичном. Вообщето я так и подозревал, но наверняка незнал, ведь Си допускает десятичные записи, просто возможно не во всех случаях. А что до Виндозного калькулятора , так я об этом знаю. Просто хотелось знать как это посчитать именно на бумаге, если конечно подсчет не слишком громоздкий. Ну что ж. Очередную проблему похоже решили теперь можно двигаться дальше, к новым проблемам Спасибо за разьяснения Сергей.
| |
|
|
|
eugenemcu | Дата: Среда, 18.11.2009, 08:57 | Сообщение # 46 |
Группа: Администраторы
Сообщений: 89
Статус: Offline
|
Компилятору, глубоко безразлично в каком представлении Вы будете записывать константы, само значение числа от формы записи никак не меняется... ему гораздо важнее с каким типом эта константа войдёт в программу. Шестнадцатеричная запись позволяет легко увидеть байты числа, потому что каждый знак - это значение тетрады, а два знака - это байт, например, по записи 0xF0 в отличие от десятичного 240, сразу видно, что в старшей тетраде числа установлены все биты, а двоичной записи 0b11110000 это ещё заметнее. Там где такая наглядность не нужна, проще использовать десятичную запись. Никаких требований со стороны компилятора по этому вопросу не существует Что касается вычисления на бумажке, то тут тоже всё очень просто. Старший байт - это количество чисел 256 в исходном числе, а младший это остаток от деления числа на 256. Например: 49911=194*256 + 247, то есть старший байт - 194, младший - 247
| |
|
|
|
us4ilq | Дата: Понедельник, 30.11.2009, 15:29 | Сообщение # 47 |
Группа: Пользователи
Сообщений: 48
Статус: Offline
|
Здравствуйте Евгений и все кто сюда заглядывает! Переустановил КОДЕВИЖН на версию 2 04 4а. Захотелось мне добавить к нашему волтметру , в нижнюю строку линейную шкалу. Ну скажем на 10 знакомест , по 0,5 вольт на каждое знакоместо. Начал разыскивать примеры на эту тему, однако ничего более менее понятного (для меня) найти неудалось , то на ассемблере, то еще на каких то , неизвесных мне языках. Правда нашел вот на этом сайте : http://arv.radioliga.com/index.php (автор использует WinAvr) архивчик с библиотеками (TUI) на подобные темы, понял что библиотеки полезные, но вот использовать их что то неполучается. Может кто поможет разобраться? Я пробовал вот это: Code
/// Битовый массив символа, используемого для "нулевого" знакоместа горизонтальной шкалы PROGMEM uint8_t h_symb[] = { 0b00000000, 0b00000000, 0b00000000, 0b00011111, 0b00000000, 0b00000000, 0b00000000, 0b00000000 } ;
// вспомогательная переменная static uint8_t offset_first; .......... .......... .......... /** Инициализация пользовательского знакогенератора для отображения шкал в виде горизонтального столбика * */
void init_h_scale_sym(void){ uint8_t mask = 0b00100000; lcd_command(0x48); // команда записи в знакогенератор for(uint8_t i=0; i<6; i++){ // запишем 6 символов for(uint8_t y=0; y<8; y++){ // состоящих из 8 строк lcd_data(pgm_read_byte(&h_symb[y]) | mask); // битовые образы загружаем из массива } mask |= (mask >> 1); // и добавляем вертикальную полоску // нарастающей слева направо ширины } offset_first = 0; // задаем значение вспомогательной переменной } PROGMEM - мой компилятор непонимает , думаю надо заменить на unsigned char, а здесь // вспомогательная переменная static uint8_t offset_first; вроде как обьявлены две переменные? Так их же вроде как надо через запятую записывать (если они обьявляются в одной строке? И (если не трудно) добавьте еще более подробные коментарии :'( Спасибо сергей.
| |
|
|
|
eugenemcu | Дата: Понедельник, 30.11.2009, 18:15 | Сообщение # 48 |
Группа: Администраторы
Сообщений: 89
Статус: Offline
|
Здравствуйте, Сергей. Мне кажется для того, что Вы задумали можно придумать огромное множество способов реализации. Вот, хотя бы то, что первое в голову приходит: в нижней строке выводить от 1 одного до 10 символов тире “-”, в зависимости от того в какой из десяти диапазонов попадает измеренное напряжение. При таком варианте нет необходимости в создании собственных символов. Создание пользовательского символа для ЖКИ это отдельная процедура. Если Вас интересует именно этот момент, то возможно в CV есть для этого готовые решения. В своём драйвере я писал для этого отдельную небольшую функцию. Скрещивать библиотеку lcd.h из CVAVR с библиотекой для WinAVR я бы не стал. Слишком уж это геморройное занятие. static uint8_t offset_first; так объявлена одна беззнаковая 8-и битная переменная с именем “offset_first ”. Static – это просто идентификатор статической переменной, доступной по всей программе.
| |
|
|
|
us4ilq | Дата: Понедельник, 30.11.2009, 19:12 | Сообщение # 49 |
Группа: Пользователи
Сообщений: 48
Статус: Offline
|
Вы написали: Quote (eugenemcu) static uint8_t offset_first; так объявлена одна беззнаковая 8-и битная переменная с именем “offset_first ”. Static – это просто идентификатор статической переменной, доступной по всей программе. По поводу Static я в курсе. А вот с uint8_t вышла заминка, я по глупости подумал что это тоже имя переменной. Тогда что означает _t ? Quote (eugenemcu) Мне кажется для того, что Вы задумали можно придумать огромное множество способов реализации. Просто хотелось бы иметь некий универсальный программный модуль , чтобы можно было , при необходимости, вставлять в другие прграммы. И сам символ видоизменять по желанию. А размер кода на данном этапе обучения , я думаю, не имеет решающего значения. Спасибо Сергей.
| |
|
|
|
eugenemcu | Дата: Понедельник, 30.11.2009, 19:59 | Сообщение # 50 |
Группа: Администраторы
Сообщений: 89
Статус: Offline
|
Посмотрите здесь KAZUS В самом низу страницы без лишней головной боли показано как в CV сгенерировать и отобразить символ похожий на бокал с помощью функций lcd_write_byte и lcd_putchar P.S. _t вместе с uint8 образуют идентификатор типа. Просто такая форма записи, один из программных диалектов. PROGMEM - указание компилятору размещать объявляемую переменную в памяти программ.
| |
|
|