Pic recebendo dados seriais e mostrando em lcd 16x2

Pessoal, estou tentando iniciar um projeto para ligar deixar uma 'placa pronta' onde um pic, ligado a um shift register e esse a um lcd 16x2.

O pic recebe dados seriais (velocidade selecionável no hexadecimal) e escreve elas no lcd.

A ligação eu já fiz, só estou com problemas para iniciar a programação do meu pic, eu só usei o pic com shift register para ligar 'leds'. No Arduíno eu consegui escrever no lcd, mas não consegui receber  os dados seriais...

Alguém afim de entrar nessa 'dor de cabeça'? 

meu código está assim: (código feito pra acender leds, não tenho ideia de como começar a escrever no lcd).

#include "12F675.h"
#include "stdlib.h"
#include "STDIO.H"
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES NOCPD
#FUSES NOPROTECT
#FUSES NOMCLR
#FUSES NOPUT
#FUSES NOBROWNOUT
#use delay(int=4000000)
#define DATA PIN_A1
#define CLK PIN_A0
#define ENA PIN_A2
#define botao PIN_A5
int x;
void pulse_shift_clock(){
output_high(CLK);
output_low(CLK); }
void write_74HC595(int databyte){
for(int databits=0; databits<8; databits++){
if(databyte & 0b10000000){
output_high(DATA);}
else{
output_low(DATA);}
pulse_shift_clock();
databyte = 1;}}
void pulse_latch(){
output_high(ENA);
delay_ms(10);
output_low(ENA);}

void main (){
while(1){
write_74HC595(0);
pulse_latch();
delay_ms(50);
}}}

Exibições: 1432

Responder esta

Respostas a este tópico

Bom, ninguem falou nada, mas vou postar meus codigos, já fiz o LCD funcionar (sem o 74HC595, não achei bibiloteca pro 74595), só falta o o pic receber os dados seriais:

biblioteca do lcd:

/***************************************************************************/
/* Rotinas para o LCD */
/***************************************************************************/

