Funções e rotinas com mikroc

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Funções e rotinas com mikroc

Mensagempor EJO » 16 Abr 2014 23:22

Estou pretendendo fazer o controle de velocidade de uma ventoinha através da leitura de um sensor de temperatura (LM35). Alem do controle pretendo acionar alguns ledes conforme o valor da temperatura e também mostrar em um display o valor da temperatura e do duty cicle - PWM. Achei na internet um programa destes que pretendo adaptar e fazer o meu, porém fazendo alguns testes utilizando o mikroc e proteus ainda não deu certo. Embora o programa compile sem algum erro quando simulo no proteus não funciona nada. O programa é mais ou menos assim:

Código: Selecionar todos
void pre_main();
void test_led_fan();
void read_lm35();
void led_control();
void pwm();

// Conexões LCD 2x16
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Final Conexões LCD 2x16

//Declaração de variáveis globais
unsigned int temp;

void main()
{
//função iniciação
pre_main();
//função teste led e fan
test_led_fan();

while(1)
{
//leitura LM35
read_lm35();
//controla led's perante temp
led_control();
//Velocidade fan
pwm();
}
}

void pre_main()
{
//Declaração de info das portas
//ADCON0 = 0x81;
//ADCON1 = 0xCE;
adcon1 = 0b00000100;
trisa = 0XFF; // portA entrada  (trisa = 1)
trisb = 0; // portB saída  (trisb = 0x00)
trisc = 0; // portC saída
trisd = 0; // portD saída
PORTD = 0; // portC nível lógico 0
//Iniciar PWM
PWM1_Init(1500);
//PWM Start
pwm1_start();
PWM1_set_Duty(0);
//Iniciar adc
adc_init();
//Iniciar Lcd
Lcd_Init();
//Iniciar Uart1
UART1_Init(9600);
Lcd_Cmd(_Lcd_CLEAR);
Lcd_Cmd(_Lcd_CURSOR_OFF);
}
void test_led_fan()
{
int j=0;
Lcd_Out(1, 1, "Aguarde: Teste");
Lcd_Out(2, 2, "Led's e Fan");
UART1_Write_text("Aguarde: TESTE\r");
UART1_Write_text("Led's e Fan\r");
do{
portd.f0=1; //verde
portd.f1=1; //amarelo
portd.f2=1; //vermelho
delay_ms(200);
portd.f0=0;
portd.f1=0;
portd.f2=0;
delay_ms(200);
j++;
pwm1_set_duty(255);
delay_ms(200);
pwm1_set_duty(0);
}
while(j!=2);
Lcd_Cmd(_Lcd_CLEAR);
Lcd_Out(1, 1, "Aguarde");
Lcd_Out(2, 2, "Led's e Fan OK");
UART1_Write_text("Led's e Fan OK\r");
delay_ms(200);
Lcd_Cmd(_Lcd_CLEAR);
}
void read_lm35()
{
char txt[15];
const unsigned short VREF = 5;

unsigned int adc_rd = 0;
adc_rd = ADC_Get_Sample(0);
temp = (adc_rd * VREF)/(1000*240);
//temp = ((unsigned long)adc_rd * VREF * 100)/1024;
floatToStr(temp, txt);
txt[4] =0;
//
UART1_Write_text(txt);
UART1_Write_text("\r");
Lcd_Out(1, 1, "Temp || Potencia");
Lcd_Chr(2, 5, 223);
Lcd_Chr(2,6,'C');
Lcd_Out(2, 1, txt);
delay_ms(10);
}
void led_control()
{
//indicação dos led's perante temperatura
if (temp <50)
{
portd.f0=1;
portd.f1=0;
}
else if (temp >51 && temp <69)
{
portd.f0=1;
portd.f1=1;
portd.f2=0;
}
else if (temp >70)
{
portd.f0=1;
portd.f1=1;
portd.f2=1;
}
}
void pwm()
{
int i=0;
if(temp > 70)
i=255;
else
{
i=temp*3;
}
PWM1_set_Duty(i);
}


