Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите плиз
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
kent
Добрый день начал изучать AVR по курсу на сайте [banned].Вроде думал что чего-то понял и решил написать програмку.Как Вы наверное поняли работать она отказалась Если не трудно ткните носом где ошибка.Программа в будующем будет намного сложнее пока решил ограничится самым простым что она должна делать, этим и вызван выбор 128меги.В этом варианте она должна зажигать светодиоды по алгоритму 2-3-2-3-2-3 вперёд или назад в зависимости от того какой логический уровень находится на ножке входа. Всего нужно 6 диодов в бинарном это так :000011 000111 000110 001110 001100 011100 011000 111000 110000 110001 100001 100011 . Ваял сие творение три вечера(до 3 ночи ) в CVAVR. Скомпилил и решил в VMLAB поэмулировать. Сразу загорелись два верхних диода(000011) а при нажатии на кнопку которая должна вызывать прерывание ничего не происходит-вернее происходит переход на СТРОКИ оператора множественного выбора (как и должно быть) по ним ползёт желтая полоска и на этом все- диоды не переключаются как горели первые два так и горят. Сейчас расскажу чего там понаписал(вернее это только я так думаю а VMLAB как оказалось совсем по другому). Подключил хидеры на мегу. Сделал порт А выходом и записал туда число 3(что и соответствует первому варианту включения диодов 000011). Сделал порт В входом с подтяжкой(хотя в будующем нужна будет всего одна ножка входа -сейчас решил не парится и сделал все) Дальше сотворил функцию initialization в которую воткнул(к стати надо ещё раз?) инициализацию портов,разрешил прерывания глобально и прерывание INT0 . Дальше сделал функцию rabota которая и должна переключать диоды с заданым алгоритмом с помощю оператора множественного выбора switch оператор if else по моему скромному разумению должен проверить состояние ножки входа PINB1 и в зависимости от результатов проверки подключить один из switch в котором я указал(повторюсь что это я так думаю) прочитать число в PINA, найти в своих вариантах такое-же число и присвоить порту А число в соответствии заданному алгоритму. Потом описал работу прерывания INT0- вызвать функцию работа. В главной функции происходит инициализация портов и все-сидим ждём прерывания.
Блин пока писал сей труд опять в мозгах ещё раз все прогнал- вроде все правильно?
Хотел послать архив с исходником но что-то хреново представляю как тут это можно сделать.Во сейчас посмотрел что тут длинну сообщения можно большую делать попробую воткнуть.
#include <MEGA128.H>
#include <m8_128.h>
#define PA_OUT DDRA = 3;
#define PB_IN PORTB = 0xFF;
void initialization(void){
PA_OUT DDRA = 3;
PB_IN PORTB = 0xFF;
#asm("sei")
EICRA=0x00;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01; }
void rabota(void){
if(PINB1){
switch(PINA){
case 3:DDRA=7;
break ;
case 7:DDRA=6;
break ;
case 6:DDRA=14;
break ;
case 14:DDRA=12;
break ;
case 12:DDRA=28;
break ;
case 28:DDRA=24;
break ;
case 24:DDRA=56;
break ;
case 56:DDRA=48;
break ;
case 48:DDRA=49;
break ;
case 49:DDRA=33;
break;
case 33:DDRA=35;
break;
case 35:DDRA=3;
break; } }
else{
switch(PINA){
case 3:DDRA=35;
break;
case 35:DDRA=33;
break;
case 33:DDRA=49;
break;
case 49:DDRA=48;
break;
case 48:DDRA=56;
break;
case 56:DDRA=24;
break;
case 24:DDRA=28;
break;
case 28:DDRA=12;
break;
case 12:DDRA=14;
break;
case 14:DDRA=6;
break;
case 6:DDRA=7;
break;
case 7:DDRA=3;
break;} } }
interrupt [EXT_INT0] void ext_int0_isr(void) {
rabota () ; }
void main(void){
initialization() ; }

Влезла ура.Мне кажется что в этом творении много лишнего(а мож и не очень ) но я НЕ ПОНИМАЮ почему она работать не желает. ПОДСКАЖИТЕ ПЛИИИИИИИЗ!!!!!!!!
Это проект для VMLAB
.MICRO "ATmega128"
.TOOLCHAIN "GENERIC"
.TARGET "555.hex"
.COFF "555.cof"
.SOURCE "555__.c"

.POWER VDD=5 VSS=0

.CLOCK 5meg

D1 VDD D1_NODE
R1 D1_NODE PA0 560

D2 VDD D2_NODE
R2 D2_NODE PA1 560

D3 VDD D3_NODE
R3 D3_NODE PA2 560

D4 VDD D4_NODE
R4 D4_NODE PA3 560

D5 VDD D5_NODE
R5 D5_NODE PA4 560

D6 VDD D6_NODE
R6 D6_NODE PA5 560

D7 VDD D7_NODE
R7 D7_NODE PA6 560

D8 VDD D8_NODE
R8 D8_NODE PA7 560

K1 VSS PD0 LATCHED

.PLOT V(PA0) V(PA1) V(PA2) V(PA3) V(PA4) V(PA5) V(PA6) V(PA7)
prottoss
Зачем же Вы меняете в прерывании направление порта А?

