Thursday, July 5, 2012

Opća shema tipke

Evo kratkog tutorijala kako spojiti tipku na neki čip...
Ova shema je isprobana na PIC mikrokontrolerima i tamo je izvrsno radila, danas sam uspjela isprobati tu istu shemu i na armu i radi više nego izvrsno! :)

1. Ovako izgleda shema po kojoj bi trebalo spojiti tipku na čip.
Čip koji je u ovom primjeru upotrebljen je neki koji sam našla u programu (za crtanje shema), tako da se previše ne zamarajte time. Bitno je uočiti 2 važna elementa na ovoj slici, otpornik od 10k oma i tipka te način na koji su spojeni međusobno i način kako su spojeni na čip. Pošto ta dva elementa nisu polarizirani ne morate paziti kako ćete ih okrenuti.

Za neke koji 1. put ovo slažu bitno je da uočite GND i +5V, to je isti onaj napon na koji spajate čip, ukoliko vam se čip nalazi na nekoj pločici koja je USB-om spojena na komp, onda ćete taj napon dobiti tako da s čipa "izvučete" njegov GND i +5V.


2.  Na ovim slikama ću pokazati kako se to u stvarnosti spaja...

Na zadnjoj slici je prikazano izbliza kako izgleda onaj dio sheme samo s tipkom, a ledica je dodana zbog provjere ispravnosti interrupta.

Program (kod) sam preuzela sa ove stranice, to je primjer (unutar .zip foldera) gpio.
Jedino što morate promijeniti je:

1.  u datoteci gpiotest.c "zalijepite" samo ovaj kod:
-------------------------------------------------------------------------------------------------------------------------
#include "LPC13xx.h"          
#include "gpio.h"

volatile uint32_t val=0;

int main (void){

  GPIOInit(); //inicijalizacija GPIO-a, to samo napišete narebu niš ne dirate

  GPIOSetDir( PORT2, 2, 0 ); //P2.2 trigger ovdje definitare na kojem portu i koji pin će biti tipka
  GPIOSetDir( PORT2, 1, 1 );//P2.1 LED ovdje je definirano na kojem portu i koji pin je led

  GPIOSetInterrupt( PORT2, 2, 0, 0, 0 );
  GPIOIntEnable( PORT2, 2 );

  while( 1 ){
      GPIOSetValue( PORT2, 1, 0 ); //LED je izgašena jer tipka nije stisnuta
  };
}
-------------------------------------------------------------------------------------------------------------------------

2. u datoteci gpio.c sve pobrišete i ovo zalijepite: (najvjerojatnije ima dosta nepotrebnih linija koda, al pošto učim kako sve to funkcionira, nadam se da mi opraštate :P)

-------------------------------------------------------------------------------------------------------------------------
#include "LPC13xx.h"            /* LPC13xx Peripheral Registers */
#include "gpio.h"

/* ===================
 * CodeRed - Modified file to extract out interrupt handler related code,
 * which is really application project specific.
 * Set TIMER16_GENERIC_INTS to 1 to reenable original code.
 * =================== */
#define GPIO_GENERIC_INTS 1

#ifdef GPIO_GENERIC_INTS
volatile uint32_t gpio0_counter = 0;
volatile uint32_t gpio1_counter = 0;
volatile uint32_t gpio2_counter = 0;
volatile uint32_t gpio3_counter = 0;
volatile uint32_t p0_1_counter  = 0;
volatile uint32_t p1_1_counter  = 0;
volatile uint32_t p2_1_counter  = 0;
volatile uint32_t p3_1_counter  = 0;

void PIOINT2_IRQHandler(void)
{
  volatile uint32_t val=0;
  uint32_t regVal;
  val=1;
  gpio2_counter++;
  regVal = GPIOIntStatus( PORT2, 2 );

  while (1){
      GPIOSetValue( PORT2, 1, 1 );
  }
  if ( regVal )
  {
    p2_1_counter++;
    GPIOIntClear( PORT2, 2 );
  }       
  return;
}

#endif //GPIO_GENERIC_INTS

/*****************************************************************************
** Function name:        GPIOInit
**
** Descriptions:        Initialize GPIO, install the
**                        GPIO interrupt handler
**
** parameters:            None
** Returned value:        true or false, return false if the VIC table
**                        is full and GPIO interrupt handler can be
**                        installed.
**
*****************************************************************************/
void GPIOInit( void )
{
  /* Enable AHB clock to the GPIO domain. */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

#ifdef __JTAG_DISABLED 
  LPC_IOCON->JTAG_TDO_PIO1_1  &= ~0x07;
  LPC_IOCON->JTAG_TDO_PIO1_1  |= 0x01;
#endif

  /* Set up NVIC when I/O pins are configured as external interrupts. */
  NVIC_EnableIRQ(EINT0_IRQn);
  NVIC_EnableIRQ(EINT1_IRQn);
  NVIC_EnableIRQ(EINT2_IRQn);
  NVIC_EnableIRQ(EINT3_IRQn);
  return;
}