LM35_PWM_FAN.PDF
Você não está autorizado a ver ou baixar esse anexo.
EJO
Bit
 
Mensagens: 7
Registrado em: 11 Abr 2014 10:28

Re: Funções e rotinas com mikroc

Mensagempor ze2 » 17 Abr 2014 03:27

não sei qual mc mas você pode ter esquecido de ligar o reset no vcc no proteus. uma pergunta tradicional seria: você já fez um pisca led com sucesso? uma nem tanto: o led era verde? este é um erro comum dos iniciantes. quanto ao fonte, até que tentei, mas a esta hora da madrugada é phoda né...
abç
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Funções e rotinas com mikroc

Mensagempor andre_luis » 17 Abr 2014 05:30

Não consegui localizar no código nenhuma referencia á configuração do LCD.
Apesar do padrão default no LCD ser por interface em 4 bits, tem certeza que está assim no Proteus ?
Pergunto porque no código, os 8 bits estão sendo declarados no inicio do programa.

Outra coisa, experimenta ajustar no Proteus o contraste do LCD pelo trimpot, pois até isso ele simula o comportamento do LCD.



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Funções e rotinas com mikroc

Mensagempor ze2 » 17 Abr 2014 07:35

sorry. em casa uso linux e não apareceu o esquema direto no post.. considere apenas a dica do andré.
pra compensar meu erro vou dar uma dica pra led_control() minimalista pra uso futuro prum bargraph meio doidão 8 leds pra monitorar temperatura. Pode servir pr'algum pobre navegante que só tenha leds a disposição (o qual me identifico com ele).
cpp code
void led_control()
{
unsigned char temp;
temp=adc_read(0); //8 bits
PORTD=1<<(temp>>8);
}

digitei online. qualquer dia eu testo pra ver se está certo.
De novo... nunca use led verde.
abç
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Funções e rotinas com mikroc

Mensagempor EJO » 17 Abr 2014 09:12

Já fiz LEds piscar e funcionou corretamente. A configuração utilizada para o LCD também já utilizei em outros circuitos e códigos e funcionou perfeitamente. O arquivo anexo .pdf é o esquema que estou utilizando no proteus (baixe o arquivo que ele está completo). O Mikroc eu não utilizei/trabalhei muito mas o proteus já fiz e simulei muitos circuitos de trabalhos da faculdade. Programas menores com mikroc estão funcionado, somente este em que crio várias rotinas e controle que não quer funcionar. Estou meio sem tempo para ficar mexendo e então resolvi buscar ajuda aqui no fórum. Valeu gente....
EJO
Bit
 
Mensagens: 7
Registrado em: 11 Abr 2014 10:28

Re: Funções e rotinas com mikroc

Mensagempor ze2 » 17 Abr 2014 09:38

EJO escreveu:Estou meio sem tempo para ficar mexendo e então resolvi buscar ajuda aqui no fórum. Valeu gente....

(antecipadamente peço perdão por expor meu ponto de vista)
isso não vai te ajudar (pelo menos com relação ao problema) mas expressão como esta não ajuda a motivar ajudantes (pelo menos a este que vos digita). De fato pode até surtir efeito contrário
Pra não deixar o post nulo, uma dica:
ao invés de postar o programa "mais ou menos assim", poste como exatamente é pois o andré corretamente achou falta de rotinas lcd. Quiçá alguma boa alma motivada te orienta direitinho
... boa sorte
ze2
Byte
 
Mensagens: 193
Registrado em: 09 Fev 2009 13:37

Re: Funções e rotinas com mikroc

Mensagempor EJO » 17 Abr 2014 10:17

