Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/33: Рейтинг темы: голосов - 33, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
1

ATmega16 не работает код для опроса пинов

15.03.2014, 18:17. Показов 6229. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет всем. У меня не хочет работать код, который в вечном цикле проверяет состояния пинов PD и шифрует это состояние, выводя в PA. При подключении к одному из пинов PD тестируемой кнопки и ее нажатии, ATmega16 делает следующие варианты из списка внизу:
> Не реагирует, но через длительное время вроде как выдает правильное значение
> Выдает правильное значение, а затем зависает и не сбрасывает его
> Выдает неправильное значение
> Выдает всякую кашу вне зависимости от того, приводилась ли mega в действие кнопкой или нет

В чем может быть проблема? Вот программа на Си:
Код
#define F_CPU 8000000L
#define baudrate 4800L

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{

DDRD = 0x00;
DDRB = 0xff;
while(1)
{
if (PIND==0x01){PORTA = 0x08; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x02){PORTA = 0x09; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x04){PORTA = 0x0a; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x08){PORTA = 0x0b; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x10){PORTA = 0x0c; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x20){PORTA = 0x0d; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x40){PORTA = 0x0e; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x80){PORTA = 0x0f; _delay_ms(500); PORTA = 0x00;}
}
}
В программу случайно попала строка с бодрейтом, может все из-за нее?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.03.2014, 18:17
Ответы с готовыми решениями:

Цикл для опроса всех аналоговых пинов и выдача ответа
Кто подскажет что не так? Необходимо считать с аналоговых входов все значения , и дать ответ от...

Помогите составить код опроса для сайта
Вам нравится сайт? Да Нет

Код для опроса сетевой карты и вывод значений в web
Доброго времени суток, подскажите пожалуйста как можно решить следующее: имеются две сетевые карты,...

Код для опроса сетевой карты и запись полученого результата в файл
Доброго времени суток, подскажите пожалуйста как можно решить следующее: имеются две сетевые карты,...

Код для опроса сетевой карты и запись полученого результата в файл
Доброго времени суток, подскажите пожалуйста как можно решить следующее: имеются две сетевые карты,...

19
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
15.03.2014, 18:36 2
1. Надо где-то установить DDRA
2. Проверка нажатия выполняется по маске

Вместо
Код
if(PIND==0x01)
Надо
Код
if(PIND&0x01)
Потому что при нажатии одновременно двух кнопок какое значение будет в регистре PIND?
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 18:57 3
Вместо DDRB = 0xff у меня должен быть DDRA = 0xff, я это уже исправлял, просто забыл изменить здесь. А нажатие больше одной кнопки мне пока не нужно, поэтому оставил == вместо &.
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
15.03.2014, 20:07 4
Цитата Сообщение от wiyrdbomomo
нажатие больше одной кнопки мне пока не нужно, поэтому оставил == вместо &.
Ну и что? Всё равно надо сразу писать правильно, с маской. В размере кода и скорости его исполнения ничего не изменится, а код станет универсальным.

Кнопки в нажатом состоянии какой лог.уровень дают - низкий или высокий? Если низкий, то программа не будет работать в нынешнем варианте с "==".

Кроме этого, здесь не надо строить цепочку из независимых операторов "if", особенно когда внутри каждого стоит задержка. Используйте зависимые опреаторы if - else if - else if - ... - else. Тогда поведение кнопок станет адекватным.
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
15.03.2014, 20:20 5
какой лог.уровень дают - низкий или высокий?
Судя по PIND==0x01 и т.д - высокий
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
15.03.2014, 20:27 6
Цитата Сообщение от YTYOUT
Судя по PIND==0x01 и т.д - высокий
А вот я в этом не уверен. Эта запись говорит лишь о том, что ТС думал, что нажатая кнопка отображается единицей в программе на Си. Между тем в программе нет включения pull-up резисторов для кнопок, не упоминаются также и внешние pull-down резисторы. А если нет ни тех, ни тех - кнопки должны работать? ;-)

