Натройка порта AVR C++

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
wir_wolf
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Чт май 05, 2011 22:37:15
Контактная информация:

Натройка порта AVR C++

Сообщение wir_wolf »

Доброго времени суток уважаемые котЫ.
Вопрос плёвый, для тех кто знает с++ и avr ки.
Я пишу программу которая бы считала булевые функции.
Примерно все выглядит так
http://s15.radikal.ru/i189/1105/de/02df1c273954.jpg
Вот мой сорс


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

/*
 * Boolean_function.c
 *
 * Created: 12.05.2011 20:19:52
 *  Author: Wir_Wolf
 */

#define F_CPU 8000000UL

#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "UART_routines.h"
#include "temp.h"


//#define ProgramUP   PORTB,0;
//#define ProgramDOWN   PORTB,1;
//#define on 1;
//#define off 0;
//#define is_high(x,y) (x & _BV(y)) == _BV(y) //(for input) checks if the input is high (Logic 1)
//#define sbi(x,y) x |= _BV(y) //set bit
//#define cbi(x,y) x &= ~(_BV(y)) //clear bit

#define BUTTON1 PINB.0
#define BUTTON2 PINB.1
#define BUTTON3 PINB.2

void Konjunkcija(void);





int main( void )
{
   unsigned char buff[40];
   int programma = 0;
   int i;
   unsigned char temp, pressedButton, myCounter=0;
   
   uart0_init();
   _delay_ms(10);
   sendStr0("*****Hello*****");
   sprintf(buff,"Booleon Function ©Wir_Wolf");
      transmitString(buff);
   
      DDRC=0xff;
      DDRB = 0000;
      
      /* for(i = 1; i <= 1000; i++)  // цикл "для", повторяющийся 10 раз
         {

             PORTC |= _BV(PC0);    // установить "1" (высокий уровень) на выводе PD1,
                    //зажечь светодиод
                  

             _delay_ms(250);      // ждем 0.25 сек.

             PORTC &= ~_BV(PC0);   // установить "0" (низкий уровень) на выводе PD1,
                    //погасить светодиод

             _delay_ms(250);      // ждем 0.25 сек.

         }*/
   while(1)
   {
      
        if (PINB.0 == 0)
        { // Кнопка на PC0 - сброс клавиатуры           
             PORTC |= _BV(PC0);//зажечь светодиод
            _delay_ms(250);      // ждем 0.25 сек.
               PORTC &= ~_BV(PC0);
            _delay_ms(250);
        }   
      }      
         
/*while(1)
   { 
      pressedButton = ~PINB;
      if (pressedButton)       // Check if any button is pressed
      {
         switch ( pressedButton )
         {
            case (1<<PB0):
               PORTC |= _BV(PC0);//зажечь светодиод
               _delay_ms(250);      // ждем 0.25 сек.
               PORTC &= ~_BV(PC0);
               _delay_ms(250);
            break;       
            case (1<<PB1):
                 
            break;   
            case (1<<PB2):
            
            break;
        }
   }       
   
/*   switch(programma){
         case 1:Konjunkcija();break;
         case 2:Konjunkcija();break;
      }         
   }*/
}










void Konjunkcija(){
   uart0_init();
   _delay_ms(10);
   sendStr0("Function Konjunkcija");
}


тут 70% закоментировано так как я тупо не могу получить значение. Нужно настроить первых 4 прина порта B на вход.
PB0 и PB1 это конкпи переключения между программами. а PB2 и PB3 x и у. Сколько я уже не изголялся над кодом.

В нете нашел пример кода типу

#define BUTTON1 PINB.0
if(BUTTON1==0) то инкрементим щетчик в котором номер программы.
авр студия как всегда отчлечается своим умом и сообразительностью.

Error 4 expected ')' before numeric constant C:\Users\Wir_Wolf\Desktop\bool\Boolean_function\Boolean_function.c 78 18 Boolean_function


http://easyelectronics.ru/avr-uchebnyj- ... atury.html
а тут все хороше компилится

потом нашел некий сорс тоже с обработчиками кнопок
http://forum.cxem.net/index.php?showtop ... t&p=579342