Olha ze posso não ter sido feliz no que escrevi, (peço desculpas). Na verdade com a correria de trabalho e faculdade não estou podendo dedicar ao problema citado e como já encontrei muita ajuda aqui no fórum para outras coisas resolvi me cadastrar e buscar ajuda para este problema. Só quis também responder sobre o uso de programação e do proteus, sou um "iniciante" mas já usei bastante. Espero mesmo conseguir a solução com ajuda aqui do fórum. Vou procurar testar todas as propostas, serão muito bem vindas. De antemão agradeço todos que puder me ajudar. Com relação ao código eu coloquei mais ou menos assim pois tenho a intenção de alterar algumas coisas , porém este é o que estou testando no proteus e não está funcionado, mesmo compilando sem nenhum problema (uso o mikroc 5.61 e o proteus 7). Valeu gente...
EJO
Bit
 
Mensagens: 7
Registrado em: 11 Abr 2014 10:28

Re: Funções e rotinas com mikroc

Mensagempor andre_luis » 17 Abr 2014 20:23

Olá ELO,


Olhando agora com mais calma, percebi que concluí incorretamente que o código estaria baseado em acesso de 8bits, mas o que voce fez está certo mesmo, é de 4bits, te peço desculpa pelo engano. As pinagens do hardware, aproveitei e observei que também estão coerentes, não parece ter nenhum problema no circuito.

O Display LM016L que voce utilizou, possui como controlador o HD44780, que de fato é o mesmo utilizado pela biblioteca Lcd_Init() do compilador MicroC, conforme está no seu programa, e assim eliminamos também essa possibildade de problema.

Pra tentar eliminar mais uma possibilidade por partes, deixa de lado temporariamente o seu programa original, e tenta compilar esse aqui abaixo, que foi extraído diretamente do site da MikroC, e depois vamos encaixando as demais funções aos poucos, já que são simples, já que o LCD é a parte mais chata:

cpp code
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

char txt1[] = "mikroElektronika";
char txt2[] = "EasyPIC6";
char txt3[] = "Lcd4bit";
char txt4[] = "example";

char i; // Loop variable

void Move_Delay() { // Function used for text moving
Delay_ms(500); // You can change the moving speed here
}

void main(){
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;

Lcd_Init(); // Initialize LCD

Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,6,txt3); // Write text in first row

Lcd_Out(2,6,txt4); // Write text in second row
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Clear display

Lcd_Out(1,1,txt1); // Write text in first row
Lcd_Out(2,5,txt2); // Write text in second row

Delay_ms(2000);