/*****************************************************************************
** Function name:        GPIOSetInterrupt
**
** Descriptions:        Set interrupt sense, event, etc.
**                        edge or level, 0 is edge, 1 is level
**                        single or double edge, 0 is single, 1 is double
**                        active high or low, etc.
**
** parameters:            port num, bit position, sense, single/doube, polarity
** Returned value:        None
**
*****************************************************************************/
void GPIOSetInterrupt( uint32_t portNum, uint32_t bitPosi, uint32_t sense,
            uint32_t single, uint32_t event )
{
  switch ( portNum )
  {
    case PORT0:
      if ( sense == 0 )
      {
        LPC_GPIO0->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO0->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO0->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO0->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO0->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO0->IEV |= (0x1<<bitPosi);
    break;
     case PORT1:
      if ( sense == 0 )
      {
        LPC_GPIO1->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO1->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO1->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO1->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO1->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO1->IEV |= (0x1<<bitPosi); 
    break;
    case PORT2:
      if ( sense == 0 )
      {
        LPC_GPIO2->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO2->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO2->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO2->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO2->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO2->IEV |= (0x1<<bitPosi); 
    break;
    case PORT3:
      if ( sense == 0 )
      {
        LPC_GPIO3->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO3->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO3->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO3->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO3->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO3->IEV |= (0x1<<bitPosi);     
    break;
    default:
      break;
  }
  return;
}

/*****************************************************************************
** Function name:        GPIOIntEnable
**
** Descriptions:        Enable Interrupt Mask for a port pin.
**
** parameters:            port num, bit position
** Returned value:        None
**
*****************************************************************************/
void GPIOIntEnable( uint32_t portNum, uint32_t bitPosi )
{
  switch ( portNum )
  {
    case PORT0:
      LPC_GPIO0->IE |= (0x1<<bitPosi);
    break;
     case PORT1:
      LPC_GPIO1->IE |= (0x1<<bitPosi);   
    break;
    case PORT2:
      LPC_GPIO2->IE |= (0x1<<bitPosi);       
    break;
    case PORT3:
      LPC_GPIO3->IE |= (0x1<<bitPosi);       
    break;
    default:
      break;
  }
  return;
}

/*****************************************************************************
** Function name:        GPIOIntDisable
**
** Descriptions:        Disable Interrupt Mask for a port pin.
**
** parameters:            port num, bit position
** Returned value:        None
**
*****************************************************************************/
void GPIOIntDisable( uint32_t portNum, uint32_t bitPosi )
{
  switch ( portNum )
  {
    case PORT0:
      LPC_GPIO0->IE &= ~(0x1<<bitPosi);
    break;
     case PORT1:
      LPC_GPIO1->IE &= ~(0x1<<bitPosi);   
    break;
    case PORT2:
      LPC_GPIO2->IE &= ~(0x1<<bitPosi);       
    break;
    case PORT3:
      LPC_GPIO3->IE &= ~(0x1<<bitPosi);       
    break;
    default:
      break;
  }
  return;
}

/*****************************************************************************
** Function name:        GPIOIntStatus
**
** Descriptions:        Get Interrupt status for a port pin.
**
** parameters:            port num, bit position
** Returned value:        None
**
*****************************************************************************/
uint32_t GPIOIntStatus( uint32_t portNum, uint32_t bitPosi )
{
  uint32_t regVal = 0;

  switch ( portNum )
  {
    case PORT0:
      if ( LPC_GPIO0->MIS & (0x1<<bitPosi) )
        regVal = 1;
    break;
     case PORT1:
      if ( LPC_GPIO1->MIS & (0x1<<bitPosi) )
        regVal = 1;   
    break;
    case PORT2:
      if ( LPC_GPIO2->MIS & (0x1<<bitPosi) )
        regVal = 1;           
    break;
    case PORT3:
      if ( LPC_GPIO3->MIS & (0x1<<bitPosi) )
        regVal = 1;           
    break;
    default:
      break;
  }
  return ( regVal );
}

/*****************************************************************************
** Function name:        GPIOIntClear
**
** Descriptions:        Clear Interrupt for a port pin.
**
** parameters:            port num, bit position
** Returned value:        None
**
*****************************************************************************/
void GPIOIntClear( uint32_t portNum, uint32_t bitPosi )
{
  switch ( portNum )
  {
    case PORT0:
      LPC_GPIO0->IC |= (0x1<<bitPosi);
    break;
     case PORT1:
      LPC_GPIO1->IC |= (0x1<<bitPosi);   
    break;
    case PORT2:
      LPC_GPIO2->IC |= (0x1<<bitPosi);       
    break;
    case PORT3:
      LPC_GPIO3->IC |= (0x1<<bitPosi);       
    break;
    default:
      break;
  }
  return;
}
-------------------------------------------------------------------------------------------------------------------------




Kako ova (eksperimentalna) pločica funkcionira:

Na slici je zelenom bojom označeno ono što se ponaša kao "čvorište" znači, da sve što tamo upiknete će biti spojeno, pripazite na to da su "gornji" i "donji" dio pločice kao odvojeni, oni su zapravo i elektročki odvojeni (zato sam nacrtala 3 zelene "gornje" crte i 3 zelene "donje" crte odvojene. Onda još imate crvene i sive crte. Crvene označavaju da je cijeli taj redak spojen (nisam cijelom dužinom povukla crtu jer je poružnilo sliku :P), također i siva crta isto to označava. Isto to se dešava i na donjoj strani pločice. NAPOMENA: "gornja" i "donja" pločica nisu povezane uopće, osim ako nekom žičicom vi to omogućite, znači crveno recimo spojite s crvenim dijelom pločice i tada se sve to nalazi na istom potencijalu, isto tako i plavo spojite s plavim dijelom.

Ako imate još kakvih pitanja, slobodno ostavite koji komentar =).

1 comment:

Anonymous said...
This comment has been removed by a blog administrator.