Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странности у Atmega88PA
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
alik_tv
Привет всем

Вот программа:

CODE
#include <ioavr.h>
#include <inavr.h>

unsigned char ucCurChanel;
unsigned char btPIN;
unsigned char ucCurChanel_lpctr;

#define BUTTON_MASK_PORTC 0x04

#define SIGNAL_LS_STATE_ON PORTB |= 0x10;
#define SIGNAL_LS_STATE_OFF PORTB &= ~0x10;


void main(void)
{
// Port B
DDRB = 0x10;
PORTB = 0x00;

// Port C
DDRC = 0x00;
PORTC = 0x00;

ucCurChanel = 2;

while(1)
{
btPIN = (PINC & BUTTON_MASK_PORTC);

if (btPIN == 0)
{
if (ucCurChanel_lpctr == 0)
{
SIGNAL_LS_STATE_ON
}
}
else
{
ucCurChanel_lpctr = ucCurChanel;
SIGNAL_LS_STATE_OFF
}
}
}


На один пин порта С навешена кнопка. Резистор на питание, конденсатор
на землю. Их общая точка через кнопку сидит на земле.
На пине порта В транзистор НПН с светодиодом в коллекторе.

Программа проверялась на эмуляторе АВР студии 4.18. Все работает как и должно быть. При запуске переменная ucCurChanel_lpctr получает значение 2 и при нажатии на кнопку светодиод НЕ включается.

Откомпилировал ее на ИАР АВР 4.3 и 5x. Загрузил в проц.
В проце при каждом нажатии кнопки включается светодиод.
При отпускании отключается.

Оптимизация отключена. Выводил значение переменной ucCurChanel_lpctr
по компорту в ПК. При нажатии кнопки значение _обнуляется_.
А значение переменной ucCurChanel не зависит от состояния кнопки.
Все переменные глобальные.

вывел листинг, ничего странного не нашел.
Вот основная часть его

CODE
RSEG CODE:CODE:NOROOT(1)
// 15 void main(void)
main:
CFI Block cfiBlock0 Using cfiCommon0
CFI Function main
// 16 {
// 17 // Port B
// 18 DDRB = 0x10;
LDI R16, 16
OUT 0x04, R16
// 19 PORTB = 0x00;
LDI R16, 0
OUT 0x05, R16
// 20
// 21 // Port C
// 22 DDRC = 0x00;
LDI R16, 0
OUT 0x07, R16
// 23 PORTC = 0x00;
LDI R16, 0
OUT 0x08, R16
// 24
// 25 ucCurChanel = 2;
LDI R16, 2
STS ucCurChanel, R16
// 26
// 27 while(1)
// 28 {
// 29 btPIN = (PINC & BUTTON_MASK_PORTC);
??main_0:
IN R16, 0x06
ANDI R16, 0x04
STS btPIN, R16
// 30
// 31 if (btPIN == 0)
LDS R16, btPIN
TST R16
BRNE ??main_1
// 32 {
// 33 if (ucCurChanel_lpctr == 0)
LDS R16, ucCurChanel_lpctr
TST R16
BRNE ??main_0
// 34 {
// 35 SIGNAL_LS_STATE_ON
SBI 0x05, 0x04
RJMP ??main_0
// 36 }
// 37 }
// 38 else
// 39 {
// 40 ucCurChanel_lpctr = ucCurChanel;
??main_1:
LDS R16, ucCurChanel
STS ucCurChanel_lpctr, R16
// 41 SIGNAL_LS_STATE_OFF
CBI 0x05, 0x04
RJMP ??main_0
CFI EndBlock cfiBlock0
REQUIRE _A_PORTC
REQUIRE _A_DDRC
REQUIRE _A_PINC
REQUIRE _A_PORTB
REQUIRE _A_DDRB
// 42 }
// 43 }// end while
// 44
// 45 }// end main


К сожалению у меня нет внутрисхемного отладчика, не могу словить где
переменная ucCurChanel_lpctr обнуляется.
Если кому не влом и все под руками, проверьте где тут грабли.

Я уже не знаю, что делать, может быть это у меня с головой ... 0)
Я перепроверил все с десяток раз, при различном коде.
Каждый раз одно и тоже, ucCurChanel_lpctr обнуляется.

Собрал еще одно устройство, с другим экземляром 88РА. Все также. Одна сплошная грабля.

Ткаченко Олег
coolbassnik
Попробуйте static и/или volatile
Палыч
Цитата(alik_tv @ Feb 7 2014, 18:36) *
При запуске переменная ucCurChanel_lpctr получает значение 2 и при нажатии на кнопку светодиод НЕ включается.