//Este é o bloco com as rotinas necessárias para manipular o LCD

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de "Nibble" para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD.
void envia_nibble_lcd(int dado)
{
//Carrega as vias de dados (pinos) do LCD de acordo com o nibble lido
output_bit(lcd_db4, bit_test(dado,0)); //Carrega DB4 do LCD com o bit DADO<0>
output_bit(lcd_db5, bit_test(dado,1)); //Carrega DB5 do LCD com o bit DADO<1>
output_bit(lcd_db6, bit_test(dado,2)); //Carrega DB6 do LCD com o bit DADO<2>
output_bit(lcd_db7, bit_test(dado,3)); //Carrega DB7 do LCD com o bit DADO<3>

//Gera um pulso de enable
output_high(lcd_enable); // ENABLE = 1
delay_us(1); // Recomendado para estabilizar o LCD
output_low(lcd_enable); // ENABLE = 0
return; // Retorna ao ponto de chamada da função
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de Byte para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina irá enviar um dado ou um comando para o LCD conforme abaixo:
// ENDEREÇO = 0 -> a variável DADO será uma instrução
// ENDEREÇO = 1 -> a variável DADO será um caractere

void envia_byte_lcd(boolean endereco, int dado)
{
output_bit(lcd_rs,endereco); // Seta o bit RS para instrução ou caractere
delay_us(100); // Aguarda 100 us para estabilizar o pino do LCD
output_low(lcd_enable); // Desativa a linha ENABLE
envia_nibble_lcd(dado>>4); // Envia a parte ALTA do dado/comando
envia_nibble_lcd(dado & 0x0f); // Limpa a parte ALTA e envia a parte BAIXA do
// dado/comando
delay_us(40); // Aguarda 40us para estabilizar o LCD
return; // Retorna ao ponto de chamada da função
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de caractere para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Esta rotina serve apenas como uma forma mais fácil de escrever um caractere
// no display. Ela pode ser eliminada e ao invés dela usaremos diretamente a
// função envia_byte_lcd(1,"<caractere a ser mostrado no LCD>"); ou
// envia_byte_lcd(1,<código do caractere a ser mostrado no LCD>);

void escreve_lcd(char c)
// envia caractere para o display
{
envia_byte_lcd(1,c);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Função para limpar o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Como esta operação pode ser muito utilizada, transformando-a em função
// faz com que o código compilado seja menor.

void limpa_lcd()
{
envia_byte_lcd(0,0x01); // Envia instrução para limpar o LCD
delay_ms(2); // Aguarda 2ms para estabilizar o LCD
return; // Retorna ao ponto de chamada da função
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Inicializa o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void inicializa_lcd()
{
output_low(lcd_db4); // Garante que o pino DB4 estão em 0 (low)
output_low(lcd_db5); // Garante que o pino DB5 estão em 0 (low)
output_low(lcd_db6); // Garante que o pino DB6 estão em 0 (low)
output_low(lcd_db7); // Garante que o pino DB7 estão em 0 (low)
output_low(lcd_rs); // Garante que o pino RS estão em 0 (low)
output_low(lcd_enable); // Garante que o pino ENABLE estão em 0 (low)
delay_ms(15); // Aguarda 15ms para estabilizar o LCD
envia_nibble_lcd(0x03); // Envia comando para inicializar o display
delay_ms(5); // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x03); // Envia comando para inicializar o display
delay_ms(5); // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x03); // Envia comando para inicializar o display
delay_ms(5); // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x02); // CURSOR HOME - Envia comando para zerar o
//contador de caracteres e retornar à posição
// inicial (0x80).
delay_ms(1); // Aguarda 1ms para estabilizar o LCD
envia_byte_lcd(0,0x28); // FUNCTION SET - Configura o LCD para 4 bits,
// 2 linhas, fonte 5X7.
envia_byte_lcd(0,0x0c); // DISPLAY CONTROL - Display ligado, sem cursor
limpa_lcd(); // Limpa o LCD
envia_byte_lcd(0,0x06); // ENTRY MODE SET - Desloca o cursor para a direita
return; // Retorna ao ponto de chamada da função
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Define inicio da escrita *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Esta função foi adicionada e serve para se definir em que posição do 
//LCD deseja-se iniciar a escrita. Para isto basta chamar a Função 
//"caracter_Inicio()" indicando a linha e a coluna onde o cursor será 
// posicionado antes de se mandar escrever

void caracter_inicio(int linha, int coluna)//define a posicão de inicio da frase
{
int16 posicao=0;
if(linha == 1)
{
posicao=0x80; //Se setado linha 1, end incial 0x80
}
if(linha == 2)
{
posicao=0xc0; //Se setado linha 2, end incial 0xc0
}

posicao=posicao+coluna; //soma ao end inicial, o numero da coluna
posicao--; //subtrai 1 para corrigir posição

envia_byte_lcd(0,posicao);
return;
}
/***************************************************************************/
/* Final das rotinas para o LCD */
/***************************************************************************/

e o main:

#include <16F73.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT //Watch Dog Timer desabilitado
#FUSES HS //oscilador cristal
#FUSES NOPUT //Power Up Timer off
#FUSES NOPROTECT //sem proteção para leitura da eprom
//#FUSES BROWNOUT //Resetar quando detectar brownout
#use delay(clock=20000000) //Define o cristal utilizado
#define lcd_enable PIN_A1 // pino enable do LCD
#define lcd_rs PIN_A0 // pino rs (register select)do LCD
#define lcd_db4 PIN_B4 // pino de dados d4 do LCD
#define lcd_db5 PIN_B5 // pino de dados d5 do LCD
#define lcd_db6 PIN_B6 // pino de dados d6 do LCD
#define lcd_db7 PIN_B7 // pino de dados d7 do LCD
#include "lcd.h"

void main(){
while (1){
output_low(LED);
inicializa_lcd(); //Inicializa o LCD
caracter_inicio(1,1); //Define o caracter de inicio da escrita
printf(escreve_lcd,"\fMSG:%u","x"); //Escreve no LCD
}
} //fecha void main

agora só preciso achar uma biblioteca pro 74595 e mudar esse esquema pro pic certo..

qualquer opinião é bem vinda.

Se for serial assincrona usada pelo padrão RS232 considere a possibilidade de trocar por um outro PIC que tenha UART ou USART, sem isso vc vai ter dor de cabeça pra fazer via software a comunicação serial.

Então Yure, descobri hoje que o pic12f675 é fraco demais, e USART / UART via software consome muita memoria, na metade da compilação o mlab já me avisa isso.

Mudei meu código e irei ficar com o pic16fxx mesmo, com o lcd ligado diretamente no pic, vai diminuir a dor de cabeça e o código ficou a metade.

O problema agora é descobrir como tratar os dados recebidos na serial, pois até o momento, só saem números aleatórios, conforme faço o teste via serial.

#include <16F73.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT //Watch Dog Timer desabilitado
#FUSES HS //oscilador cristal
#FUSES NOPUT //Power Up Timer off
#FUSES NOPROTECT //sem proteção para leitura da eprom
//#FUSES BROWNOUT //Resetar quando detectar brownout
#use delay(clock=20000000) //Define o cristal utilizado
#use rs232(baud=9600, bits=8, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors) )
#define lcd_enable PIN_A1 // pino enable do LCD
#define lcd_rs PIN_A0 // pino rs (register select)do LCD
#define LED PIN_A3 // (0) para comandos (1) para dados
#define lcd_db4 PIN_B4 // pino de dados d4 do LCD
#define lcd_db5 PIN_B5 // pino de dados d5 do LCD
#define lcd_db6 PIN_B6 // pino de dados d6 do LCD
#define lcd_db7 PIN_B7 // pino de dados d7 do LCD
#include "lcd.h"
void piscaled(){
output_high(LED);
delay_ms(200);
output_low(LED);
delay_ms(20);
}
void main(){
int conta=0;
char data;
while (1){
output_low(LED);
inicializa_lcd(); //Inicializa o LCD
for (conta=0;conta<900;conta++){
data = getchar();
caracter_inicio(1,6); //Define o caracter de inicio da escrita
printf(escreve_lcd,"dd-wrt - powered"); //Escreve no LCD
caracter_inicio(2,1);
printf(escreve_lcd,"\f%u",data); //Escreve no LCD
piscaled();
}
conta=0;
}
} //fecha void main

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço