PIC16F877 timing voltage acquisition LCD1602 display Proteus simulation diagram

Publisher:advancement3Latest update time:2020-04-25 Source: eefocusKeywords:PIC16F877 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Function: The timer collects the AD voltage once every 50us, a total of 30 times, and displays it on LCD1602.


Software: MPLAB X IDE v5.35, ISIS 7 Professional


Note: The system clock is configured as an external clock of 8Mhz. Since the data is collected every 50us, the AD collection time should be less than 50us. You can collect AD data at different intervals by adjusting the value of the timer.


code show as below:


#include "pic.h"

#define RS RC1 //command or data

#define RW RC2 //read write io

#define EN RC3 //enable


__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF ​​& BOREN_ON & LVP_ON & CPD_OFF);


void LCD1602_Init(void); 

void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str); //display 

void Time_Init(void);

void ADC_Init(char k);

int AD_CollectVolt(void);


char AD_Complete_Flag = 0;    

unsigned int arr[30];  

unsigned int ad_volt = 0;  

unsigned long sum = 0;

unsigned char num = 0,j = 0;

unsigned int Data = 0;

unsigned char volt_num[5];


void main(void) //Fosc = 8Mhz

{

    PEIE = 1;  

    GIE = ​​1;  

    TRISC = 0X00; //OUTPUT

    TRISD = 0X00; //OUTPUT


    Time_Init(); //50us interrupt

    ADC_Init(0); //Channel 0 RA0

    LCD1602_Init();

    

    while(1)

    {

        AD_CollectVolt();

        volt_num[0] = ad_volt/1000 + 48;

        volt_num[1] = ad_volt/100%10 + 48;

        volt_num[2] = ad_volt/10%10 + 48;

        volt_num[3] = ad_volt%10 + 48;

        volt_num[4] = '';

        LcdShowStr(0, 0, &volt_num);

        LcdShowStr(5, 0, "MV");

    }

}


void interrupt ISR(void)

{

    static unsigned char test = 0;

    if((TMR1IE == 1) && (TMR1IF == 1))  

    {

        TMR1IF = 0;  

        TMR1 = TMR1 + 0xffcd;  

        

        if(GO != 1)  

        {

            Data = ADRESH; 

            Data = Data << 8;  

            Data = Data | ADRESL;   

            arr[num]= Data;

            num++;

        }

        GO = 1;  

        if(test == 0) //test 50us time GPIO

        {

            RC4 = 0;

            test = 1;

        }

        else

        {

            RC4 = 1;

            test = 0;

        }


        if(num >= 30)  

        {

            TMR1ON = 0;    

            TMR1IE = 0;

            for(j = 0;j < 30;j ++)

            {

                sum = sum + arr[j];

            }

            sum = sum/30;

            ad_volt = sum*5000/1024;

            sum = 0;

            num = 0;

            AD_Complete_Flag = 1;

        }

    }

}


void LCD_WaitReady(void)

{

    unsigned char sta;

    PORTD = 0xff;

    RS = 0;

    RW = 1;

    do

    {

        EN = 1;

        sta = PORTD;

        EN = 0;

    }

    while(sta&0x80);

}


void Write_Command(unsigned char Command)

{

    LCD_WaitReady();

    PORTD = Command;

    RW = 0;

    RS = 0;

    EN = 1;

    EN = 0;    

}


void Write_Data(unsigned char Data)

{

    LCD_WaitReady();

    PORTD = Data;

    RW = 0;

    RS = 1;

    EN = 1;

    EN = 0;    

}


void LcdSetCursor(unsigned char x, unsigned char y)

{

    unsigned char addr;

    if (y == 0)

    { 

        addr = 0x00 + x;

    }

    else

    {

        addr = 0x40 + x; 

    }

    Write_Command(addr | 0x80); 

}


void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)

    {

    LcdSetCursor(x, y); 

    while (*str != '')

    { 

        Write_Data(*str++); 

    }

}


void LCD1602_Init(void)

{

    Write_Command(0x38);

    Write_Command(0x0c);

    Write_Command(0x06);

    Write_Command(0x01);

}


void Time_Init(void)

{

    TMR1CS = 0; //FOSC/4

    T1CKPS1 = 0;

    T1CKPS0 = 1; //1:2      

    TMR1 = 0xffcd; //50us    

    TMR1IF = 0;  

    TMR1IE = 1;  

}

void ADC_Init(char k)

{

    TRISA = 0XFF; //input

    ADCON1 = 0X80;

    ADCON0 = 0b00000001; //FOSC/2

    ADCON0 |= (k << 3);       

}

int AD_CollectVolt(void)  

{

    TMR1ON = 1;

    TMR1IE = 1;

    GO = 1;         

    do  

    {

    }

    while(AD_Complete_Flag == 0); //delay collect volt complete

    AD_Complete_Flag = 0;

}


Hardware Diagram:


Connect an external 3V power supply in RA1, and the LCD displays 2998mv;

Note: How to verify whether the data is collected once every 50us? In the timer interrupt function, flip the IO port level and then observe it with an oscilloscope.

As shown in the figure above, the value flips once every 50us, which means that the AD value is collected once every 50us.

Keywords:PIC16F877 Reference address:PIC16F877 timing voltage acquisition LCD1602 display Proteus simulation diagram

Previous article:【MPLAB X IDE】05: Configuration bits
Next article:PIC microcontroller I2C communication (master mode)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号