jgcl
(usa Ubuntu)
Enviado em 16/06/2009 - 19:10h
Olá pessoal.
Estou tendo um pouco de dificuldade para programar escutando e enviando dados da porta serial usando a programação C.
Fiz algumas tentativas de modificar o código abaixo, porém não obtive sucesso.
Alguém sabe modifica-lo para que eu receba uma string (ex: "login") e retorne outra string (ex: "abre")?
Segue o código:
(lembrando que requer a lib "ncurses" -> sudo apt-get install libncurses5-dev)
#include <stdio.h>
#include <stdlib.h>
#include <termios.h> /* Configuração da linha série */
#include <unistd.h>
#include <signal.h> /* Instalação de rotina para Ctrl-C */
#include <getopt.h> /* Tratamento da linha de comando */
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <curses.h> /* Gestão do teclado */
#include <ctype.h>
#define DEFAULT_COMM_DEVICE "/dev/ttyS0"
#define DEFAULT_BAUDRATE B1200
/* Variáveis para o processamento das opções de linha de comando */
extern char *optarg;
extern int optind, opterr, optopt;
struct termios comm_config_orig; /* configuracao original */
/* Variáveis globais que armazenam vários valores de configuração */
/* Neste ponto são inicializadas com os valores "default" */
char CommDevice[32] = DEFAULT_COMM_DEVICE; /* Porta série */
int CommPort; /* file descriptor da porta série. */
/* rotina de tratamento do control c */
void rotina_ctrl_C(int sinal) {
endwin(); /* Fecha a janela dos ncurses */
/* Repõe config original da porta série */
tcsetattr(CommPort,TCSANOW, &comm_config_orig);
exit(0);
}
/* apresentacao inicial */
void apresentacao(char *commPort) {
printw("Comunicacao serial ('%s')\n", commPort);
printw("*use control+c para finalizar\n\n");
refresh();
}
/* comunicação serial */
int InitLinhaSerie(char *LinhaSerie, struct termios *p_oldtio) {
int fd; /* Descriptor de ficheiro para a porta série */
struct termios newtio;
/*
1º passo:
Abrir a porta sérial
*
A porta é aberta para leitura e escrita (O_RDWR) e o
programa não fica o processo controlador do terminal (O_NOCTTY)
*/
fd = open(DEFAULT_COMM_DEVICE, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("erro ao abrir");
return -1;
}
/* Depois da porta aberta, guardar valores da configuração */
/* anterior e criar a nova configuracao */
tcgetattr(fd, p_oldtio); /* guarda valores antigos */
bzero(&newtio, sizeof(newtio)); /* limpa nova configuracao */
/*
Configuracao das c_flags
B19200 : Baudrate
CS8 : 8 data bits
CLOCAL : ligacao local, ignorar linhas de controle do modem
CREAD : autorizar recepcao de caracteres
sem CRTSCTS : sem controlo por hardware
*/
newtio.c_cflag = DEFAULT_BAUDRATE;
newtio.c_cflag |= (CS8 | CLOCAL | CREAD);
/*
Configuracao das c_iflags:
IGNPAR : ignorar erros de paridade;
ICRNL : transforma "carriage return" em "newline" à entrada.
*/
newtio.c_iflag = IGNBRK | IGNPAR | ICRNL;
/* Configuracao das c_oflags */
newtio.c_oflag = ONLCR;
/* Configuracao das c_lflags */
newtio.c_lflag = 0;
/* Configuracao do timeout entre caracteres recebidos */
newtio.c_cc[VTIME] = 0; /* timeout em 1/10s */
newtio.c_cc[VMIN] = 0; /* não tem numero limite de caracteres */
/* Limpar a linha série antes de activar a nova configuracao */
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
return fd;
}
/* Faz a configuração do teclado para garantir que a leitura é feita */
/* caracter a caracter sem buffering. */
void iniciaTeclado() {
initscr(); /* inicia a tela do nCurses */
keypad(stdscr,TRUE); /* Enable das teclas de fungão (F1, ...) */
scrollok(stdscr,TRUE); /* Permite fazer o "scroll" da janela principal (ecrã) */
nodelay(stdscr,TRUE); /* Não fica eternamente à espera de um caracter lido do teclado */
noecho(); /* Não faz eco dos caracteres lidos */
cbreak();
}
int main(int argc, char *argv[]) {
int cnt;
char c;
/* Inicialização da portaserie */
CommPort=InitLinhaSerie(CommDevice,&comm_config_orig);
/* Inicialização do teclado */
iniciaTeclado();
/* O programa anuncia-se */
apresentacao(CommDevice);
/* Atribuição de uma rotina para atendimento do Ctrl-C */
signal(SIGINT, rotina_ctrl_C);
/************* Ciclo principal *********************/
while(1){
/* Tenta ler da porta série */
cnt = read(CommPort,&c,1);
if(cnt==1){
/* Recebeu caracter */
addch(c);
fflush(stdout);
} else if(cnt == 0) {
/* Não há caracter recebido */
/* Vai testar teclado */
c = getch();
if(c != ERR){
/* Houve tecla carregada... */
write(CommPort,&c,1);
}
} else{
printw("Erro RS232!\n");
}
}
/************* Ciclo principal *********************/
return 0;
}