[Programação]

C
C++
Java

[Artigos]

Controle
Imagens
Web Programming
Microcontroladores

[Pessoal]

Biografia
Currículo
Z-Log
Músicas
English Page
Contato

GUESTBOOK:

LER ASSINAR
HOME<

Tecnologia e outros

[ CoffeeCup - Web Hosting & Web Design Software ]
   


"My software never has bugs. It just develops random features."

-Unknown

A idéia nessa página é focalizar programação em ANSI C, C para microcontroladores, C para rotinas gráficas, comunicação serial ou ethernet.


-Comunicação serial em C-

Antes de mais nada. Eu encontrei um tutorial sobre comunicação serial e comecei a alterar o código. Notei que é tão simples quanto usar a API do Java com a vantagem de ser C. Só que o código só funciona usando o compilador da Microsoft. Aqui pode ser encontrada a apostila do Professor Constantino. Há alguns trechos que precisam ser corrigidos no código original. A idéia é usar as funções para inicializar a porta serial e depois usar a função de leitura para fazer polling.


serial.h

/*
****************************************************************************
SOFTWARE PARA CONFIGURAÇAO DA PORTA SERIAL
COMUNICAÇÃO SERIAL-UFMG 
AUTOR: PROFESSOR DR.CONSTANTINO SEIXAS FILHO,  (UFMG)
ALTERAÇÕES: DANIEL V. GOMES
****************************************************************************
[DISCLAIMER]:
Apesar de compreender todo esse código e ser capaz de ensiná-lo e usá-lo em
aplicações reais, não me autorgo a autoria de seu cerne. Apenas o modifiquei.
Quaisquer dúvidas: zlogdan@gmail.com.
****************************************************************************
comentários Daniel V. Gomes estão entre tags <da></da>
ou em LETRAS MAIUSCULAS
*/

#include <windows.h>
#include <stdio.h>

/*<da>VARIAVEIS GLOBAIS,</da>*/
DCB dcb;//<da>estrutura para configurar parametros de com.</da>
HANDLE hCom;//<da>estrutura para configurar com.</da>
BOOL fSuccess;// <da>FALSE = Não pode estabelecer com</da>	.
			  // <da>TRUE = Pode estabelecer com.</da>	
DWORD  dwRead;//<da>N.o de bytes lidos </da>
BOOL fWaitingOnRead = FALSE;//<da>FALSE = leitura pendente</da>
							//<da>TRUE = leitura habilitada</da>
char *lpBuf;//<da></da>


OVERLAPPED osReader = {0};//<da></da>
DWORD dwRes;//<da></da>


/*TIMEOUT*/
#define READ_TIMEOUT 500

/*ROTINA PARA INICIALIZAR A PORTA*/
BOOL InicializarPorta( char * );

/*ROTINA DE LEITURA*/
BOOL ReadStuff();

/*ROTINA DE ESCRITA*/
void WriteStuff();

void TrateLeituraComSucesso(char * lpBuf, DWORD dwRead);

serial.c

/*
****************************************************************************
SOFTWARE PARA CONFIGURAÇAO DA PORTA SERIAL
COMUNICAÇÃO SERIAL-UFMG 
AUTOR: PROFESSOR DR.CONSTANTINO SEIXAS FILHO,  (UFMG)
ALTERAÇÕES: DANIEL V. GOMES
****************************************************************************
[DISCLAIMER]:
Apesar de compreender todo esse código e ser capaz de ensiná-lo e usá-lo em
aplicações reais, não me autorgo a autoria de seu cerne. Apenas o modifiquei.
Quaisquer dúvidas: zlogdan@gmail.com.
****************************************************************************
comentários Daniel V. Gomes estão entre tags <da></da>
ou em LETRAS MAIUSCULAS
*/

#include "serial.h"

/*IMPLEMENTACÕES*/

BOOL InicializarPorta( char * COMPORTA ){

	   char *pcCommPort = COMPORTA   ;
       
       hCom = CreateFile(
              pcCommPort,
              GENERIC_READ|GENERIC_WRITE,
              0,
              NULL,
              OPEN_EXISTING,
              0,
              NULL);
       
       if ( hCom == INVALID_HANDLE_VALUE ) {           
           return FALSE;
           /*erro*/
       };
       
       fSuccess = GetCommState( hCom,&dcb );
       
       if (!fSuccess ) {
           return FALSE ;
           /*Erro*/
       };
       
       dcb.BaudRate = CBR_9600;
       dcb.ByteSize = 8;
       dcb.Parity = NOPARITY;
       dcb.StopBits = ONESTOPBIT;
       
       fSuccess = SetCommState( hCom, &dcb );
       
       if (!fSuccess ) {
           return FALSE;   
          /*erro*/            
       }; 
	   
	   return TRUE;

}

