PIC18F4550 Help on a Homework plz?

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
hardware:
-Motor DC
-Bridge H
-LM35 Temperature Sensor
-Potenciometro 50k Ohms
-LCD
-LEDs

Software:
-The LCD should start showing the student's name on the first line and the course name in the second line.
-If The push button key (CH1) connected to the INT0 interrupt pin is activated, it will allow the A / D conversion perform the pot,
and this converted value, to the motor PWM cycle;
-The Key CH2 and CH3 select the motor direction;
-For Both cases, the LCD shows:
"Motor powered" - First line of the display if the CH1 is triggered
"Duty PWM = xxx%" - Second line of the display if the CH2 switch is activated;
- "Temperature Sensor" - first line of the LCD, if CH1 is not pressed;
- "Temperature = XXºC" -Second line, CH1 is not pressed through the LED1 indicates the motor direction of rotation;

So, i'm coding my Pic 18F4550 in MPLAB, and i'm stuck, really, This is my code:

C:
#include<p18f4550.h>
#include<delays.h>
#include<pwm.h>

#pragma config CCP2MX=ON  //PINO RC1 - ON
void TOPO (void);
void BOTO (void);
void nome(void);
void configuralcd(void);
void temperatura (void);
void atraso (unsigned char tempo);
void escreve_LETRA(unsigned char letra);
void escreve_CMD(unsigned char caracter);
void string (const rom char *i);

#define MAX 40
#define MAX1 500

#pragma code ALTA = 0x08  //Interrupção de ALTA prioridade
void ALTA (void)
{
    TOPO();
}
#pragma code
#pragma code BAIXA = 0x18 //Interrupção de BAIXA prioridade
void BAIXA (void)
{
    BOTO();
}
#pragma code

int duty_pwm=0;
int a=0;
char graus;
float   X;

void main()
{
    char dezena,unidade;
    ADCON0bits.ADON=0; //Desliga o Conversor A/D
    ADCON1= 0b00001111; //Todos os canais com Entrada Digital
    RCONbits.IPEN=0; //Prioridade de Interrupção Desligada
    INTCONbits.GIE=1; //Interrupções Globais Habilitadas
    INTCONbits.PEIE=1; //Interrupções de Periféricos Habilitadas
    INTCONbits.INT0IE=1; //Interrupção INT0 Habilitada
    INTCONbits.INT0IF=0; //Flag de Interrupção ?Limpo?
    INTCON2bits.INTEDG0=1; //Interrupção Sensível a Borda de Subida
    DDRDbits.RD0=0;       //RD0 Saida
    DDRCbits.RC1=0;       //RC1 Saida

   //configuração da interrupção
    ADCON1=0x0F;          //Canais analógicos desligados
    RCONbits.IPEN=1;      //INT com prioridade = 1
    INTCONbits.GIE=1;     //INT Globlal = 1
    INTCONbits.PEIE=1;    //INT periferica = 1
    INTCON2bits.INTEDG1=0;//INT 1 em Borda de DESCIDA
    INTCON2bits.INTEDG2=1;//INT 2 em Borda de SUBIDA
    INTCON3=0b01011000;

    //configuração do timer
    T2CONbits.T2CKPS0=0;  //    Pre-escala (PS)
    T2CONbits.T2CKPS1=1;  //vvvvvvvvv1:16vvvvvvvvv
    T2CONbits.TMR2ON=1;   //timer 2 = ON
    T2CONbits.T2OUTPS0=0; //------------------------
    T2CONbits.T2OUTPS1=0; //  seleciona pós escala
    T2CONbits.T2OUTPS2=1; //         1:16
    T2CONbits.T2OUTPS3=1; //------------------------
    TMR2=0x00;            //Timer inicia em 0
    PR2=38;               //conta ate 38 e compara com o TRM2, pra gerar um
                          //pulso para a postcale
    //configura o PWM
    CCP2CONbits.CCP2M0=0; //-----------------
    CCP2CONbits.CCP2M1=0; //   Habilita o
    CCP2CONbits.CCP2M2=1; //      PWM2
    CCP2CONbits.CCP2M3=1; //-----------------

    configuralcd();
    atraso(MAX);
    nome();
    while(1)
    {
            if(a==1)
    {
        ADCON0bits.GO=1;
        while (ADCON0bits.GO==1);

        escreve_CMD(0X01);

        dezena=(graus/10)+48;
        PORTEbits.RE0=1;    //dezena
        PORTEbits.RE1=1;
        PORTD=dezena;
        atraso(MAX);
        PORTEbits.RE1=0;
        atraso(MAX);

        unidade=(graus%10)+48;
        PORTEbits.RE0=1;   //unidade
        PORTEbits.RE1=1;
        PORTD=unidade;
        atraso(MAX);
        PORTEbits.RE1=0;
        atraso(MAX);
        a=2;
    }
    if(a==2)
    {
        atraso(MAX1);
        atraso(MAX1);
        atraso(MAX1);
        atraso(MAX1);
        nome();
        a=0;
    }
    }
}