// Moving text
for(i=0; i<4; i++) { // Move text to the right 4 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}

while(1) { // Endless loop
for(i=0; i<8; i++) { // Move text to the left 7 times
Lcd_Cmd(_LCD_SHIFT_LEFT);
Move_Delay();
}

for(i=0; i<8; i++) { // Move text to the right 7 times
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
}
}


Se nem esse código aí acima funcionar, aí meu palpite á que os FUSES do microcontrolador devem estar mal configurados no PROTEUS, e teria de rever se por exemplo o Oscilador está á cristal e na faixa correta.

No mais, reforço a dica anterior: Por incrível que pareça, o ajuste no contraste do LCD pelo trimpot, mesmo no PROTEUS, faz os caracteres aparecerem saturados como quadrados pretos, ou até mesmo desaparecer, e por isso eu se fosse voce tambem testaria essa possibilidade, ajustando valores.



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Funções e rotinas com mikroc

Mensagempor Siltech » 11 Jun 2014 12:23

EJO escreveu:Embora o programa compile sem algum erro quando simulo no proteus não funciona nada.


Eu fiz uma simulação parcial no Proteus e a parte do LCD esta funcionando normalmente.
Você não está autorizado a ver ou baixar esse anexo.
Siltech
 
Mensagens: 3
Registrado em: 11 Jun 2014 11:19
Localização: Rio de Janeiro

Re: Funções e rotinas com mikroc

Mensagempor tcpipchip » 11 Jun 2014 14:11

Verifique se as portas estao configuradas como todas digitais.
------------------------------------------
http://www.youtube.com/tcpipchip
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Re: Funções e rotinas com mikroc

Mensagempor Siltech » 11 Jun 2014 14:57

tcpipchip escreveu:Verifique se as portas estao configuradas como todas digitais.


Ja estão configuradas!

cpp code
//Declaração de info das portas
//ADCON0 = 0x81;
//ADCON1 = 0xCE;
adcon1 = 0b00000100;
trisa = 0XFF; // portA entrada (trisa = 1)
trisb = 0; // portB saída (trisb = 0x00)
trisc = 0; // portC saída
trisd = 0; // portD saída
PORTD = 0; // portC nível lógico 0


O código ta funcionando no mikroc , basta entrar com um novo projeto, selecionar o pic e o clock e colar o código.
Eu ainda não testei a outra parte do código, mais a parte de LCD ta rodando.
Siltech
 
Mensagens: 3
Registrado em: 11 Jun 2014 11:19
Localização: Rio de Janeiro

Re: Funções e rotinas com mikroc

Mensagempor EJO » 03 Set 2014 13:34

1) Senhores; grato pela ajuda. Fiz por partes conforme orientações aqui do fórum e deu certo. Quando juntava tudo novamente dava errado. Resolvi desinstalar o mikroc e instalar novamente e assim não ocorreu mais o problema. Está rodando direitinho na simulação. Estou esperando uns materiais que comprei no ebay para montar na prática.
2) O código postado anteriormente funciona corretamente, porém resolvi acrescentar um controle manual para o PWM que não quer funcionar de maneira alguma. O controle automático é feito pela leitura do LM35 e no manual deveria incrementar ou decrementar o valor que é gravado na eeprom de acordo com um botão externo. Segue a parte do código:

cpp code
void pre_main();
void read_lm35();
void pwm();
//void pwm_A();
//void pwm_M();

//*****************************************************************************

// Conexões LCD 2x16
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Final Conexões LCD 2x16

//Declaração de variáveis globais
unsigned int temp;
//unsigned long i;
unsigned short i = 0;
//*****************************************************************************
void main()
{
pre_main (); //função iniciação

while(1) //loop infinito

{
read_lm35(); //leitura LM35
pwm(); //Controle Velocidade fan
/*if (portc.f7==1)
//if (RC7_bit)
{
pwm_M();
}
else
{
pwm_A();
} */


}
}

//*****************************************************************************

void pre_main()
{
//Declaração de info das portas
//ADCON0 = 0x81;
//ADCON1 = 0xCE;
adcon1 = 0b00000100;
trisa = 0XFF; // portA entrada (trisa = 1)
trisb = 0; // portB saída (trisb = 0x00)
trisc = 0b10000000; // portC: rc7 entrada e demais saídas
trisd = 0b11000000;; // portD saída
trise = 0b00000011;
PORTD = 0; // portD nível lógico 0
//Iniciar PWM
PWM1_Init(1500); //1,5 KHz
pwm1_start(); //PWM Start
PWM1_set_Duty(0);//duty cycle = 0
adc_init(); //Iniciar adc
Lcd_Init();//Iniciar Lcd
Lcd_Cmd(_Lcd_CLEAR); //limpa lcd
Lcd_Cmd(_Lcd_CURSOR_OFF); //desliga cursor


}

//*****************************************************************************
void read_lm35()
{
char txt[15];
const unsigned short VREF = 5;
unsigned int adc_rd = 0;
adc_rd = Adc_Read(0); //lê canal 0 - RA0
delay_us(32);
temp = adc_rd*(0.488759);//(1000*5)/1023= 0.4887585533
//Saída do LM35 é 10mV por grau ºC - *1000 para converter para volts
//* 5 Vreferência - / resolução
floatToStr(temp, txt); //com intToStr não funciona
txt[4] =0;

Lcd_Out(1,1,"Temp:");
Lcd_Chr(1,12,223);
Lcd_Chr(1,13,'C');
Lcd_Out(1,7,txt);
delay_ms(10);
}