BOOL ReadStuff(){

	osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	/*
	<da>
	typedef struct _OVERLAPPED {
		DWORD Internal;
		DWORD InternalHigh;
		DWORD Offset;
		DWORD OffsetHigh;
		HANDLE hEvent;<====
	} OVERLAPPED;</da>
	*/

	if ( osReader.hEvent == NULL ) {
		/*erro ao criar evento de leitura*/
		return FALSE;
	};


	/*Nenhuma leitura pendente*/
	/*	<da>
		ReadFile(...) inicializa a estrutura lPBuf um char 
		de tamanho 32 bytes</da>
	*/
	if (!fWaitingOnRead ) 
	{
		/*leitura*/
		if (!ReadFile( hCom, lpBuf, 32, &dwRead, &osReader) ) // lpOverlapped
		{
			if (GetLastError()!= ERROR_IO_PENDING){ // Leitura não foi enfileirada
			// Erro de comunicação: relate-o
			}
			else {
			fWaitingOnRead = TRUE; // ativa flag leitura pendente			
			}
		}
	} else {
		TrateLeituraComSucesso(lpBuf, dwRead);
		/*	<da>
			Aqui os dados lidos lpBuf podem ser processados
			lpBuf é um char</da>
		*/
	};

	/*
		<da>
		Supomos nesse caso que exista uma leitura pendente e que deve
		acontecer antes da leitura atual. O código espera 500 ms
		para em seguida verificar o status num laco switch
		</da>
	*/
	if (fWaitingOnRead) { // Existe uma leitura pendente: espere-a
		dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);
		/*
				<da>aguarda com timeout = 500 ms</da>

		*/
		/*
			OS COMENTARIOS DO PROFESSOR EXPLICAM BEM O QUE
			ACONTECERÁ.
		*/
		switch (dwRes)
		{
			// Leitura completada
			case WAIT_OBJECT_0:
				
				if (!GetOverlappedResult(hCom, &osReader, &dwRead, FALSE) ){
				// Erro de comunicação: relate-o
				} else {
				// Leitura completada com sucesso
				TrateLeituraComSucesso(lpBuf, dwRead);
				}

				// Reseta flag para que outra operação possa ser iniciada
				fWaitingOnRead = FALSE;
				break;

			case WAIT_TIMEOUT:
				// Operação ainda não foi completada. Pode-se reemitir o comando e
				// continuar esperando ou cancelá-lo.
				// Este é um bom momento para realizar alguma outra atividade.
				break;
	
			default:
				// Erro em WaitForSingleObject; aborte.
				// Isto indica algum problema com o handle do evento na estrutura
				// OVERLAPPED.
				break;
		}
	}
	
	CloseHandle(osReader.hEvent);

	return TRUE;


}

void TrateLeituraComSucesso( char * lpBuf, DWORD dwRead ){
		 //com uma string lpBuf voce pode tratar os dados lidos		 
}

void WriteStuff(){
		 //Ainda precisa ser implementada...
}

-Ponteiros-

Estou meio com preguiça de escrever, mas o programa abaixo exemplifica e mostra como usar ponteiros com tipos de dados char, int e como passar ponteiros pra funções, alocar memória dinâmicamente pra um ponteiro e depois como usar esse ponteiro como um Array simples. Note que o operador & não é necessário quando passamos um char ou um ptr que representa um array para uma função.


#include <stdio.h>
#include <stdlib.h>

/*Receives a char pointer as parameter*/
void StuffWChars( char * );
/*Replace two strings*/
char *Reprace( char * , char * );
/*Replace two ints*/
void Swapnums( int * , int * );
/*Allocates memory for n int memory positions*/
int * myAloc ( int );
void PPtr2F( int * , int );

#define N = 10

int main(void)
{
   
  /*Variables declaration*/   
  char ovo[] = "Ovo";
  char *povo = "ovo";
  int a = 2;
  int b = 3;
  int n ;
  int i;
  int * myinptr;

  /*End of Variables declaration*/ 
  
  printf("[First we create two chars using two different methods...]\n");
  printf("The string created as a char pointer: \n");
  printf(">_  %s\n",povo);
  printf("The string created as an array of chars: \n");
  printf(">_  %s\n",ovo);
  StuffWChars(povo);
  printf("\n\n");

  printf("[Now let's us test a swap function...]\n");
  char *Jaca = "Jaca";
  char *Manga = "Manga";
  char *tempo;
  printf("Before the change Jaca points to : %s\n",Jaca);
  tempo = Reprace( Jaca, Manga );
  printf("After the change Jaca now points to : %s\n\n\n",tempo);
  
  
  printf("[Now let's us investigate numbers rather than chars...]\n");
  Swapnums( &a, &b );
  printf("\n\n");
  
  printf("[Now let's us investigate passing pointers to functions...]\n");  
  n = 10;  
  myinptr = myAloc( n );  
  for ( i = 0 ; i < 10 ; i++ ) 
  {
      myinptr[i] = i - 1 ;    
  };      
  
  PPtr2F( myinptr , n );
  
  system("PAUSE");	
  return 0;
}

