Configuração do Port Bit a Bit (Linguagem C)

Software e Hardware para uC PSoC

Moderadores: andre_luis, 51

Configuração do Port Bit a Bit (Linguagem C)

Mensagempor Ricardo_Franco » 28 Jul 2008 19:14

Ola Senhores
Gostaria de configurar os pinos do PSoC para serem usados bit a bit ou por Byte, para tanto pensei em utilizar uma estrutura assim:
Código: Selecionar todos
union Port1
{
   struct
   {
     unsigned char P0:1;   // Dados para - P0
     unsigned char P1:1;   // Dados para - P1
     unsigned char P2:1;   // Dados para - P2
     unsigned char P3:1;   // Dados para - P3
     unsigned char P4:1;   // Dados para - P4
     unsigned char P5:1;   // Dados para - P5
     unsigned char P6:1;   // Dados para - P6
     unsigned char P7:1;   // Dados para - P7
  } Bits;
char Byte;
};
#define PORT1 (*(union Port1 *)PRT1DR)

Dessa forma seria possível acessar o port todo:
Código: Selecionar todos
PORT1.Byte = valor;

Ou somente o bit:
Código: Selecionar todos
PORT1.Bits.P0 = valor;


No entanto este código aparentemente correto é compilado, mas não funciona, já tentei indicar diretamente o endereço do port na memória 0x004, mas também não funcionou.
Código: Selecionar todos
#define PORT1 (*(union Port1 *)0x004)

A ultima linha foi retirada diretamente do documento “C Language Compiler User Guide.pdf” (pg. 31).
Alguém tem alguma idéia ?
Ricardo Franco
____________________________________________________________________________________________
web: www.engricardofranco.kit.net
Skype: engricardofranco
Fone Skype: (19) 3119-8162
Ricardo_Franco
Byte
 
Mensagens: 305
Registrado em: 11 Out 2006 20:53
Localização: Campinas - SP

Mensagempor msamsoniuk » 30 Jul 2008 12:58

eu testei o seu codigo num PC e funciona corretamente sua logica. inclusive acho q o SDCC usa umas macros similares para criar facilidades tipo PORTA, PORTB, PORTA0, PORTB0, etc.

talvez o que possa ocorrer eh que os bits na struct tem q ser invertidos, isso eu vi portanto codigo de x86 no gcc para 68k no gcc. outra consideracao eh a indicacao volatile, que eu obrigatoriamente tenho que usar no gcc para 68k, do contrario o compilador assume que as operacoes sao em memoria e simplesmente nao as efetua na ordem correta quando usamos io mapeado em memoria.

Código: Selecionar todos
union porta_u
{
   struct
   {
     unsigned char P0:1;   // Dados para - P0
     unsigned char P1:1;   // Dados para - P1
     unsigned char P2:1;   // Dados para - P2
     unsigned char P3:1;   // Dados para - P3
     unsigned char P4:1;   // Dados para - P4
     unsigned char P5:1;   // Dados para - P5
     unsigned char P6:1;   // Dados para - P6
     unsigned char P7:1;   // Dados para - P7
  } bit;
  unsigned char byte;
};

unsigned char porta_d;

#define PORTA  ((*(volatile union porta_u *)&porta_d).byte)
#define PORTA0 ((*(volatile union porta_u *)&porta_d).bit.P0)
#define PORTA1 ((*(volatile union porta_u *)&porta_d).bit.P1)
#define PORTA2 ((*(volatile union porta_u *)&porta_d).bit.P2)
#define PORTA3 ((*(volatile union porta_u *)&porta_d).bit.P3)
#define PORTA4 ((*(volatile union porta_u *)&porta_d).bit.P4)
#define PORTA5 ((*(volatile union porta_u *)&porta_d).bit.P5)
#define PORTA6 ((*(volatile union porta_u *)&porta_d).bit.P6)
#define PORTA7 ((*(volatile union porta_u *)&porta_d).bit.P7)

main() {


        PORTA = 0;
        PORTA7 = 1;

        printf("%x\n",PORTA);
}
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor Ander_sil » 30 Jul 2008 15:50

Ola eu testei no Keil e 8051 conforme o Marcelo passou e para variavel funcionou mas quando troco pelo sfr do Port P0 não funciona, acusa erro de acesso ilegal a sfr.