скачал, все зашибись.
код примерно

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

  while(1)
  { 
    pressedButton = ~PIND;
    if (pressedButton)       // Check if any button is pressed
    {
      do{temp = ~PIND;}      // Wait until key released
      while (temp);
     
      switch ( pressedButton )
      {
        // Send a Generall Call
        case (1<<PD0):     
          messageBuf[0] = TWI_GEN_CALL;     // The first byte must always consit of General Call code or the TWI slave address.
          messageBuf[1] = 0xAA;             // The command or data to be included in the general call.
          TWI_Start_Transceiver_With_Data( messageBuf, 2 );
          break;

        // Send a Address Call, sending a command and data to the Slave         
        case (1<<PD1):     
          messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
          messageBuf[1] = TWI_CMD_MASTER_WRITE;             // The first byte is used for commands.
          messageBuf[2] = myCounter;                        // The second byte is used for the data.
          TWI_Start_Transceiver_With_Data( messageBuf, 3 );
          break;

        // Send a Address Call, sending a request, followed by a resceive         
        case (1<<PD2):     
          // Send the request-for-data command to the Slave
          messageBuf[0] = (TWI_targetSlaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
          messageBuf[1] = TWI_CMD_MASTER_READ;             // The first byte is used for commands.
          TWI_Start_Transceiver_With_Data( messageBuf, 2 );

          TWI_operation = REQUEST_DATA;         // To release resources to other operations while waiting for the TWI to complete,
                                                // we set a operation mode and continue this command sequence in a "followup"
                                                // section further down in the code.
        /*           
        // Get status from Transceiver and put it on PORTB
        case (1<<PD5):
          PORTB = TWI_Get_State_Info();
          break;

        // Increment myCounter and put it on PORTB         
        case (1<<PD6):     
          PORTB = ++myCounter;       
          break;
         
        // Reset myCounter and put it on PORTB
        case (1<<PD7):     
          PORTB = myCounter = 0;       
          break;*/ 
      }
    }   

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

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

            case (1<<PB0): 
sendStr0("Button1 == 1");
            break;

Терминал молчит.
Мне подсказали что нужно каким то образом перестроить порт, чтобы он принимал аналоговый сигнал, а цифровой, но как это сделать не неаю.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Натройка порта AVR C++

Сообщение Мастер Ломастер »

во-первых, у тебя не С++, а простой тривиальный Си.
во-вторых, о кнопках и их обработке на этом форуме уже столько было обсуждений - воспользуйся поиском. у тебя обычная беда: нет подавелния дребезга кнопок.

настройка порта делается элементарно: DDRx = 255; PORTx = 255; - настроить все 8 пинов порта x на ввод кнопок, которые замыкают пин на массу.
битва с дураками проиграна, победители торжествуют. слава победителям!
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Натройка порта AVR C++

Сообщение urry »

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

pressedButton = ~PIND;
  if (pressedButton)       // Check if any button is pressed
    {
      do{temp = ~PIND;}      // Wait until key released
      while (temp);

Я не знаю, как поведет себя оптимизатор компилятора при работе с такой конструкцией - как вариант, один раз прочитает из порта в переменную, а потом будет опрашивать переменную до победного конца.
Таких вещей вообще боюсь - опрашивайте порт, а не переменную, плюс к тому же как заметили - антидребезг, все дела ...
И пользуйтесь макросами, наконец, они понятней.
А то стоят в коде, как три тополя на плющихе

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

#define BITTST1(var,bitno) ((var) & (1 << (bitno)))
#define sbi(x,y) x |= _BV(y) //set bit
#define cbi(x,y) x &= ~(_BV(y)) //clear bit

#define BUTTON1 0
#define BUTTON2 1

if(BITTST1(PIND,BUTTON1)) - проверка на 1
if(!BITTST1(PIND,BUTTON1)) - проверка на 0
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Натройка порта AVR C++

Сообщение Jack_A »

Мастер Ломастер писал(а):настройка порта делается элементарно: DDRx = 255; PORTx = 255; - настроить все 8 пинов порта x на ввод кнопок, которые замыкают пин на массу.

Как выяснилось, не так уж и элементарно. Приведенный пример - настройка на вывод единиц во всех разрядах. Если верить даташиту, то ввод с подтяжкой к высокому уровню - DDRx = 0; PORTx = 255; Можно, наверное, и как указано - коротя на землю выходной транзистор, пытающийся тянуть пин в единицу, получить ноль, но это уже через Альпы, и долго он так не протянет.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Натройка порта AVR C++

Сообщение ARV »

urry писал(а):Я не знаю, как поведет себя оптимизатор компилятора при работе с такой конструкцией - как вариант, один раз прочитает из порта в переменную, а потом будет опрашивать переменную до победного конца.
Таких вещей вообще боюсь - опрашивайте порт, а не переменную, плюс к тому же как заметили - антидребезг, все дела ...
бояться не надо, все регистры периферии AVR определены как volatile-переменные, так что никаких козней оптимизатора не будет :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
alex1126
Вымогатель припоя
Сообщения: 567
Зарегистрирован: Ср дек 19, 2012 12:16:22

Re: Натройка порта AVR C++

Сообщение alex1126 »

ARV писал(а):бояться не надо, все регистры периферии AVR определены как volatile-переменные, так что никаких козней оптимизатора не будет :)

вот такой у меня код:

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

while (~(PINA & (1<<H_END))) {
    PORTC |=(1<<CLK);
    _delay_ms(100);
    PORTC &= ~(1 << CLK);
   _delay_ms(100);
   if ((PINA & (1<<H_END))==1) lcd_dat('1');
   if ((PINA & (1<<H_END))==0) lcd_dat('0');
}

и цикл while не прерывается, хотя единичка появляется в порту. Я думал что это из-за оптимизации....
alex1126
Вымогатель припоя
Сообщения: 567
Зарегистрирован: Ср дек 19, 2012 12:16:22

Re: Натройка порта AVR C++

Сообщение alex1126 »

сорри, погорячился :)

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

while ((PINA & (1<<H_END))==0) {

вот так все работает :) всем спасибо, все свободны.... хотя интересно, конечно, почему так не заработало.....
Ответить

Вернуться в «AVR»