天天看點

51單片機液晶1602 ADC0832 proteus仿真源程式

基于網上的資料,整理而成。

/**
 * 51單片機 1602+ADC0832顯示程式,用proteus 7.8仿真通過。
 */

#include <reg52.h>
#include <intrins.h>
#include <math.h>
#include <stdio.h>

char data str[]="                ";

/**********LCD1602接口程式**********/

#define DD P2
sbit Rs = P3^0;
sbit Rw = P3^1;
sbit E = P3^2;

void delay_1ms(unsigned char i) //最小延時1ms
{
    unsigned char j;
    while(i--)
        for(j=0;j<125; j++);
}

void delay_10us(unsigned char i) //最小延時10us
{
    unsigned char j;
    while(i--)
        for(j=0;j<10; j++);
}

void write_com(unsigned char com) //寫指令
{
    delay_10us(5);
    E=0;
    Rs=0;
    Rw=0;
    DD=com;
    delay_10us(50); //>40us
    E=1;
    delay_1ms(2); //>150us
    E=0;
    delay_10us(4); //>25+10us
}


void write_data(unsigned char DATA)  //寫資料
{
    delay_10us(50);
    E=0;
    Rs=1;
    Rw=0;
    DD=DATA;
    delay_10us(50);
    E=1;
    delay_10us(50);
    E=0;
    delay_10us(4);
}

void addr_x_y(unsigned char x,bit y)  //寫坐标,定位置
{
    unsigned char temp=0x80; //預設最高位:D7為1 即以0x80開始。

    if(y) //y :0為第一行 1為第二行
    {
        temp|=0x40;
    }
    temp|=x;
    write_com(temp);
}

//在指定位置顯示一個字元。
void Show_Char(unsigned char x,bit y,unsigned char p)
{
    addr_x_y(x,y);
    write_data(p);
}

void Show_String(unsigned char x,bit y,char *ptr)
{
    unsigned char i;
    for (i=0;i<16;i++)
        Show_Char(x++,y,*(ptr+i));//循環顯示16個字元
}

//1602初始化代碼
void init(void)
{
    delay_1ms(1500);
    write_com(0x38);
    delay_1ms(5);
    write_com(0x38);
    delay_1ms(5);
    write_com(0x38);
    delay_1ms(5);
    write_com(0x38);
    write_com(0x08);
    write_com(0x06);
    write_com(0x0c);
    write_com(0x01);
}

void xs_int(unsigned int shuju,bit t) //資料顯示
{
    unsigned char huancun[6]={0};
    unsigned char biaozhi=0,i;

    if (shuju < 10) biaozhi = 1;
    else if(shuju < 100) biaozhi = 2;
    else if(shuju < 1000) biaozhi = 3;
    else if(shuju < 10000) biaozhi = 4;
    else if(shuju < 65535) biaozhi = 5;

    switch(biaozhi) //這裡沒有break,是以從辨別比對的入口直接執行到最後,完成整數各位的提取到數組。
    {
        case 5:
            huancun[5] = shuju/10000;
        case 4:
            huancun[3] = shuju%10000/1000;
        case 3:
            huancun[2] = shuju%1000/100;
        case 2:
            huancun[1] = shuju%100/10;
        case 1:
            huancun[0] = shuju%10;
            break;
        default:
            break;
    }
    for(i=0;i<6;i++)
    {
        if(i==1)
            Show_Char(i,1,'.'); /* 加入小數點,縮小了10000倍,是以AD采樣後的值需要乘上10000*5V/256=196(V) */
        else
            Show_Char(i,t,0x30+huancun[6-i-1]);
    }
    Show_Char(6,t,'V');
}

/**********ADC0832接口程式************************************/
sbit ADC_CS =P3^4;
sbit ADC_CLK=P3^5;
sbit ADC_DO =P3^6;
sbit ADC_DI =P3^7;

void Delay(unsigned char j)
{
    unsigned char i;
    for(i=0;i<j;i++); //延時,脈沖一位持續的時間
}

unsigned char ADC0832(void) //把模拟電壓值轉換成8位二進制數并傳回
{
    unsigned char i,data_c;
    data_c=0;
    ADC_CS=0;
    ADC_CLK=1;
    ADC_DO=0;//片選,DO為高阻态
    //ADC_DI=0; //先拉低

    for(i=0;i<10;i++)
    {;}

    ADC_CLK=0;
    Delay(2);
    ADC_CLK=1;
    ADC_DI=1; //啟始位
    Delay(2);

    ADC_CLK=0; //第一個脈沖下降沿,DI=1為起始位?
    Delay(2);
    ADC_CLK=1;
    ADC_DI=1;//1
    Delay(2);

    ADC_CLK=0; //第二個脈沖下降沿,DI=1
    Delay(2);
    ADC_DI=1;//1 若為0則選擇CH0
    ADC_CLK=1;
    Delay(2);

    ADC_CLK=0; //第三個脈沖下降沿,DI=1,選擇 ADC0832 的CH1(1 1)
    Delay(2);
    ADC_DI=1; //已不關心
    ADC_DO=1; //高阻
    ADC_CLK=1;
    Delay(2);

    for (i=0; i<8; i++)
    {
        ADC_CLK=0; //第四個開始讀資料
        Delay(2);
        data_c=(data_c<<1)|ADC_DO;//在每個脈沖的下降沿DO輸出一位資料,最終ch為8位二進制數
        ADC_CLK=1;
        Delay(2);
    }
    ADC_CS=1;//取消片選,一個轉換周期結束
    return(data_c);//把轉換結果傳回
}

void main(void)
{
    unsigned int data_temp=0;
    while(1)
    {
        data_temp=ADC0832();
        sprintf(str,"The voltage is:"); //the first line
        init();
        Show_String(0,0,str);
        xs_int(196*data_temp,1); /* 10000*5V/256=196(V),把采樣值放大10000倍後再處理,移動小數點4位。
            4位有效數字,其實用不到,因為8位采樣精度為:0.019V */
        delay_1ms(1500);
    }
}
           

proteus仿真原理圖如下:

51單片機液晶1602 ADC0832 proteus仿真源程式