Страница 230 из 421

Re: CodeVision AVR в вопросах и ответах

Добавлено: Вт янв 01, 2013 19:08:53
vitalik_1984
Верно я не вникал что он хочет делать, но натягивать трусы через голову не правильно
Я тоже так считаю.Как потом разделить, завис ли контроллер или просто прерывание обычное нужно провести?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 12:24:16
леня
как написать чтоб при нажатии на кнопку (пинВ.0) к переменной прибавлялось 1 ?
если писать просто if (PINB.0 = 1) {x++}; то к переменной прибавляется дохрена

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 12:59:08
vitalik_1984
есть тема помогите опросить кнопку там есть несколько примеров.
Самый простой добавить после вашей строки

Код: Выделить всё

while (PINB.0 = 1) {}; 

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 13:14:09
леня
а можно полностью написать а то чёто я непонмаю :dont_know:

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 13:30:19
vitalik_1984
Видать совсем после праздников трудно соображать :)))
добавить после вашей строки

Код: Выделить всё

 if (PINB.0 = 1) {x++}; //ваша строка
while (PINB.0 = 1) {}; // то, что нужно добавить
 
Чего непонятно то?
Алгоритм работает так:
нажали, если та кнопка, что требуется, то прибавили.(Ваша часть)
Дальше ждем, пока кнопку отпустят.(моя добавка)

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 13:37:54
леня
понял. щас попробую :)

Re: CodeVision AVR в вопросах и ответах

Добавлено: Ср янв 02, 2013 13:48:20
леня
вроде работает 8)

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 07:29:34
mr4ester
Сначала хотелось бы поздравить всех с уже наступившим новым годом. А теперь к делу, пытаюсь написать функцию для опроса 12 сенсоров, но так как они висят на разных портах возникли трудности, на просторах инета нашел программу для опроса 8 кнопок, вот кусок где калибруются датчики

Код: Выделить всё