void StuffWChars( char * s ) 
{
   printf("the string passed to the function: \n");
   printf(">_  %s\n",s);   
}

char *Reprace( char * s1 , char * s2 )
{
    char *temp;
    temp = s1;
    s1 = s2;
    s2 = temp;
    printf("Jaca after reprace: \%s\n", s1);
    printf("Manga after reprace: \%s\n", s2);
    return s1;
}

void Swapnums( int * a , int * b )
{
    int temp;
    printf("The value of a before swapping was %d\n", *a );
    printf("The value of b before swapping was %d\n", *b );
    temp = *a;
    *a = *b;
    *b = temp;
    printf("The value of a after swapping was %d\n", *a );
    printf("The value of b after swapping was %d\n", *b );
       
}

int * myAloc ( int a ) 
{    
    int * ptr;
    /* Does not need the cast in the ANSI C 99*/
    ptr = ( int *)calloc( a , sizeof(int));
    if (!ptr) {
        printf("Erro.");
        return 0; 
    } else {        
         return ptr;/*Note that we don't actually need to use the *
                operator. Horrors and terrors huh?*/  
    }  
}

void PPtr2F( int * ptr, int n )
{
    int i ;    
    i = 0;        
    for ( i = 0 ; i < n ; i++ )
    {
        if ( (ptr[i]==0) | (ptr[i]<0) ) 
        {
            printf("%d\n",ptr[i]+20);
        } else 
        {
            printf("%d\n",ptr[i]-3);
        }    
    }    
}
                   


                                                     

-Calculando valores através de alocação dinâmica e escrevendo em arquivo

A idéia é gerar vetores do tipo float dinâmicamente e passar esses valores para um arquivo .dat.


#include <stdio.h>
#include <stdlib.h>

/*THIS PROGRAM IS NOT COPYRIGHTED, I JUST GO AND
TYPE, IF YOU USE IT, I HOPE IT HELPS YOU.*/


#include <stdio.h>
#include <stdlib.h>
#include <math.h>


float *ptrX;
float *ptrY;
float *ptrM;


/*
  Computes the modulus of a complex number
*/
float ObterModulo( float , float );


/*
  Allocates memoroy for an array of floats with size a
*/
float * myAloc ( int );

void InitPontos( int  );

void LiberaMemoria(void);

void WriteData2File( float *, float *, float *, int );

int main( void ) {

	InitPontos( 20 );
    WriteData2File(ptrX,ptrY,ptrM,20);
	LiberaMemoria();
	system("PAUSE");
	return 0;
}

/*
  Implementations:
*/


void WriteData2File( float * ptrx, float *ptry, float *ptrM, int N ){
     FILE *mfile;
     int i;
     float temp1,temp2,temp3;
     if ( ( mfile = fopen("Dados.dat","w") ) == NULL) {
       printf("Erro");
     } else {
       for ( i = 0 ; i < N ; i++ ){
           temp1 = ptrx[i];temp2=ptry[i];temp3=ptrM[i];    
	       printf( "%f,%f,%f\n", temp1,temp2,temp3 );
           fprintf( mfile , "%f %f %f\n", temp1,temp2,temp3);
       }
     fclose(mfile);
     }
}

float ObterModulo( float x , float y ){
	return sqrt ( pow( x , 2 ) + pow ( y , 2 ) );
}

float * myAloc ( int a ) {
      float * ptr;
      ptr = ( float *)calloc( a , sizeof(float));
      if (!ptr) {
        printf("Erro.");
        return 0;
      } else {
        return ptr;
      }
}

void InitPontos( int N ){
     int i;
     ptrX = myAloc( N );
     ptrY = myAloc( N );
     ptrM = myAloc( N );
     for ( i = 0 ; i < N ; i++ ) {
         ptrX[i] = (float)(2.2*i + i);
         ptrY[i] = (float)(2.3*i);
         ptrM[i] = ObterModulo( ptrX[i] , ptrY[i] );
     }
}

void LiberaMemoria(void){
    free (ptrX);
    free (ptrY);
    free (ptrM);
}


-Alocando memória dinamicamente-

Como alocar memória dinamicamente em C usando calloc().


/*
This program examplifies the use of calloc to allocate
memory dinamically to a int array. Let's us let it clear
this is not C++ just plain and good ol' C!
*/
#include <stdio.h>
#include <stdlib.h>

int * myAloc ( int );/*Declare the prototype to the function
                       it returns a pointer to an int 
                       */
                     