//*****************************************************************************

void pwm()
{
char txi[3];
char tx[3];
int e=0; // i=0,
int duty=0;

if (portc.f7==1)//modo manual
{
Lcd_Out(1, 16, "M");

do {
i = EEPROM_Read(0x00);//lê eeprom uma vez
e++ ;
} while(e!=1);

EEPROM_Write(0x10,i);
//PWM1_set_Duty(i);
//while (1){
if (!RE0_bit) // if button on RE0 pressed
{
Delay_ms(40);
i++; // incrementa duty cycle
PWM1_Set_Duty(i);
}

if (!RE1_bit)
{
Delay_ms(40);
i--;// decrementa duty cycle
PWM1_Set_Duty(i);
}

//PWM1_set_Duty(i);
//Delay_ms(10);//}

}
else
{
Lcd_Out(1, 16, "A");
if (temp < 30)
{
i=0;
//duty=0;
}
else if(temp > 70)
{
i=255;
}
else if (temp >= 30 && temp <= 70)
{
i=temp*3;
}
PWM1_set_Duty(i);

EEPROM_Write(0x00,i);
Delay_ms(20);
}

duty=i*(0.39216); //duty cicle(0 a 255)*0.39216 (0 a 100)

floatToStr (duty, tx); //transforma em texto (string)
tx[3]=0;
Lcd_Out(2, 1, "DC:"); //Duty Cycle=DC
Lcd_Chr(2, 7, 37);
Lcd_Out(2, 4, tx);
//IntToStr (duty, tx);
delay_ms(10);
floatToStr (i, txi);
txi[3]=0;
Lcd_Out(2, 9, "i:");
Lcd_Out(2, 12, txi);
delay_ms(10);
}

//*****************************************************************************
EJO
Bit
 
Mensagens: 7
Registrado em: 11 Abr 2014 10:28

Re: Funções e rotinas com mikroc

Mensagempor andre_luis » 03 Set 2014 21:13

Não encontrei o corpo das funções pwm_A e pwm_M.
Aproveitando, não entendi exatamente o que deve acontecer em que sequencia. descreve exatamente o funcionamento esperado, tipo: Aperta botão, grava na EEprom, lê A/D, etc...
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Funções e rotinas com mikroc

Mensagempor EJO » 04 Set 2014 08:28

Como disse andré já tentei de várias formas e não consigo incrementar/decrementar o valor do pwm. As funções pwm_a/pwm-m também foram uma tentativa que não deu certo. PWM_M era chamada quando tinha RC7 acionado, se não, funcionava a PWM_A. No código postado isso é feito dentro da função PWM. A gravação na eeprom é feita quando roda em automático e foi feito só para teste, devo usar uma variável global e assim usar tanto quando do controle em manual quanto automático (li alguma coisa que a eeprom tem um limite de gravação). Minha intenção (ainda não sei como fazer isto) é que a gravação na eeprom só aconteça quando o pic for desligado ou aconteça um pic de tensão (modo LVD - não sei se o pic 16f877a tem isso). Em manual quando aciono o pino RE0 o valor do PWM é incrementado, quando aciono o pino RE1 é decrementado.
EJO
Bit
 
Mensagens: 7
Registrado em: 11 Abr 2014 10:28

Re: Funções e rotinas com mikroc

Mensagempor andre_luis » 04 Set 2014 21:22

O problema é que não sabemos exatamente o que não tá funcionando, se é a parte de leitura, o incremento do PWM, gravação na EEprom, etc...
Como sugestão, usa o próprio LCD pra jogar temporariamente nele o valor de variaveis do programa ( copiadas para uma variavel global ) e saber se cada parte do código tá fazendo o que deveria fazer. Isso é algo comum na etapa de desenvolvimento.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x