#pragma interrupt TOP
void TOPO (void)
{
    duty_pwm+=50; //incrementa 50
    if (duty_pwm>156)
    {
        duty_pwm=156;
    }
    else
    {
        SetDCPWM2(duty_pwm);
    }
    INTCON3bits.INT1IF=0; //Int Flag vai pra 0
}
#pragma interrupt BOT
void BOTO (void)
{
    duty_pwm-=50; //decrementa 50
    if (duty_pwm<0)
    {
        duty_pwm=0;
    }
    else
    {
        SetDCPWM2(duty_pwm);
    }
    INTCON3bits.INT2IF=0; //Int Flag vai pra 0
}
void atraso (unsigned char tempo)
{
    int i;
    for(i=0;i<tempo;i++)
    {
        Delay1KTCYx(1);
        Delay1KTCYx(1);
        Delay1KTCYx(1);
        Delay1KTCYx(1);
        Delay1KTCYx(1);
    }
}
void nome(void)
{
    escreve_CMD(0X01);
    string("STUDENT"); //Escreve a primeira linha do DISPLAY
    escreve_CMD(0X00);
    escreve_CMD(0XC0);
    string("COURSE"); //Escreve a segunda linda do DISPLAY
}

void configuralcd(void)
{
    escreve_CMD(0x30);//escolha de bits
    escreve_CMD(0x38);//matriz
    escreve_CMD(0x0F);//Cursor Piscante
    escreve_CMD(0x06);//DESLOCAMENTO DO CURSOR
}

void escreve_CMD(unsigned char caracter)
{
    PORTEbits.RE0=0;    //COMANDOS
    PORTEbits.RE1=1;
    PORTD=caracter;
    atraso(MAX);
    PORTEbits.RE1=0;
    atraso(MAX);
}

void escreve_LETRA(unsigned char letra)
{
    PORTEbits.RE0=1;    //DADOS
    PORTEbits.RE1=1;
    PORTD=letra;
    atraso(MAX);
    PORTEbits.RE1=0;
    atraso(MAX);
}
void string (const rom char *i)
{
    while(*i>0)
    {
        escreve_LETRA(*i++);
    }
}
#pragma interrupt temperatura
void temperatura (void)
{
    int result; //Variável de 16 bits

    DDRAbits.RA0 = 1; //Pino A0 como entrada
    ADCON0bits.ADON = 1; //Habilita o conversor A/D
    PIE1bits.ADIE = 0; //Desliga a Interrupção por conversão A/D
    ADCON0bits.CHS0 = 0; //------------------------
    ADCON0bits.CHS1 = 0; // SELECIONA O CANAL
    ADCON0bits.CHS2 = 0; // AN0
    ADCON0bits.CHS3 = 0; //------------------------
    ADCON1 = 0b00001110; //REFERENCIA DE Vss e VDD e o CANAL AN0 como analógico
    ADCON2 = 0b10111101; //FOSC / 16
    //TAD = 20x
    //ADFM = Resultado Justificado á Direita
    ADCON0bits.GO = 1; //Inicializa a Conversão (16 us de aquisição)
    while (ADCON0bits.GO == 1); //Programa Fica parado no WHLE até que o bit GO vá para 0
    result=((unsigned int)ADRESH<<8)|(ADRESL); //RESULTADO EM BINÁRIO
    X=((float)result*5)/1023;
    graus=(X*1)/0.01;
    a=1;

    INTCONbits.INT0IF=0; // limpa flag
}
PLZ, can someone JUST HELP ME, PLZ, It's a hurry, I do really need to do this, if someone send me the complete code, do it your way or send me an example so I can understand better and FINISH IT!!
THX !!!

and sorry my bad english. ;P

Mod EDIT: Use code tags to make your code easier to read. Moved this thread to Homework Help.
 
Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
4,787
Welcome to AAC!