int main( void ) {
    int i;
    int *myptr;/*this is actually our dynamic structure*/
    int a = 0;
    
    /*Say we are only now aware that we know the
    size of the sctruture, say the user typed the
    size of a data collection...*/
              
    printf("Type the dimension of the array to be allocated: ");
    scanf("%d",&a);
    printf("\n");         
    
    myptr = myAloc( a );
    
    /*Note that we don't use the * operator here 
    which is not required. But we allocated memory*/
                        
    printf("Allocated memory for %d",a);
    printf(" numbers\n");                        
    for ( i = 0 ; i < a ; i++ ){
        myptr[i] = i;
        /*Now myptr is an array*/ 
    }
    
    free ( myptr );/*Now that we aren't using memory it is always
                    best to release it for all good..*/
    
    system("Pause");
    
    return 0;
    
    

}
/*Now we must implement myAloc to dynammically allocate
memory for an array with size a */
int * myAloc ( int a ) {    
    int * ptr;
    ptr = ( int *)calloc( a , sizeof(int));
    if (!ptr) {
        printf("Erro.");
        return 0; 
    } else {        
         return ptr;/*Note that we don't actually need to use the *
                operator. Horrors and terrors huh?*/  
    }  
}

-Rotinas gráficas-

Eu estava pensando em bibliotecas gráficas e do nível de complexidade envolvido. E comecei a imaginar uma função hipotética que escreve um pixel na tela com uma cor determinada e partir disso estou escrevendo uma biblioteca hipotética em C puro. Sem trocadilho, por pura diversão.

/*
****************************************************************
Theoretical C Program to create a theoretical C graphic library
****************************************************************
author: Daniel Vasconcelos Gomes
email: zlogdan@gmail.com
****************************************************************

Comments: 
****************************************************************
It is fun to do, isn't it? It is getting less theoretical every
day as I progress towards a more real-world solution.
****************************************************************

*/

#include <stdio.h>
#include <conio.h>

struct point {
 int x;
 int y;
};

/*I couldn't avoid two typedefs here ;-)*/
typedef struct point point;
typedef unsigned char uchar;


void DrawALine( uchar Col,
                point *po ,
                point *pf);
                
void DrawACircle( uchar Col ,
                  point *p,  
                  int * R );
                  
void DrawARectangle( uchar Col,
                     point *po ,
                     point *pf);
                     
void DrawAPoligon( uchar Col,
                   point *po,
                   point *pf );

int ReturnScreenLength();
int ReturnScreenWidth();
int checksForValidPoints( point *po,
                          point *pf );

/*Main Function*/
int main() {  
  return 0;
}



/*
This functions checks if the user provided a valid point, i.e. ,
if it is located within the current screen.
*/
int checksForValidPoints( point *po,
                          point *pf )
{
    if ( pf->x >= ReturnScreenWidth() & pf->y >= ReturnScreenLength() ){
        if ( po->y >= 0 & po->x >= 0 ) {
                return 1;
        }
    }
    else {
        return 0 ;
    }         
}
/*
This function creates a line by connection two points
*/
void DrawALine( uchar Col,
                point *po ,
                point *pf )
{
    int i = 0;
    int j = 0;
        
    if ( checksForValidPoints( po, pf ) == 1 ){
        /* Implementation, two valid points always connect a
        line. */
        for ( i = po->x ; i < pf->x ; i++ ) {
                for ( j = po->y ; j < pf->y ; j++ ) {
                   /*here goes the code to write pixels*/
                }
        }        
        /* End of main inplementation */
    } else {
        printf("Can't do it man!");
    }
}

/*
This function creates a circle by connecting points around a central
point with ratio R
*/
void DrawACircle( uchar Col,
                  point *p,  
                  int * R )
{
    if ( checksForValidPoints( p , p ) == 1 ){
        /*
        Here must go the code to draw the circle
        around point p with ratio R
        */
    } else {
        printf("Can't do it man!");
    }
}

/*
This function creates a square by connecting two points. It will check if
the points represent a valid square
*/
void DrawARectangle( uchar Col,
                     point *po ,
                     point *pf )
{
    if ( checksForValidPoints( po , pf ) == 1 ){
        /*
        Here must go the code to draw the rectangle
        on point po and p1 .
        */
    } else {
        printf("Can't do it man!");
    }
}

/*
This function creates a square by connecting two points. It will not heck if
the points represent a valid square as it will simply connect everything.
*/
void DrawAPoligon( uchar Col,
                   point *po,
                   point *pf )
{

}

/*
It returns the length of the current screen. 
I don't know how to get the Screen length.
*/
int ReturnScreenLength()
{
    return 1024;
}

/*
It returns the Width of the current screen. 
I don't know how to get the Width length
*/
int ReturnScreenWidth()
{
    return 728;
}

1