Э-э-э-э... А, что Вас удивляет? Программа работает в точности так, как она написана!
При пуске программы - кнопка не нажата и регистр PINC не равен нулю. Следовательно и btPIN не равен нулю. Условие if(btPIN == 0) не выполняется и переменная ucCurChanel_lpctr принимает не нулевое значение (ucCurChanel_lpctr = ucCurChanel). Позже, когда Вы нажмёте кнопку, зажеться светодиоду мешает невыполнение условия if (ucCurChanel_lpctr == 0). Поскольку в программе переменная ucCurChanel_lpctr принимает значение ноль только при включении питания и тут же программа изменяет его на 2 (см. выше), то светодиоду не зажечься никогда!
В симуляторе всё работало, вероятно, потому, что Вы имитировали нажатие кнопки до присвоения переменной ucCurChanel_lpctr значения 2.
alik_tv
Цитата(Палыч @ Feb 7 2014, 18:08) *
Э-э-э-э... А, что Вас удивляет? Программа работает в точности так, как она написана!
При пуске программы - кнопка не нажата и регистр PINC не равен нулю. Следовательно и btPIN не равен нулю. Условие if(btPIN == 0) не выполняется и переменная ucCurChanel_lpctr принимает не нулевое значение (ucCurChanel_lpctr = ucCurChanel). Позже, когда Вы нажмёте кнопку, зажеться светодиоду мешает невыполнение условия if (ucCurChanel_lpctr == 0). Поскольку в программе переменная ucCurChanel_lpctr принимает значение ноль только при включении питания и тут же программа изменяет его на 2 (см. выше), то светодиоду не зажечься никогда!
В симуляторе всё работало, вероятно, потому, что Вы имитировали нажатие кнопки до присвоения переменной ucCurChanel_lpctr значения 2.



Вы не поняли. Как Вы написали, так она НЕ работает в проце. В этом и грабля. Она работает при ЭМУЛЯЦИИ, как Вы написали.
А после прошивки, в реальном устройстве, светодиод включается при нажатии кнопки. ВКЛЮЧАЕТСЯ!

Олег

Цитата(coolbassnik @ Feb 7 2014, 17:53) *
Попробуйте static и/или volatile


попробовал. как и ожидалось никаких изменений в ассемблере нет. Прерываний для volatile у меня нет,
а static для одного файла кода ни на что не влияет.
Сергей Борщ
Цитата(alik_tv @ Feb 7 2014, 16:36) *
Каждый раз одно и тоже, ucCurChanel_lpctr обнуляется.
Собаку отключите sm.gif
alik_tv
Цитата(Сергей Борщ @ Feb 7 2014, 22:52) *
Собаку отключите sm.gif

не угадали, отключена. Фьюзы смотрел, стоит такая же красивая галочка как
и у CKDIV8.
San_75
volatile unsigned char ucCurChanel;
volatile unsigned char btPIN;
volatile unsigned char ucCurChanel_lpctr;
так попробуйте
ucCurChanel_lpctr нигде не инициализируется
_Артём_
Цитата(San_75 @ Feb 8 2014, 03:31) *
volatile unsigned char ucCurChanel;
volatile unsigned char btPIN;
volatile unsigned char ucCurChanel_lpctr;
так попробуйте
Нет, не надо так пробовать (а то вдруг заработает sm.gif - так и не поймёте тогда в чём дело было).

Цитата(San_75 @ Feb 8 2014, 03:31) *
ucCurChanel_lpctr нигде не инициализируется
Инициализируется - в стартапе.

Цитата(alik_tv @ Feb 7 2014, 22:11) *
не угадали, отключена. Фьюзы смотрел, стоит такая же красивая галочка как
и у CKDIV8.
Такая же - это в смысле никакой нет? В какой программе смотрите? Каждая же по-своему показывает.
alik_tv
Цитата(San_75 @ Feb 8 2014, 04:31) *
volatile unsigned char ucCurChanel;
volatile unsigned char btPIN;
volatile unsigned char ucCurChanel_lpctr;
так попробуйте
ucCurChanel_lpctr нигде не инициализируется


проверил, не помогает.

ucCurChanel_lpctr можно считать инициализируется ucCurChanel в цикле.
Речь не идет о неправильной работе сразу после перезагрузке, программа
постоянно неправильно работает. Ошибка перманентная.

Цитата(_Артём_ @ Feb 8 2014, 04:55) *
Такая же - это в смысле никакой нет? В какой программе смотрите? Каждая же по-своему показывает.


Я работаю с uniprof. Именно потому, что каждая программа показывает по разному, я сравниваю с состоянием
фьюза, состояние которого заранее мне известно и мною контролируется.
Иначе, сами понимаете, у меня все частоты "поплывут" в программе.