You will get more help faster if you post a schematic or hookup diagram of your circuit and a detailed description of what is and is not working and what it shows on the display, LEDs etc.
Which compiler are you using? MPLAB supports several.
On common problem that I think I see here is that you are not initializing the LCD display correctly. You need delays between the commands (and characters too when you write). If you search on LCD, Hitachi 44780 or similar terms, you'll probably get some hits with code. I've attached a datasheet describing the controller that most dot-matrix LCD modules use. Compare your init code with that.

Good luck.

EDIT: A quick search brought up this thread which discusses LCD inits among other things. There are lots of others here.
Here's a good one with searching help from @nerdegutta (thanks again!)
 

Attachments

Last edited:

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
I am using compiler C18.

The LCD is starting correctly, and showing my Name and my Course. But after a Time it should show in the first line "Temperature Sensor" and on the second line it should show the Temperature of LM35, BUT I don't know how to do it...

And a second question is, how to I control a Motor with a Potentiometer via PIC18F4550, The potentiometer with 50K Ohms need to be connected directly to the Pic, and the Pic needs to read it's OHMs, after reading the resistence, It will make the motor Faster or Slower via a PWM..

To read the resistence, I need to Enable the A/D? And which is the PWM terminal and A/D Terminal? (I can't find this information and neither remember)
 

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
Yeah, CCP2, Now I found it hehe, just don't know how to use a Potentiometer to control the PWM and control the High Band (more time in 1 than in 0)
 

djsfantasi

Joined Apr 11, 2010
9,162
What does A to D read? Or in other words, what is its input? You have the answers available to you if you don't know.

Then, what does it output? We know it's digital, but what else can you say about it?
 

djsfantasi

Joined Apr 11, 2010
9,162
You may be confused on what the AD converter is reading. Did you refer to the data sheet?

Let's pretend the ADC is connected to an MP3 player. What is it reading now? Is it different that the circuit with the potentiometer? Does that make sense if you think it's different?
 

ErnieM

Joined Apr 24, 2011
8,377
To expand on djsantasi's question... What is the A2D, or the Analog To Digatal converter reading?

The answer is right in front of you.
 

shteii01

Joined Feb 19, 2010
4,644
It read the Hardware OHMs from the potentiometer, and in the Output it will make a Motor Faster or Slower.

And here is a Almost finished circuitry
Pot is a voltage divider. What is different is that it is ADJUSTABLE voltage divider. You, the user, rotate the knob and that changes the resistances in the voltage divider, which in turn changes the voltage drop across each resistor that forms the voltage divider. You then feed the voltage from voltage divider to the ANALOG to DIGITAL CONVERTER. Your ADC is reading voltages, not resistances. This same process should be repeated for the temperature sensor.

As far as temperature, you can use this for an example of the procedure, you will have to write your own code, but the formula should work:
https://learn.adafruit.com/tmp36-temperature-sensor
https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor
So the algorithm is:
1) temp sensor produces voltage, this voltage is sent to ADC
2) ADC converts the voltage into digital value
- if ADC is 8 bit, it produces digital values from 0 to 255
- if ADC is 10 bit, it produces digital values from 0 to 1023
Read what ADC your PIC has. This is your job. One of many.
3) the software converts the digital value into temperature using formula
4) change the temperature from Step 3 into characters
5) send characters to lcd

As far as pot. It has three pins, left and right pins will determine the range of voltages, the middle pin is the your knob and when you rotate the knob you move this pin and changes the resistances in the voltage divider. ASSUMING you want values from 0 to +Something, then you connect one side pin to 0 volts/Ground, this is your reference pin/reference voltage of the voltage divider/pot, this is also will be your minimum speed, 0 volts==0 RPM for example. The other side pin is going to be your maximum voltage, this is the voltage that correspond to the maximum speed. Again, I will ASSUME that you are using 5 volt PIC, the maximum voltage that ADC of your PIC can read is 5 volts. So you want to put 5 volts on the other side pin of the pot. To review, you have 0 volts on one side pin of the pot, you have 5 volts on other side pin of the pot. The middle pin of the pot is connected to the ADC of the PIC. The ADC will read the voltage coming out of the voltage divider/pot, convert it into digital value (8 bit: 0-255; 10 bit: 1-1023; etc.) and then your program will look at the digital value and setup the PWM to drive the motor.

As far as driving the motor. You will have to either setup some kind of Look Up Table or use a formula.
 

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
OK, I Did INT0 (interrupt in pin RB0) Work, and now LCD works correctly with strings, commands, and writings.