at.
Anderson Chrispim da Silva
chrispimdasilva@gmail.com
Ander_sil
Byte
 
Mensagens: 368
Registrado em: 30 Out 2006 09:58
Localização: Campinas - SP

Mensagempor chrdcv » 02 Ago 2008 15:09

Só completando, o ideal da definição:

#define PORT1 (*(union Port1 *)0x004)

Seria:

#define PORT_1 (*(volatile unsigned char *)0x004)

Caso for desejável a manipulação direta do registrador do endereço especificado.

Dessa forma, a manipulação de bit a bit dos pinos referentes ao "port" poderia ser feita através de "bitwise operations":
#define BIT(x) (1<<(X))

Operações:

PORT_1 |= BIT(0); /* bit 0 em H */
PORT_1 &= ~BIT(0); /* bit 0 em L */
PORT_1 ^= BIT(0); /* bit 0 toggle */

Ainda pode-se ter:
#define SET_BIT(p, b) (p)|=BIT(b)
#define CLR_BIT(p, b) (p)&=~BIT(b)

chrdcv
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

fghgf

Mensagempor Ricardo_Franco » 10 Ago 2008 13:43

Ola Senhores
Pessoal consegui acertar a biblioteca para uso do port bit a bit.
Gostaria de agradecer à William César por sua ajuda, foi ele quem deu a letra para a solução do problema.

arquivo: uc_CY8C29xxx.h
Código: Selecionar todos
/*--------------------------------------------------------------\
|   Arquivo:    uc_CY8C29xxx.h                           |
|   Criado por:   Ricardo Franco                            |
|   Data:      10/08/2008 13:07                        |
|   Observação:                                       |
|      Agradecimentos à William César Santos Ramalho         |
\--------------------------------------------------------------*/
// -- Previne a reentrancia --------------------------------------
#ifndef __uc_CY8C29xx
   #define __uc_CY8C29xx
   
// -- Estrutura para definição do port bit a bit -----------------   
   typedef struct
   {
    unsigned char           b7          : 1;
    unsigned char           b6          : 1;
    unsigned char           b5          : 1;
    unsigned char           b4          : 1;
    unsigned char           b3          : 1;
    unsigned char           b2          : 1;
    unsigned char           b1          : 1;
    unsigned char           b0          : 1;
    } PORT_BITS;

// -- Declaração da Union ----------------------------------------
   typedef union
   {
    unsigned char           byte;
    PORT_BITS               b;
    } PORT_DEF;
   
// -- Atribuição da union aos registradores dos ports ------------
   #ifdef CY8C29466
   
      #pragma ioport Port0:   0x000
      PORT_DEF Port0;
      
      #pragma ioport Port1:   0x004
      PORT_DEF Port1;
      
      #pragma ioport Port2:   0x008
      PORT_DEF Port2;
   
   #endif CY8C29466

// -- Fim ---------------------------------------------------------
#endif __uc_CY8C29xx


O segredo é a diretiva #pragma que deve ser utilizada para apontar um endereço especifico, no caso o resgistrador dos ports.

Abaixo um pequeno exemplo de como utilizar esta biblioteca.

Arquivo: Main.c
Código: Selecionar todos
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#define CY8C29466      // Define necessario para configuração dos ports bit a bit

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include "uc_CY8C29xxx.h"   // Biblioteca com os registradores especiais

#define LED1   Port2.b.b0   // define para acessar um único bit

void main (void)
{
   while(1)
   {
   Port2.byte = 6; // acesso do Byte todo
   Port2.b.b3 = 1; // acesso apenas de um unico bit
   LED1 = 1;      // acesso de um unico bit pode #define
   }
}

A maior vantagem deste sistema é a portabilidade que o aplicativo ganha e o uso dos pinos por nomes definidos.

Obrigado a todos pela força

Ricardo Franco
Ricardo Franco
____________________________________________________________________________________________
web: www.engricardofranco.kit.net
Skype: engricardofranco
Fone Skype: (19) 3119-8162
Ricardo_Franco
Byte
 
Mensagens: 305
Registrado em: 11 Out 2006 20:53
Localização: Campinas - SP


Voltar para Cypress

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 0 visitantes

x