"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.
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.
/* **************************************************************************** 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: [email protected]. **************************************************************************** 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);
/* **************************************************************************** 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: [email protected]. **************************************************************************** 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... }
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);
}
}
}
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);
}
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?*/
}
}
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: [email protected] **************************************************************** 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; }