But now, I still don't know how to convert, in Analogic, the value in ohms from potentiometer to make the motor run faster or slower.
I Set RA0 and RA1 (which are two analog pins) to work as analogic, but now, I don't know what to do, how to use it =/

and don't know how to say a variable on a string to show how much duty is on the LCD screen...
Like this, for writing on the LCD, I write:
string("herethetext", 1); (this 1 is the line 1, if 2 then goes to line 2)
but how do I say the duty via a variable? does it work like
string("DutyPWM%d%, 2);
????
 

djsfantasi

Joined Apr 11, 2010
9,162
ADC reads voltage, not ohms. And it does not return the actual voltage. It returns a number from 0 to 1023 (depending on the bit accuracy). So you have to map the numbered returned to what you want your motor to do.
 

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
OHHHH, Thanks djsfantasi, now I think I know a way to make it, so, I will need to quantize (or quantizate) (sorry english isn't my main language)
anyways, there's 3 Prints of the Ready circuit.

Now i'll try to implement the PWM and LM35 Reader to the code.
=D
 

Attachments

Thread Starter

Jouy Durão

Joined Dec 6, 2015
7
SO, I did the Code, and now I need to write on the LCD the DUTY PWM, but, I don't know how to calculate it right, and get it to work...
CAN SOMEONE GIVE A LIGHT?
I don't know how to quantizate it from 100 to 0%, and show it on the display and the PWM output (RC1 on PIC) work correctly.
Here is my code, feel free to change it =P
The TMR(void) and INTerruption are the part of PWM
C:
#include<p18f4550.h>
#include<delays.h>

#pragma config CCP2MX=ON  //PINO RC1 - ON (Saida PWM)
#pragma config FOSC=HS // Fosc = 20MHz
#pragma config PWRT=OFF
#pragma config CPUDIV=OSC1_PLL2 //Divisor de Frequência == 1
#pragma config WDT=OFF //Watchdog Desligado
#pragma config MCLRE=ON //Master Clear Ligado
#pragma config LVP=OFF //Low Program Voltage Desligado
#pragma config BOR=OFF //Brown-Out Timer Desligado

//void string()
#define RS PORTEbits.RE0
#define RW PORTEbits.RE2
#define ENA PORTEbits.RE1

void delay_ms(unsigned int tempo);
void delay_us(unsigned int tempo);
void comandalcd(unsigned char valor, char valor_rs);
void escrevelcd(unsigned char valor);
void configlcd(void);
void string(const rom char *i, unsigned char linha);
void INT(void);
void temperatura(void);
void escrevetemperatura(void);
void TMR(void);


#pragma code end_INTE = 0x08  //Interrupção de BAIXA prioridade

void end_INTE(void)
{
    INT();
}
#pragma code

int duty_pwm = 0;
int a = 0;
char graus;
char b = 0;
char c = 0;
float X;
int motor = 0;
int ENG = 0;
char configTMR = 0;

void main()
{
    char dezena, unidade;
    DDRA = 0b11000011;
    DDRC = 0x00;
    DDRD = 0x00;
    DDRE = 0b00001000;
    DDRB = 0b01100001;
    PORTB = 0x00;
    PORTD = 0x00;
    PORTA = 0x00;
    PORTC = 0x00;
    PORTE = 0x00;

    //configuração da interrupção
    ADCON0bits.ADON = 0x00; //Desliga o Conversor A/D
    ADCON1 = 0b00001111; //Todos canais como entrada Digital
    RCONbits.IPEN = 0; //Prioridade de Interrupção ligada
    INTCONbits.GIEL = 1; //Habilita INT sem Mascara DataSheet
    INTCONbits.GIE = 1; // Interrupções Globais Habilitadas
    INTCONbits.PEIE = 1; //Interrupções de Periféricos Habilitadas
    INTCONbits.INT0IE = 1; //Habilita INT0
    INTCONbits.INT0IF = 0; //Limpra flag INT0
    INTCON2bits.INTEDG0 = 1; //Interrupção Sensível a Borda de Subida

    configlcd();
    string("GABRIELA", 1);
    string("ELETRONICA", 2);
    delay_ms(50);
    while (1)
    {
        if (a == 0)
        {
            temperatura();
            if (b == 0) //se a temperatura estiver diferente
            {
                comandalcd(0x01, 0); //limpa a tela
                string("TEMPERATURA", 1); //escreve na linha 1
                delay_us(5);
                comandalcd(0xC0, 0); //pula linha
                escrevetemperatura(); //escreve a temperatura
                escrevelcd('C'); //escreve o C de Celsius após a temperatura
            }
            else if (b == 1) //se a temperatura estiver igual
            {
                temperatura();
            }
        }
        if (motor >= 1)
        {
            motor = 0;
        }
        if (PORTBbits.RB5 == 1 && PORTBbits.RB6 == 0) //SEN1
        {
            PORTBbits.RB3 = 1; //Saida como SEN1
            PORTBbits.RB4 = 0; //DESLIGA o SEN2
            PORTBbits.RB7 = 1; //LIGA o LED
        }
        else if (PORTBbits.RB5 == 0 && PORTBbits.RB6 == 1) //SEN2
        {
            PORTBbits.RB3 = 0; //DESLIGA o SEN1
            PORTBbits.RB4 = 1; //Saida como SEN2
            PORTBbits.RB7 = 0; //DESLIGA o LED
        }
    }
}

#pragma interrupt INT

void INT(void)
{
    int result;
    char centena, dezena, unidade;
    if (INTCONbits.INT0IF == 1)
    {
        if (configTMR == 0)
        {
            TMR();
        }
        ADCON1 = 0b00001011; //PORTAS RA0 e RA1 viram analógicas
        comandalcd(0x01, 0); //apaga LCD
        string("MOTOR ACIONADO", 1);
        string("Duty PWM = ", 2);
        ADCON0bits.ADON = 1; //Habilita o conversor A/D
        PIE1bits.ADIE = 0; //Delisga a interrupção por converão A/D
        ADCON0bits.CHS0 = 0; //------------------------
        ADCON0bits.CHS1 = 0; // SELECIONA O CANAL
        ADCON0bits.CHS2 = 0; // AN0
        ADCON0bits.CHS3 = 0; //------------------------
        ADCON1 = 0b00001110; //Referencia de VSS e VDD e o canal AN0 como analóg
        ADCON2 = 0b10111101; //FOSC /16
        ADCON0bits.GO = 1; //inicializa a conversão (leva 16us)
        while (ADCON0bits.GO == 1); //Programa Fica parado no WHLE até que o bit GO vá para 0
        result = ((unsigned int) ADRESH << 8) | (ADRESL); //RESULTADO EM BINÁRIO
        X = ((float) result * 5) / 1023;
        SetDCPWM2(X); //envia o sinal do PWM para o Motor
        ENG = (X * 1) / 0.01;
        centena = (ENG / 100) + 48;
        PORTD = centena;
        PORTE = 0b00000011; // ENABLE e RS em 1
        delay_us(100);
        PORTE = 0b00000001; // ENABLE em 0 RS em 1
        delay_us(100);
        dezena = (ENG / 10) + 48;
        PORTD = dezena;
        PORTE = 0b00000011; // ENABLE e RS em 1
        delay_us(100);
        PORTE = 0b00000001; // ENABLE em 0 RS em 1
        delay_us(100);
        unidade = (ENG % 10) + 48;
        PORTD = unidade;
        PORTE = 0b00000011; // ENABLE e RS em 1
        delay_us(100);
        PORTE = 0b00000001; // ENABLE em 0 RS em 1
        delay_us(100);
        motor = 1;
    }
    //ADCON0bits.ADON = 0;
    /*duty_pwm+=50; //incrementa 50
    if (duty_pwm>156)
    {
        duty_pwm=156;
    }
    else
    {
        SetDCPWM2(duty_pwm);
    }*/
    a = 0;
    INTCONbits.INT0IF = 0; //Int1 Flag vai pra 0
}

void TMR(void)
{
    //configuração do timer
    T2CONbits.TMR2ON = 1; //timer 2 = ON
    T2CONbits.T2CKPS0 = 1; //    Pre-escala (PS)
    T2CONbits.T2CKPS1 = 1; //vvvvvvvvv1:16vvvvvvvvv
    TMR2 = 0x00; //Timer inicia em 0
    PR2 = 255; //conta ate 819us e compara com o TRM2, pra gerar um
    //pulso para a postcale

    //configura o PWM
    CCP2CONbits.CCP2M0 = 1; //-----------------
    CCP2CONbits.CCP2M1 = 1; //   Habilita o
    CCP2CONbits.CCP2M2 = 1; //      PWM2
    CCP2CONbits.CCP2M3 = 1; //-----------------
    configTMR = 1;
}

void temperatura(void)
{
    int result; //Variável de 16 bits

    DDRAbits.RA1 = 1; //Pino A1 como entrada
    ADCON0bits.ADON = 1; //Habilita o conversor A/D
    PIE1bits.ADIE = 0; //Desliga a Interrupção por conversão A/D
    ADCON0bits.CHS0 = 1; //------------------------
    ADCON0bits.CHS1 = 0; // SELECIONA O CANAL
    ADCON0bits.CHS2 = 0; // AN0
    ADCON0bits.CHS3 = 0; //------------------------
    ADCON1 = 0b00001101; //REFERENCIA DE Vss e VDD e o CANAL AN0 e AN1 como analógico
    ADCON2 = 0b10111101; //FOSC / 16
    //TAD = 20x
    //ADFM = Resultado Justificado á Direita
    ADCON0bits.GO = 1; //Inicializa a Conversão (16 us de aquisição)
    while (ADCON0bits.GO == 1); //Programa Fica parado no WHILE até que o bit GO vá para 0
    result = ((unsigned int) ADRESH << 8) | (ADRESL); //RESULTADO EM BINÁRIO
    X = ((float) result * 5) / 1023;
    graus = (X * 1) / 0.01;
    if (c == graus)
    {
        b = graus;
    }
    else if (c != graus)
    {
        b = 0;
        c = graus;
        //string("TEMPERATURA", 1);
    }
}

void escrevetemperatura(void)
{
    char dezena, unidade;
    temperatura();
    ADCON0bits.GO = 1;
    while (ADCON0bits.GO == 1);
    dezena = (graus / 10) + 48;
    PORTD = dezena;
    PORTE = 0b00000011; // ENABLE e RS em 1
    delay_us(100);
    PORTE = 0b00000001; // ENABLE em 0 RS em 1
    delay_us(100);
    unidade = (graus % 10) + 48;
    PORTD = unidade;
    PORTE = 0b00000011; // ENABLE e RS em 1
    delay_us(100);
    PORTE = 0b00000001; // ENABLE em 0 RS em 1
    PORTE = 0b00000000; //Setando todo o PORTE para Zero
}

void comandalcd(unsigned char valor, char valor_rs)
{
    PORTEbits.RE0 = valor_rs; // PINO RS 1=caracter 0=comando
    PORTEbits.RE2 = 0; // RW 0=escrever
    PORTD = valor; //Recebe o caracter ou comando para o PORTD
    PORTEbits.RE1 = 1; //Pino ENABLE ligado
    delay_us(1);
    PORTEbits.RE1 = 0; //Pino ENABLE desligado
    delay_us(400);
}

void escrevelcd(unsigned char valor)
{
    PORTD = valor;
    PORTE = 0b00000011; //Pino ENABLE e RS em 1
    delay_us(4);
    PORTE = 0b00000001; //Pino ENABLE em Zero
    delay_us(4);
    PORTE = 0b00000000; //PORTAS RE em Zero
}

void configlcd()
{
    comandalcd(0x30, 0); //Ativa modo 8Bits
    comandalcd(0x38, 0); //8Bits com 2 linhas e font de 5x7
    comandalcd(0x01, 0); //Limpa Display
    comandalcd(0x0c, 0); //Liga Display, Cursor Desligado
    comandalcd(0x06, 0); //Incrementa Cursor
    comandalcd(0x0f, 0); //Ativa Cursor Piscante
}

void string(const rom char *i, unsigned char linha)
{
    if (linha == 1)
    {
        //comandalcd(0x01, 0); //Curso linha 1 col 1
        while (*i)
        {
            escrevelcd(*i); //Caracter
            i++;
        }
    }
    else if (linha == 2)
    {
        comandalcd(0xC0, 0); //Pula Linha e
        while (*i) //cursor col 1 lin 2
        {
            escrevelcd(*i); //Caracter
            i++;
        }
    }

}

void delay_ms(unsigned int tempo)
{
    unsigned int i;
    for (i = 0; i < tempo; i++)
    {
        Delay1KTCYx(500);
    }
}

void delay_us(unsigned int tempo)
{
    unsigned int i;
    for (i = 0; i < tempo; i++)
    {
        Delay1TCY(); //atrasa 0.2us
        Delay1TCY();
        Delay1TCY();
        Delay1TCY();
        Delay1TCY();
    }
}
 
Top