|
ATtiny 2313 |
|
|
|
May 6 2010, 13:10
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Добрый день, возникли трудности с работой с МК. Это мой первый практический опыт в паянии и работе с МК. Есть схема ультразвукового дальномера, пока собрал кусок: питание, кнопки управление, МК и 7сегм индикатор. Столкнулся с проблемой, когда начал писать простенькую прошивку. Цель прошивки: просто отображать какие-то крякозяблы поочереди на 3х знакоместах (использую динамику). Пишу и шьюсь через винавр: Код #include <avr/io.h> void delay_7s() { unsigned int k, l; for(l=0; l<1; l++) { for(k=0;k<65000;k++){} } } void main() { DDRB = 0xFF; DDRD = 0xFF; for(;;) { PORTB = 0b00110011; PORTD = 0x40; delay_7s(); PORTD = 0x0; // PORTB = 0b01010101; PORTD = 0x20; delay_7s(); PORTD = 0x0; // PORTB = 0b11001100; PORTD = 0x10; delay_7s(); PORTD = 0x0; } } Не могу понять почему, но информация отображается сразу на всех знакоместах. Проверял прошивку в Протеусе, там все работает. Следовательно, проблема со спаянной схемой. Меня настараживает что моя тинька, когда на выводах лог 0, выдает 1,2-1,3 В !!!. Следовательно, напряжение после ограничивающих резюков перед транзисторами, колеблется от 0,74 В (когда на выводе PD6 (PD5 или PD4) лог 0) и до 0,82 В (когда лог 1). Думаю, что проблема в этом. То есть напряжения 0,74 и 0,82 способствуют постоянному открытию транзисторов. Опыта мало, так что надеюсь на ваше помощь!
Сообщение отредактировал rezident - May 8 2010, 23:57
Причина редактирования: Оформление цитаты исходника.
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 26)
|
May 6 2010, 13:30
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Исправил ситуацию с принтскрином.
Проблем с землей/питанием вроде нет. Прозванивал, все баги давно уже исправил
|
|
|
|
|
May 6 2010, 13:45
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(indi_88 @ May 6 2010, 19:10)  информация отображается сразу на всех знакоместах. Надо сначала отключать знакоместо, а потом уже выводить цифру для следующего знакоместа. То есть, добавить Код PORTD = 0x0; перед каждым Код PORTB = ....; Ну и - volatile unsigned int k, l;  Пардон, первое замечание снимается - проглядел
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 6 2010, 14:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Используйте кнопку  для оформления исходников. Иначе их очень трудно читать и, соответственно, уменьшается желание в них вникать. Цитата(indi_88 @ May 6 2010, 16:10)  Код void delay_7s() { unsigned int k, l; for(l=0; l<1; l++) { for(k=0;k<65000;k++){} } } Этот код работать не будет. Точнее, он будет выкинут компилятором как бесполезный при включенной оптимизации (а без оптимизации компилировать не имеет смысла). Используйте встроенную функцию _delay_ms() из <util/delay.h> или хотя бы объявите переменные цикла как volatile. А когда компилятор выкинул задержку - вваша программа исполняется быстро-быстро  Цитата(AHTOXA @ May 6 2010, 16:45)  То есть, добавить Код PORTD = 0x0; перед каждым Код PORTB = ....; Ой. Оно же и так отключит при записи PORTB =
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 6 2010, 14:46
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Я б изменил код в теме, но пропала кнопочка едит( Поменя код на Код #include <avr/io.h> #include <util/delay.h> int main() { DDRB = 0xFF; DDRD = 0xFF; for(;;) { PORTB = 0b00110011; PORTD = 0x40; _delay_ms(1000); PORTD = 0x0; // PORTB = 0b01010101; PORTD = 0x20; _delay_ms(1000); PORTD = 0x0; // PORTB = 0b11001100; PORTD = 0x10; _delay_ms(1000); PORTD = 0x0; } return(0); } Все равно выводит на 3 знакоместа. Странно, но задержка между изменением кракозяблов на 7сегм равна дето 4 сек а не 1 сек. Что вы можете сказать про напряжение на ноге мк при лог 0 ? Хм, почему 4 сек а не 1 сек я разобрался. Тк в мейкфайле стояла частота 4Мгц, то чего-то функция задержки работала в 4 раза дольше. Поставил 1Мгц и задержка стала 1 сек
Сообщение отредактировал indi_88 - May 6 2010, 14:29
|
|
|
|
|
May 6 2010, 15:00
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Сергей Борщ @ May 6 2010, 20:06)  Ой. Оно же и так отключит при записи PORTB = Нет, там же катоды (знакоместа) на PORTD. Цитата(indi_88 @ May 6 2010, 20:46)  Поменя код на Код ... _delay_ms(1000); Вы очень своеобразно трактуете понятие "динамическая индикация"  Вообще-то обычно для этого переключают разряды гораздо чаще, чем раз в секунду. Раз в сто чаще. Уменьшите задержку примерно раз в сто, и всё станет нормально. (В том числе и напряжения.)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 6 2010, 15:08
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Цитата Вы очень своеобразно трактуете понятие "динамическая индикация" smile.gif Вообще-то обычно для этого переключают разряды гораздо чаще, чем раз в секунду. Раз в сто чаще. Я правильно понимаю динамическую индикацию. Просто Вы, наверное, не правильно поняли, что я хочу. Мне надо по очереди выводить разыне крякозяблы на индикаторе. То есть, сначало что-то показывается в течении 1 сек на первом знакоместе, остальные погашены. Потом что-то показывается на второй знакоместе и т.д.
|
|
|
|
|
May 6 2010, 16:24
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(indi_88 @ May 6 2010, 17:46)  Что вы можете сказать про напряжение на ноге мк при лог 0 ? Ненормально. А что на базах транзисторов? Если еще больше - то у вас транзистор не той полярности (pnp) или попутаны выводы базы и коллектра. В результате в вывод стекает ток из индикатора. Других разумных объяснений нет - направление портов вы задали. Цитата(indi_88 @ May 6 2010, 17:46)  Хм, почему 4 сек а не 1 сек я разобрался. Тк в мейкфайле стояла частота 4Мгц, то чего-то функция задержки работала в 4 раза дольше. Поставил 1Мгц и задержка стала 1 сек У вас тактирование от внутреннего RC 8МГц и запрограммирован фуз CKDIV. Поэтому тактирование получается 1 МГц. А компилятор высчтитывает количество циклов задержки исходя из значения F_CPU. Так что все правильно. Цитата(AHTOXA @ May 6 2010, 18:00)  Нет, там же катоды (знакоместа) на PORTD. Да. Стормозил.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 6 2010, 17:58
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Цитата Значит вы неясно выражаете свои мысли Прошу прощение) Цитата Что касается вопроса "почему выводятся сразу на все места" - осталось лишь одно разумное объяснение - вы перепутали цоколёвку индикатора. Вряд ли, я меняя значение порта Б могу зажигать/тушить все сегменты знакоместа индикатора (то есть вывести все, что я захочу). Цитата Ненормально. А что на базах транзисторов? Если еще больше - то у вас транзистор не той полярности (pnp) или попутаны выводы базы и коллектра. В результате в вывод стекает ток из индикатора. Других разумных объяснений нет - направление портов вы задали. Маркировка на транзисторе: BC547B Выводы транзисторов выбирал так: если смотреть срез корпуса, то слева направо: к б э На базах напряжения 0,74 (лог 0) или 0,82 (лог 1) вольт. Меня очень смущают эти напряжения. Если они не падают ниже 0,74 В, то возможно что транзисторы постоянно открыты? Следовательно, тогда будут гореть все знакоместа
|
|
|
|
|
May 6 2010, 21:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цоколевка похожа на правду, транзистор npn. Цитата(indi_88 @ May 6 2010, 20:58)  На базах напряжения 0,74 (лог 0) или 0,82 (лог 1) вольт. А что на ногах если отключить от них транзисторы?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 7 2010, 14:50
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Купил новый мк и транзисторы, попытаюсь сделать новую разводку и заново все собрать
|
|
|
|
|
May 12 2010, 12:42
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Собрал кусок схемы на новом мк и транзисторах, с новой разводкой. проблема ушла сама собой, так что уже и нипонятно, где она была))) Возник другой вопрос: Как мне сделать генерацию пачки импульсов (например, штук 25), изменяя состояние ноги мк PD0. Мне надо добиться частоты 40 кГц, мой внутренний тактовый генератор настроен ан 4 Мгц. Код должен выглядеть следующим образом: Код PORTD |= 0b00000001; // какая-то задержка PORTD &= 0b11111110; // задержка, которая дает частоту 40 кГц Загвоздка в том, что я не очень понимаю одну вещь: Если частота тактового 4 Мгц, то выполнение одной итерации мцу занимает 0,25*10^-6 c. 40 кГц дает период длительностью 25*10^-6 c. Тогда импульсы должны появляться каждую 100ую итерацию мцу. Если делать это с помощью цикла, то непонятно, сколько времени идет на проверку условий и т.д. Вообщем как-то так))
|
|
|
|
|
May 12 2010, 21:29
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
А если использовать такой код: Код for(unsigned char i = 25; i > 0; i--) { PORTD |= 0b00000001; //WAITING(); _delay_us(12.5); PORTD &= 0b11111110; _delay_us(12.5); //WAITING(); } читаю док на функцию: Код void _delay_ms (double __ms) В симмуляторе аврстудио не хочет делать паузу в 12,5 мкс, вместо этого получаю 12 мкс. ЗЫ Еще возник вопрос по функции дилей: Пытался по очереди выводить что-то на знакоместа, код: Код PORTB = 0x01; PORTD = 0x10; _delay_ms(1000); PORTD = 0x00; PORTB = 0x02; PORTD = 0x20; _delay_ms(1000); PORTD = 0x00; PORTB = 0x03; PORTD = 0x40; _delay_ms(1000); PORTD = 0x00; Смотрю док: Код The maximal possible delay is 262.14 ms / F_CPU in MHz.
When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution. Я так понял, 1 секунду оно мне все-таки выдаст... Идем дальше... В мейкфайле ставлю частоту 4000000, задержка составляет 4 сек, а не 1 сек. Ставлю 1000000 и, о чудо, задержка равна 1 сек. Кто может объяснить почему? Да-да, я думал, что понял в чем суть, но ошибался. ЗЫ Забыл добавить, оптимизация -Os
Сообщение отредактировал indi_88 - May 12 2010, 21:51
|
|
|
|
|
May 13 2010, 06:50
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(indi_88 @ May 13 2010, 00:29)  А если использовать такой код: То вы не сможете в это время выводить что-то на индикатор. А если выводить на индикатор в прерываниях (что, в общем-то, грамотоно), то прерывания будут вносить искажения в ваши задержки. Изучите таймер - он может формировать такие импульсы железно на выводах OCx Цитата(indi_88 @ May 13 2010, 00:29)  Идем дальше... В мейкфайле ставлю частоту 4000000, задержка составляет 4 сек, а не 1 сек. Ставлю 1000000 и, о чудо, задержка равна 1 сек. Кто может объяснить почему? Потому что процессор с завода поставляется с фузами, прошитыми на тактирование от внутреннего RC генератора 8МГц и включенным делителем (CVDIV) на 8. Отсюда получается 1 МГц тактовой частоты.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 13 2010, 07:58
|
Местный
  
Группа: Свой
Сообщений: 289
Регистрация: 6-12-05
Пользователь №: 11 864

|
Цитата В симмуляторе аврстудио не хочет делать паузу в 12,5 мкс, вместо этого получаю 12 мкс. У Вас тактовая процессора 1МГц вот и получается ровно 12мкс
Сообщение отредактировал rezident - May 14 2010, 17:43
Причина редактирования: Излишнее цитирование.
|
|
|
|
|
May 13 2010, 09:23
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Цитата Потому что процессор с завода поставляется с фузами, прошитыми на тактирование от внутреннего RC генератора 8МГц и включенным делителем (CVDIV) на 8. Отсюда получается 1 МГц тактовой частоты. Ну я понимаю, что включен пределитель, но я думал, что если я в мейкфайле для винавр пишу, что я хочу частоту 4000000, то компилятор при прошивке изменит нужные фбюзы, чтобы получить именно 4000000. Строго не судите, тк я вот только начал этим всем заниматься.
|
|
|
|
|
May 13 2010, 09:44
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(indi_88 @ May 13 2010, 12:23)  но я думал, что если я в мейкфайле для винавр пишу, что я хочу частоту 4000000, то компилятор при прошивке изменит нужные фбюзы, чтобы получить именно 4000000. Вы хотите от него слишком многого. А если вы напишете 1234567, у процессора ведь нет компбинации фузов для такой частоты  . Опять же, вы можете затактировать процессор от кварца или внешнего генератора на 4МГц, а как компилятор отличит такую ситуацию от внутреннего RC?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 13 2010, 09:57
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Хм, я начинаю понимать, то есть если я в мейкфайле пишу частоты, то они автоматически делятся на 8? Но возникает другой вопрос: пишу: 1) 1000000 - задержка 1сек 2) 2000000 - задержка 2сек 3) 4000000 - задержка 4сек 4) 8000000 - задержка 8сек
Если я частоту увеличиваю, то период уменьшается, и, следовательно, задержка должна наоборот уменьшаться, а она увеличивается. Вообщем, я запутался. Мне необходимо настроит ьвнутренний тактовый на 4МГц или 10МГц, и чтобы когда я пишу _delay_ms(1000), оно ждало именно 1сек.
|
|
|
|
|
May 13 2010, 10:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(indi_88 @ May 13 2010, 12:57)  Хм, я начинаю понимать, то есть если я в мейкфайле пишу частоты, то они автоматически делятся на 8? Нет. Вы указываете компилятору частоту, а он рассчитывает - сколько циклов надо сделать задержку для этой частоты. Допустим, вы указали частоту 1000000 и компилятор посчитал, что надо сделать (допустим) 100 циклов для указанного вами времени задержки 7 мкс. Теперь вы указываете ему вдвое бОльшую частоту - 2000000. Естественно, чтобы получить то же время задержки 7 мкс при удвоенной скорости процессора, процессору надо сделать вдвое больше пустых циклов. А если вы реальную частоту в железе оставили ту же, то вдвое больше пустых циклов будут исполняться в 2 раза дольше, что вы и наблюдаете. Цитата(indi_88 @ May 13 2010, 12:57)  Мне необходимо настроит ьвнутренний тактовый на 4МГц или 10МГц, и чтобы когда я пишу _delay_ms(1000), оно ждало именно 1сек. Отключите CKDIV. Внимательно прочитайте, какое состояние фузов CKSEL включает внутренний RC-генератор на 4 МГц и есть ли вообще возможность включить его на 4 МГц. Если нету - включайте его на 8 МГц. Главное - в makefile надо указать именно ту частоту, которой тактируется ядро. Тогда и только тогда _delay_ms(1000) даст вам задержку ровно 1 сек (при отсутствии прерываний).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 13 2010, 10:28
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Через понипрог убрал галочку с CKDIV и все заработало как надо! СПАСИБО БОЛЬШОЕ!
|
|
|
|
|
May 13 2010, 10:53
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(indi_88 @ May 13 2010, 13:28)  Через понипрог Раз уж вы начинающий - позвольте дать еще один совет. Если вы пользуетесь программатором на LPT - используйте в качестве софта для программирования AVReal. Один раз напишете .bat - файл для запуска и будете избавлены от возможности случайно зашить не ту компинацию фузов. Да и прошивка будет заключаться в одно двойном щелчке по иконке этого .bat вместо лазания по менюшкам лошади. вот пример .bat для прошивки через STK200/STK500 или "5 проводов": Код @echo off SET FIRMWARE=release\FS-led-display
SET AVREAL=avreal32 +MEGA8 -as -p1 -o0.5MHz SET FUSES=BODEN=0,BLEV=1,BLB0=3,BLB1=0,RSTDSBL=1,WDTON=1,BSIZ=0,BRST=1,CKSEL=F,CKOPT =0 %AVREAL% -e -w -v -f%FUSES% -c %FIRMWARE%.hex -d %FIRMWARE%.eep
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 13 2010, 11:02
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 6-05-10
Пользователь №: 57 112

|
Спасибо, но я шью через винавр и использую com-программатор
Сообщение отредактировал indi_88 - May 13 2010, 11:17
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|