void Calibrate()  //Калибруем все сенсоры по очереди
{
unsigned char i=1,k=0;
    while(i!=0)
    {
        TCNT1=0x0000;   // обнуляем счетный регистр
        TCCR1B=0x01; // разрешаю счет таймера1
        DDRD = ~i;// настраиваем пин порта на вход
        while((PIND&i)==0); // жду пока не появится 1 на пине порта
        TCCR1B=0x00; //останавливаю таймер
        DDRD|=i;  // конфигурирую пин на выход состояние Hi-Z
        SensorTimes[k]=TCNT1; // присваиваю время зарядки сенсора
        SensorHI[k]=SensorTimes[k]+70; //задаю верхний предел
        SensorLO[k]=SensorTimes[k]+20; // и нижний
        k++;                           // увеличиваю переменную на 1
        i<<=1;                         //сдвигаю 1 влево
    }
чтоб опросить все датчики, приходит в голову только такая конструкция, объявить переменную которая будет ссылкой на название порта, то есть сделать что то вроде

Код: Выделить всё

void Calibrate()  //Калибруем все сенсоры по очереди
{
unsigned char i=1,k=0;
  DDR_X = DDRD    // присваиваю "переменной" порт с которым работаю
    while(i!=0)
    {
      
        TCNT1=0x0000;   // обнуляем счетный регистр
        TCCR1B=0x01; // разрешаю счет таймера1 
        DDR_X = ~i;// настраиваем пин порта на вход
        .
        .   
        .
        if (i == 0x80){
        DDR_X = DDRB;
        i == 0;
        }
          k++;                           // увеличиваю переменную на 1
        i<<=1;                         //сдвигаю 1 влево
    }
это к примеру, но я не знаю как объявить с помощью дерективы #define?
Или если можете подскажите как правильно делать опрос с 2х портов.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 16:38:17
vitalik_1984
а вам не приходила в голову идея сделать в виде матрицы? 12 ног убивать как то не очень, а так всего 7 и на одном порту висеть будет.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 18:33:17
mr4ester
приходила, но в данном случае это несущественно, имеется только 8 меги, и не вижу смысла экономить, ну как вариант можно и так сделать. Но хотелось бы разобраться с данной проблемой, тут уже просто спортивный интерес.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 18:53:14
Аlex
подскажите как правильно делать опрос с 2х портов.
Правильно будет сделать это через указатели. Но я как-то пробовал в CV создать указатель на порт и поработать с ним - не получилось. Видимо, атмелам подобное не дано...
Придётся создавать ф-ии для работы с битом, в которую будет передаваться порядковый № порта и № бита, а в ней уже выбирать порт через switsh из задефайненых названий.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 18:55:13
vitalik_1984
обычное условие можно сделать число x двигаем,когда число больше чем 128(0b10000000) один порт, если меньше другой порт.вот и все.
Видимо, атмелам подобное не дано...
Вроде как можно писать в порт по полной адресации.Надо будет подумать над этим.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 19:18:49
mr4ester
vitalik_1984 писал(а):обычное условие можно сделать число x двигаем,когда число больше чем 128(0b10000000) один порт, если меньше другой порт.вот и все.
ну так я и делаю вот эта условие

Код: Выделить всё

  if (i == 0x80){
        DDR_X = DDRB;
        i == 0;
только так придется 2 раза писать одни и те же условия для порта B и D. Что то вроде

Код: Выделить всё

void Calibrate()  //Калибруем все сенсоры по очереди
{
unsigned char i=1,k=0;
    while(i!=0)
    {  
 
        TCNT1=0x0000;   // обнуляем счетный регистр
        TCCR1B=0x01; // разрешаю счет таймера1
        DDRD = ~i;// настраиваем пин порта на вход
        while((PIND&i)==0); // жду пока не появится 1 на пине порта
        TCCR1B=0x00; //останавливаю таймер
        DDRD|=i;  // конфигурирую пин на выход состояние Hi-Z
        SensorTimes[k]=TCNT1; // присваиваю время зарядки сенсора
        SensorHI[k]=SensorTimes[k]+70; //задаю верхний предел
        SensorLO[k]=SensorTimes[k]+20; // и нижний
        k++;                           // увеличиваю переменную на 1
        i<<=1;                         //сдвигаю 1 влево
       
         if ( i == 0x80)
        {
        while (i! = 0)
         {
         i = 1;
         TCNT1=0x0000;   // обнуляем счетный регистр
        TCCR1B=0x01; // разрешаю счет таймера1
        DDRB = ~i;// настраиваем пин порта на вход
        while((PINB&i)==0); // жду пока не появится 1 на пине порта
        TCCR1B=0x00; //останавливаю таймер
        DDRB|=i;  // конфигурирую пин на выход состояние Hi-Z
        SensorTimes[k]=TCNT1; // присваиваю время зарядки сенсора
        SensorHI[k]=SensorTimes[k]+70; //задаю верхний предел
        SensorLO[k]=SensorTimes[k]+20; // и нижний
        k++;                           // увеличиваю переменную на 1
        i<<=1;                         //сдвигаю 1 влево
        if (i == 0x08 ) // использую у порта B использую только 4 пина 
         {
          i=0;
          }
        }
       }
        
    }
я только начал учить СИ. так что если я не прав, прошу поправить меня.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 19:25:34
Аlex

Код: Выделить всё

        SensorTimes[k]=TCNT1; // присваиваю время зарядки сенсора
Плюс ещё нужно подумать о переполнении таймера, т.е. добавить обработчик прерываний по переполнению и инкрементировать в нём старшие байты времени заряда. Иначе, если таймер переполнится, Вы получите неправильное значение.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 19:37:24
mr4ester
ну это да, я напишу обработчик прерывания на всякий случай и сделаю проверку условия в программе, хотя теоретически пластинка сенсора имеет емкость в несколько пикофарад пусть 10, то время заряда через резистор 1 МОм будет 10^6*10^(-12) = 10^(-6) c, ну с прикосновением конечно гораздо больше, так что на всякий случай сделать проверку условием, не помешает. А что на счет выше написанного мной, так и придется писать,? просто как то мне это не очень нравиться, ведь помимо калибровки которая происходит только при включении устройства, по переполнению таймера0 происходит основной опрос клавиатуры, где и сравнивается текущее время заряда, с числом полученным при калибровке.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 19:59:11
vitalik_1984
Можно сделать подпрограмму смены направления и чтения и вызывать в нужном месте.Основной повторяющийся код не нужно переписывать.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 20:02:40
Аlex
Вам нужно вот эти 2 строки

Код: Выделить всё

        DDRD = ~i;// настраиваем пин порта на вход
        DDRD|=i;  // конфигурирую пин на выход состояние Hi-Z
и выражение заменить на подпрограммы, в которые Вы будете передавать номер сенсора. А вот как подпрограммы будут обращаться к битам портов по этим номерам, это нужно думать.
Пока я вижу только один вариант - дефайнить порт и номер бита каждого сенсора, а в продпрограммах, через switch, работать с ними.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 20:14:58
mr4ester
а если попробовать так, создать переменную в которой будет хранится и меняться адрес порта, ведь на сколько я понимаю порт это регистр с определенным адресом, и в процессе выполнения программы к примеру того же условия

Код: Выделить всё

if (i == 0x80)
переменной уже присваиваем адрес порта б, ну к примеру

Код: Выделить всё

Name_Port = 0x35 // к примеру это адрес порта B
Name_Port  = ~i
правда я не знаю как в микроконтроллере записывать по адресу, вообщем это имеет смысл, или этой мой дурной полет мысли?

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 20:24:35
Аlex
Мыслите правильно, но в атмелах такое не получается, по крайней мере в CV. Я об этом уже писал выше.

Re: CodeVision AVR в вопросах и ответах

Добавлено: Пт янв 04, 2013 20:36:31
mr4ester
понял, спасибо, буду что то думать.
п.с. Просмотрел даташит на мегу8, в самом конце нашел адреса портов, но как то непонятно они записаны, например PORTB записан как 0x18 (0x38)