Если бы мы говорили о чётко работающей программе, тогда да, "==1" указывало бы на активный высокий уровень.
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 20:51 7
Программу тестирую на плате Pinboard II, про уровни кнопок уже вообще не уверен. Можно сказать, что микросхемы в руки вчера взял и поэтому мало что понимаю в данной теме, а обучиться радиоэлектронике страсть как хочется :)
Что же именно мне следует добавить в программу, чтобы все работало? Судя по схеме Pinboard II, кнопки ведут на землю, то есть выдают низкий уровень.
0
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.03.2014, 21:56 8
Нужно инвертировать константы. Например первая сейчас 0x01, это в бинарном 0b00000001. Инвертируем и получаем 0b11111110. В хексе это будет 0xFE. Остальные по аналогии.
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 22:13 9
Цитата Сообщение от itysiy
Нужно инвертировать константы.
Пробовал инвертировать, как ни странно, не помогло. Попробую для верности описывать константы двоичным значением вместо шестнадцатеричного. Или все-таки где-то еще ошибся? Вот программа:
Код
#define F_CPU 1000000UL

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 0x00;
DDRA = 0xff;
PORTA = 0x00;
while(1)
{
if (PIND==0xfe){PORTA = 0x08; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xfd){PORTA = 0x09; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xfb){PORTA = 0x0a; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xf7){PORTA = 0x0b; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xef){PORTA = 0x0c; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xdf){PORTA = 0x0d; _delay_ms(500); PORTA = 0x00;}
if (PIND==0xbf){PORTA = 0x0e; _delay_ms(500); PORTA = 0x00;}
if (PIND==0x7f){PORTA = 0x0f; _delay_ms(500); PORTA = 0x00;}
}
return 0;
}
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
15.03.2014, 22:16 10
Схемку бы для полного понимания
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 22:25 11
Подключал все на Pinboard II. Вот ее схема (высокое разрешение). Для теста подсоединял одну из кнопок (вывод BTN1) к какому-нибудь пину из PORTD, а PORTA0..3 подсоединял к светодиодной шкале, которая идет на землю.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 57
15.03.2014, 22:31 12
а чем смотрите изменения на выходе порта А ?
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 22:35 13
Светодиодной шкалой, которая уходит в землю через резисторы на 200 Ом. Задержку в полсекунды поставил специально для того, чтобы отследить показания.
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 57
15.03.2014, 22:49 14
PORTD=0xFF поставить вначале, чтобы включить подтяжку входов к "1"
0
0 / 0 / 0
Регистрация: 13.07.2013
Сообщений: 20
15.03.2014, 23:26 15
Спасибо, imox! Все заработало. Сижу довольный как слон:)
Только работает почему-то только когда я удерживаю кнопку, а задержки в 500 мс нету. Может быть delay.h нужно как-то "запихнуть" в .hex файл?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
16.03.2014, 00:51 16
Цитата Сообщение от wiyrdbomomo
Спасибо, imox! Все заработало. Сижу довольный как слон:)
Только работает почему-то только когда я удерживаю кнопку, а задержки в 500 мс нету. Может быть delay.h нужно как-то "запихнуть" в .hex файл?
Задержка может и работает. Если вы не установили фьюзы на кварц, то МК работает на 1 мгц (500*8=5 с). И вы убираете пальцы с кнопок раньше, чем задержка заканчивается. Как вариант. Сделайте тестовый код, чтобы светодиод моргнул 1 секунду. Так вы поймете соответствие реальной и ожидаемой частоты.
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
16.03.2014, 15:24 17
Цитата Сообщение от wiyrdbomomo
Все заработало. Сижу довольный как слон:)
Сразу-то прочитать не судьба было?
Цитата Сообщение от OtyxPM
Между тем в программе нет включения pull-up резисторов для кнопок
Или не знаете, кАк подтягивающие резисторы во входных портах AVR включаются? Тогда срочно учить матчасть. Хотя бы "Учебный курс AVR" на этом сайте прочтите.
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
16.03.2014, 15:26 18
Цитата Сообщение от itysiy
Нужно инвертировать константы. Например первая сейчас 0x01, это в бинарном 0b00000001. Инвертируем и получаем 0b11111110. В хексе это будет 0xFE. Остальные по аналогии.
Не обязательно инвертировать.
Если бы ТС не упорствовал и сделал проверку по маске вместо сравнения с константами, код бы заработал хоть с инверсией, хоть без неё.