Код
if(PINB1){
switch(PINA){
case 3:DDRA=7;
break;
case 7:DDRA=6;
break;
case 6:DDRA=14;
break;
case 14:DDRA=12;
break;
case 12:DDRA=28;
break;
case 28:DDRA=24;
break;
case 24:DDRA=56;
break;
case 56:DDRA=48;
break;
case 48:DDRA=49;
break;
case 49:DDRA=33;
break;
case 33:DDRA=35;
break;
case 35:DDRA=3;
break; } }
else{
switch(PINA){
case 3:DDRA=35;
break;
case 35:DDRA=33;
break;
case 33:DDRA=49;
break;
case 49:DDRA=48;
break;
case 48:DDRA=56;
break;
case 56:DDRA=24;
break;
case 24:DDRA=28;
break;
case 28:DDRA=12;
break;
case 12:DDRA=14;
break;
case 14:DDRA=6;
break;
case 6:DDRA=7;
break;
case 7:DDRA=3;
break;


скорее всего, вместо DDRA (направление порта А), Вам надо записать PORTA (состояние выхода порта А)
GetSmart
для начала в свиче измени все строки типа
case 3:DDRA=7;
break ;

на типа это
case 3:PORTA=7;
break ;

короче все DDRA на PORTA

А в initialization замени
DDRA = 3;
на
DDRA = 0xff;

в обоих свичах измени
switch(PINA){
на
switch(PORTA){

А нажатие клавиши делается сложнее. Нужно отслеживать только момент нажатия и фильтровать дребезг. Чтобы отследить нажатие нужно сравнивать с ранее прочитанным значением. Что-то вроде этого:
char a = oldPINB
if (~(oldPINB = PINB) & a & 2) {если нажата}
else {если не нажата}
kent
Блин во я осёл!!!!!!! Спасибо а дребезга не будет в- реальном устройстве уже цифра будет .Кнопку воткнул чтобы в эмуляторе посмотреть.
kent
Сейчас исправил, заново откомпилировал, загнал в VMLAB не хочет работать тоже самое что и раньше попробывал напротив строчек бряки ставить-короче она почему-то в первом switch е по кругу носится как будто вариантов нет но два верхних диода горят и значит чило 3 в порту А есть.
GetSmart а зачем "в initialization замени
DDRA = 3;
на
DDRA = 0xff;
" ?
варианта 255 в свичах нет да и нельзя на этом порту такому числу быть(по условию задачи) но я и так тоже попробывал не пашет.
Чего-ж ей дуре надо-то? А?
defunct
Цитата(kent @ Jun 18 2006, 23:02) *
GetSmart а зачем "в initialization замени
DDRA = 3;
на
DDRA = 0xff;
" ?
варианта 255 в свичах нет да и нельзя на этом порту такому числу быть(по условию задачи) но я и так тоже попробывал не пашет.
Чего-ж ей дуре надо-то? А?


DDRA - регистр направления порта. Когда какой-то бит в DDRA установлен, то соответвующий вывод порта настроен на вывод. Вы же в своей программе используете порт A для вывода, т.о. логично настроить все его пины на вывод DDRA=0xff;


а вот какой может быть ваша программа (упрощенно, движение в одну сторону):


Код
// массив значений 000011 000111 000110 001110 001100 011100 011000 111000 110000 110001 100001 100011
char data[12] = { 0x03, 0x07, 0x06, 0x0E, 0x0C, 0x1C, 0x18, 0x38, 0x30, 0x31, 0x21, 0x23 };

int main(void)
{
   char i = sizeof(data);
   DDRA = 0xff;

   for(;;){
      i = (i < sizeof(data)-1) ? i+1 : 0;
      PORTA = data[i];
      // сюда можно вставить задержку
   }

}


А чудо курс читать не стоит, не зря он banned
beer_warrior
Ну во-первых DDRA отвечает за напраление - тройка стоит и 2 бита работают. DDRx ставится вначале и без особой нужды не трогаются.
Выходы выставляются через PORTx
во-вторых - опрос IO в свитче не лучшая практика, лучше сбросить все-таки в переменную и от этого плясать. Входы могут изменится во время обработки.
в-третьих более 4-5 case городить не стоит, в таких случаях лучше получать значения табличным методом.
(2-3) на результат не влияют и относятся к стилю программирования,
которое у Кертиса отсутствует как класс smile.gif
kent
Cпасибо разобрался все заработало, а что посоветуете почитать?
defunct
Цитата(kent @ Jun 19 2006, 00:04) *
Cпасибо разобрался все заработало, а что посоветуете почитать?

Даташит на Mega128 и любую книжку по C (лучше справочник, напр неплохой справочник по C/C++ Герберта Шильдта)
kent
Спасибо ещё раз.
beer_warrior
http://cs.mipt.ru/docs/comp/rus/programmin...r_code/main.pdf
http://www.chipinfo.ru/literature/chipnews/200010/10.html
первое, что на глаза попалось.
Еще очень посоветую товарищей Кернигана и Эккеля ибо С он и в Африке С
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.