даю картинкуНажмите для просмотра прикрепленного файла
_Артём_
Цитата(alik_tv @ Feb 8 2014, 15:40) *
я сравниваю с состоянием
фьюза, состояние которого заранее мне известно и мною контролируется.
Вообще-то фузы - это три байта, которые могут принимать некоторые значения. Вот и вопрос - какие у фузов значения?
Цитата(alik_tv @ Feb 8 2014, 15:40) *
я сравниваю с состоянием фьюза, состояние которого заранее мне известно и мною контролируется.
Что вам известно мы же не знаем. А вот по значениям можно определить как настроен МК.

ЗЫ Watchdog-то включен похоже...sm.gif Сергей Борщ был скорей всего прав.
alik_tv
Цитата(_Артём_ @ Feb 8 2014, 17:08) *
Вообще-то фузы - это три байта, которые могут принимать некоторые значения. Вот и вопрос - какие у фузов значения?
Что вам известно мы же не знаем. А вот по значениям можно определить как настроен МК.

ЗЫ Watchdog-то включен похоже...:) Сергей Борщ был скорей всего прав.

Боюсь, что по значениям вы и ошиблись.
"Note that the fuses are read as logical zero, “0”, if they are programmed."

Но, если вам лень читать документацию, как мне, то можно посмотреть на состояние бита SPIEN
и спросить себя, а чем же обычно люди программируют? Да, именно им - Serial Program.
_Артём_
Цитата(alik_tv @ Feb 8 2014, 16:34) *
Боюсь, что по значениям вы и ошиблись.
А где значения-то? Числа в смысле? Галочки - это не числа.
Цитата(alik_tv @ Feb 8 2014, 16:34) *
Да, именно им - Serial Program.

То есть у uniprof всё через...наоборот?
Цитата(alik_tv @ Feb 8 2014, 16:34) *
Да, именно им - Serial Program.
Да откуда мы можем знать чем вы программируете? Parallel programming?
alik_tv
Цитата(_Артём_ @ Feb 8 2014, 18:22) *
А где значения-то? Числа в смысле? Галочки - это не числа.

То есть у uniprof всё через...наоборот?
Да откуда мы можем знать чем вы программируете? Parallel programming?


Вопрос хороший, но как выдрать числа я не знаю. Я достаточно давно работаю
с этой программой и, в общем, ей доверяю.

Ну, да, можно сказать наоборот.
Это, в некотором смысле, просто инверсная логика, не так уж и сложно привыкнуть.

Точно вы не знаете, но можно догадаться, я же сказал "обычно".
В общем, не собака это, что-то другое.
Сергей Борщ
Ну что, есть прорыв?

"Давайте пойдем логическим путем. Давайте пойдем вместе" (с).

Единственное место, где переменная обнуляется - это startup() при запуске программы. Мы можем предположить, что программа периодически сбрасывается. Проверить это просто при наличии осциллографа. Напишите простейшую программу - настройка портов на вывод 0, задержка несколько миллисекунд, зажигание светодиода, бесконечный цикл. Если осциллограф покажет импульсы на светодиоде - процессор сбрасывается. Или можно посылать один символ в последовательный порт. Если символ будет посылаться постоянно - ну вы поняли.

Сбрасываться процессор может либо собакой, либо уходом в прерывание для которого не прописан обработчик, либо же из-за замыкания в плате при зажигании светодиода лог. 0 поступает на вход RESET процессора. Поскольку программа проста, как трехлинейная винтовка и прерываний в ней не видно, собаку вы отмели, ищите замыкание в цепи сброса.
alik_tv
Цитата(Сергей Борщ @ Feb 10 2014, 10:10) *
Ну что, есть прорыв?


Почти есть. При замыкании кнопки разряжается емкость 0.1мкФ на землю
без ограничения тока. Срабатывает BOD и RESET.
Я это вижу по MCUSR. Не знаю почему, но BORF и PORF устанавливаются вместе.
Если я меняю уровень MCUSR с 4.3В на 2.7В ничего не сбрасывается.
Если в цепь разряда кондера поставить резюк 300 Ом, то и с включенным BOD,
на уровне 4.3В, тоже все работает.
И если отключить BOD все нормально.

Разводку проверил, мекка по питанию от эликтролита входного. Не сказал бы,
что плохо, хоть и сам разводил. :0)
Ширина дорожек не менее 0.3мм.

Поставил осцик 100Мгц Ригол на питание, включил развертку на спаду.
Нажал на кнопку - ничего. Развертки нет. Сейчас вот в голову пришло, что
уровень не проверил, не знаю, что там по умолчанию стояло.
Но с другой стороны не понятно почему там что-то должно быть.
Но я это перепроверю.

Плата пока на столе, если есть у кого мысли могу проверить сегодня после 7 вечера.
Кстати, на этой плате кроме одной кнопки, проца и светодиода ничего нет.

БП импульсный на 2А, если не ошибаюсь.
К нему кроме этой платы ничего не подключено.
Программатор я отсоединяю при тестировании.
Резистор через который заряжается кондер на кнопке 4.7кОм.
delamoure
AVcc подключен к питанию?
Да, и еще. Блокировочные конденсаторы установлены?

88PA - отличная рабочая лошадка была когда-то.
А попробуйте залить мой вариант.
alik_tv
Цитата(delamoure @ Feb 10 2014, 15:45) *
AVcc подключен к питанию?
Да, и еще. Блокировочные конденсаторы установлены?

88PA - отличная рабочая лошадка была когда-то.
А попробуйте залить мой вариант.


AVcc - подключен. Блокировочные конденсаторы с двух сторон,
На картинке обозначены синими "с".Нажмите для просмотра прикрепленного файла
В паре 1мкФ и 0.1мкФ. На основной плате пара 10мкФ и 0.1мкФ.

Залил, ничего не поменялось. Светодиод загорается при нажатии кнопки.
Если кондер разряжается через резистор, то светодиод не загорается.
delamoure
Цитата(alik_tv @ Feb 10 2014, 23:10) *
Залил, ничего не поменялось. Светодиод загорается при нажатии кнопки.
Если кондер разряжается через резистор, то светодиод не загорается.


День добрый.

Я вашу программу скомпилировал в WinAVR-20100110 без оптимизаций, ее вы и "заливали".
Еще интересно fuses посмотеть, но лень разбираться с вашим программатором. Hex значения fuses оценили бы все, кто хочет вам помочь здесь.

R16 на вашей плате подключен к reset? Полностью опишите подключение этого вывода, ну или дайте jpeg платы. Если это Orcad, можно и оригинал.
alik_tv
Цитата(delamoure @ Feb 11 2014, 13:07) *
.


через R16 reset подключен к программатору.

Hex значение fuses - есть пару мыслей может выйдет.
Но зачем фьюзы, вы про WDT? MCUSR показывает, что не собака это.

Может кто подскажет для такой версии схемы программатора есть ПО кроме uniprof?


Проверил с avrdude не нашел в ее списке такого программатора.
delamoure
То есть RESET - это длинная линия, которая подключена в итоге к разъему программатора. Я правильно понял?
Если так, то попробуйте не на m88, а сразу после R16, подтянуть эту линию к питанию через 2k и из этой же точки - конденсатор 2,2nF - на общий проводник.
Я думаю, схеме очень сильно полегчает sm.gif

p.s. Да вот, собственно, пример из другой схемы.
alik_tv
Я отключаю программатор перед проверкой схемы. Эта цепь с резистором просто висит
в воздухе. Вы предлагаете мне ее к питанию притянуть и через емкость на землю?

Сергей Борщ
Цитата(alik_tv @ Feb 11 2014, 23:35) *
Я отключаю программатор перед проверкой схемы. Эта цепь с резистором просто висит
в воздухе.
То есть внешней подтяжки к питанию нет? Тогда чему удивляться?
alik_tv
Цитата(Сергей Борщ @ Feb 12 2014, 10:11) *
То есть внешней подтяжки к питанию нет? Тогда чему удивляться?

Строго говоря, если почитать описание, легко увидеть _внутренний_ "Pull-up Resistor"
сигнала сброса.
Но не вопрос, сегодня вечером проверю.
Сергей Борщ
Цитата(alik_tv @ Feb 12 2014, 11:56) *
легко увидеть _внутренний_ "Pull-up Resistor"
Да знаем мы про него. Его хватает если нога никуда не подключена. А если к ней подведена антенна в виде дорожки через всю плату - будут сюрпризы.
Я бы еще и конденсатор параллельно кнопке убрал, а дребезг давил программно.
alik_tv
Не через всю плату, тут вы загнули. Сразу за резистором разъем начинается.
2*3, типа такого
На картинке 99% длины этой дорожки.
Я и кондер поставил и давлю программно. Другое дело, что этим конденсатором сделал себе новый гембель.
"Возьмите у них этот брак и выдайте другой" (с)

Проверил я с резистором и кондером. Не помогает.
Посмотрел осциком, что на выводе. Есть там мусор при нажатии. Но размах его не более 200мВ, а длительность
не более 500нс, что намного меньше чем надо для BOD.
delamoure
OK.
alik, предлагаю выложить здесь схему и плату в любом доступном формате аля jpg, pdf.
Думаю, мы заблудились в трех соснах и ответ будет очень простым.
alik_tv
схемаНажмите для просмотра прикрепленного файла
плата в файле.
Чего на схеме нет, и на плате нет.
фото платы в зипе.
delamoure
alik, извините за задержку с ответом.
Принципиальных замечаний по схеме/разводке нет.
По плате есть несущественные для вашей проблемы замечания.
Ну как - побороли?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.