"== 0xFE" ("== ~0x01") - такой же костыль, что и "== 0x01" :-(
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
16.03.2014, 17:39 19
Есть разница?

Код
//==============================================================
// Inputs:
#define KEYS_PIN PIND
//--------------------------------------------------------------------------------
#define KEY_1 0
#define KEY_2 1
#define KEY_3 2
#define KEY_4 3
#define KEY_5 4
#define KEY_6 5
#define KEY_7 6
#define KEY_8 7
//==============================================================

//==============================================================
// Outputs:
#define LEDS_DDR
//--------------------------------------------------------------------------------
#define LED_1 0
#define LED_2 1
#define LED_3 2
#define LED_4 3
#define LED_5 4
#define LED_6 5
#define LED_7 6
#define LED_8 7
//==============================================================

//==============================================================
#include "debug.h"

//========================================================================
extern void tid_1_on (void) {LEDS_DDR |= (1<<LED1);}
//------------------------------------------------------------------------
extern void tid_1_off (void) {LEDS_DDR &= (~(1<<LED1));}
//------------------------------------------------------------------------
extern void tid_1_switch (void) {LEDS_DDR ^= (1<<LED1);}
//========================================================================

//========================================================================
extern void tid_2_on (void) {LEDS_DDR |= (1<<LED2);}
//------------------------------------------------------------------------
extern void tid_2_off (void) {LEDS_DDR &= (~(1<<LED2));}
//------------------------------------------------------------------------
extern void tid_2_switch (void) {LEDS_DDR ^= (1<<LED2);}
//========================================================================

//========================================================================
extern void tid_3_on (void) {LEDS_DDR |= (1<<LED3);}
//------------------------------------------------------------------------
extern void tid_3_off (void) {LEDS_DDR &= (~(1<<LED3));}
//------------------------------------------------------------------------
extern void tid_3_switch (void) {LEDS_DDR ^= (1<<LED3);}
//========================================================================

//========================================================================
extern void tid_4_on (void) {LEDS_DDR |= (1<<LED4);}
//------------------------------------------------------------------------
extern void tid_4_off (void) {LEDS_DDR &= (~(1<<LED4));}
//------------------------------------------------------------------------
extern void tid_4_switch (void) {LEDS_DDR ^= (1<<LED4);}
//========================================================================

//========================================================================
extern void tid_5_on (void) {LEDS_DDR |= (1<<LED5);}
//------------------------------------------------------------------------
extern void tid_5_off (void) {LEDS_DDR &= (~(1<<LED5));}
//------------------------------------------------------------------------
extern void tid_5_switch (void) {LEDS_DDR ^= (1<<LED5);}
//========================================================================

//========================================================================
extern void tid_6_on (void) {LEDS_DDR |= (1<<LED6);}
//------------------------------------------------------------------------
extern void tid_6_off (void) {LEDS_DDR &= (~(1<<LED6));}
//------------------------------------------------------------------------
extern void tid_6_switch (void) {LEDS_DDR ^= (1<<LED6);}
//========================================================================

//========================================================================
extern void tid_7_on (void) {LEDS_DDR |= (1<<LED7);}
//------------------------------------------------------------------------
extern void tid_7_off (void) {LEDS_DDR &= (~(1<<LED7));}
//------------------------------------------------------------------------
extern void tid_7_switch (void) {LEDS_DDR ^= (1<<LED7);}
//========================================================================

//========================================================================
extern void tid_8_on (void) {LEDS_DDR |= (1<<LED8);}
//------------------------------------------------------------------------
extern void tid_8_off (void) {LEDS_DDR &= (~(1<<LED8));}
//------------------------------------------------------------------------
extern void tid_8_switch (void) {LEDS_DDR ^= (1<<LED8);}
//==============================================================

//==============================================================
void main (void)
{
//.........
//.........
//.........

// Так:
//   if (!(KEYS_PIN & (1<<KEY_1))) {tid_1_on (); _delay_ms(500); tid_1_off ();}
// Или так:
if (!(KEYS_PIN & (1<<KEY_1)))
{
tid_1_on ();
_delay_ms(500);
tid_1_off ();
}
// Или так:
//   if (KEYS_PIN & (1<<KEY_1)) {tid_1_on (); _delay_ms(500); tid_1_off ();}
// Или так:
if (KEYS_PIN & (1<<KEY_1))
{
tid_1_on ();
_delay_ms(500);
tid_1_off ();
}
}
0
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
16.03.2014, 20:02 20
Цитата Сообщение от OtyxPM
Не обязательно инвертировать...
Конечно это дикий костыль, и код приведенный ТС костыль, но что он хотел услышать, то я ему и сказал. Когда он в следующий раз со знанием дела придет на форум за этим вопросом, тогда ему и расскажем :)
0
16.03.2014, 20:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.03.2014, 20:02
Помогаю со студенческими работами здесь

MPI | Код опроса наличия данных
Нужно написать код опроса наличия данных в каждом из 4 каналов, ввод данных из канала по готовности...

Не работает программа опроса персонала на месторождении
В одном месте происходит ошибка, подскажите пожалуйста в чем дело, за ранее спасибо. unit Unit1; ...

Обозначение пинов в прошивке для MSP430
У меня естько плата MSP430 и два микроконтроллера к ней. У этих микроконтроллерах ( и у некоторых...

PWM Input для нечётных каналов (пинов)
Вобщем, надо захватить DutyCycle и частоту PWM входа. Это для DHT22 сенсора, если что. Примеры от...

не работает клавиатура на Atmega16
Здравствуйте. в своем проекте сделал четырехкнопочную клавиатуру. для этого подтянул...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru