再做三点温度检测,遇到些采样转换与lcd显示问题,求帮助

2019-07-15 14:06发布

本帖最后由 Mr_vxman 于 2016-5-4 16:45 编辑

问题主要是,调节滑动变阻器,lcd上面的数字是随机变化的,比如说,直接从1跳到4,再变成0,不是按线性变化的
#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int
#define LCD_DataBus P2
//AD0808引脚定义
sbit OE = P3^0;
sbit START = P3^1;
sbit EOC = P3^2;
//LCD12864引脚定义
sbit LCD_E = P3^3;
sbit LCD_RW = P3^4;
sbit LCD_RS = P3^5;
sbit LCD_CS2 = P3^6;
sbit LCD_CS1 = P3^7;

//函数声明
void LCD_ReadBusy();
void InitLCD();
void LCD_ClearScreen(uchar screen);
void LCD_Display(uint flag,uchar ss,uchar page,uchar column,uchar *p);
void LCD_SetLine(uchar line);
void LCD_LoadPhoto();
uint DataProcessing(uint value,uchar flag);
void WriteOutData(uchar flag,uchar a,uchar b,uchar c);
/*------------------------------字模------------------------------*/
//1、数字字模0-9(宋体),11(M),12(T),13(U),14(:) 15(.)
uchar code num[15][16]={
                                                {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},
                                                {0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00},
                                                {0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},
                                                {0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00},
                                                {0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24},
                                                {0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00},
                                                {0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00},
                                                {0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00},
                                                {0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},
                                                {0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00},
                                                {0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x01,0x3E,0x01,0x3F,0x20,0x00},
                                                {0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},
                                                {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},
                                                {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},
                                                {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00}
                                                };
//智(宋体)
uchar code CH_zhi[]={0x10,0x94,0x53,0x32,0x1E,0x32,0x52,0x10,0x00,0x7E,0x42,0x42,0x42,0x7E,0x00,0x00,
                                0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,0x00};
//能(宋体)
uchar code CH_neng[]={0x08,0xCC,0x4A,0x49,0x48,0x4A,0xCC,0x18,0x00,0x7F,0x88,0x88,0x84,0x82,0xE0,0x00,
                                0x00,0xFF,0x12,0x12,0x52,0x92,0x7F,0x00,0x00,0x7E,0x88,0x88,0x84,0x82,0xE0,0x00};
//节
uchar code CH_jie[]={0x04,0x44,0x44,0x44,0x5F,0x44,0xC4,0x44,0x44,0x44,0x5F,0x44,0xC4,0x04,0x04,0x00,
                                0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x08,0x10,0x08,0x07,0x00,0x00,0x00};
//水
uchar code CH_shui[]={0x00,0x20,0x20,0x20,0xA0,0x60,0x00,0xFF,0x60,0x80,0x40,0x20,0x18,0x00,0x00,0x00,
                                0x20,0x10,0x08,0x06,0x01,0x40,0x80,0x7F,0x00,0x01,0x02,0x04,0x08,0x10,0x10,0x00};
//控
uchar code CH_kong[]={0x10,0x10,0x10,0xFF,0x90,0x20,0x98,0x48,0x28,0x09,0x0E,0x28,0x48,0xA8,0x18,0x00,
                                0x02,0x42,0x81,0x7F,0x00,0x40,0x40,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x40,0x00};
//制
uchar code CH_zhi2[]={0x40,0x50,0x4E,0x48,0x48,0xFF,0x48,0x48,0x48,0x40,0xF8,0x00,0x00,0xFF,0x00,0x00,
                                0x00,0x00,0x3E,0x02,0x02,0xFF,0x12,0x22,0x1E,0x00,0x0F,0x40,0x80,0x7F,0x00,0x00};
//系
uchar code CH_xi[]={0x00,0x00,0x22,0x32,0x2A,0xA6,0xA2,0x62,0x21,0x11,0x09,0x81,0x01,0x00,0x00,0x00,
                                0x00,0x42,0x22,0x13,0x0B,0x42,0x82,0x7E,0x02,0x02,0x0A,0x12,0x23,0x46,0x00,0x00};
//统
uchar code CH_tong[]={0x20,0x30,0xAC,0x63,0x30,0x00,0x88,0xC8,0xA8,0x99,0x8E,0x88,0xA8,0xC8,0x88,0x00,
                                0x22,0x67,0x22,0x12,0x12,0x80,0x40,0x30,0x0F,0x00,0x00,0x3F,0x40,0x40,0x71,0x00};
//温
uchar code CH_wen[]={0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
                                        0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00};
//度
uchar code CH_du[]={0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
                                        0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00};
//位
uchar code CH_wei[]={0x00,0x80,0x60,0xF8,0x07,0x10,0x90,0x10,0x11,0x16,0x10,0x10,0xD0,0x10,0x00,0x00,
                                        0x01,0x00,0x00,0xFF,0x40,0x40,0x41,0x5E,0x40,0x40,0x70,0x4E,0x41,0x40,0x40,0x00};
//浊
uchar code CH_zhuo[]={0x10,0x60,0x02,0x8C,0x00,0xF8,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0xF8,0x00,0x00,
                                        0x04,0x04,0x7E,0x01,0x20,0x63,0x21,0x21,0x21,0x3F,0x21,0x21,0x29,0x33,0x60,0x00};
//状
uchar code CH_zhuang[]={0x00,0x08,0x30,0x00,0xFF,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x22,0x2C,0x20,0x00,
                                                0x04,0x04,0x02,0x01,0xFF,0x80,0x40,0x30,0x0E,0x01,0x06,0x18,0x20,0x40,0x80,0x00};
//态
uchar code CH_tai[]={0x00,0x04,0x84,0x84,0x44,0x24,0x54,0x8F,0x14,0x24,0x44,0x84,0x84,0x04,0x00,0x00,
                                        0x41,0x39,0x00,0x00,0x3C,0x40,0x40,0x42,0x4C,0x40,0x40,0x70,0x04,0x09,0x31,0x00};
//℃
uchar code Temper[]={0x06,0x09,0x09,0xE6,0xF8,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
                                        0x00,0x00,0x00,0x07,0x1F,0x30,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00};

/*----------变量声明区-----------*/
uint datatemp = 0;
uint flag = 1;
uchar mark = 0;
uint outdata = 0;
uchar a,b,c;

void delay()   //---------延时子程序  
{
        char i,j;
        for(i=100;i>0;i--);     
        for(j=100;j>0;j--);
}
void main()
{
        EA = 1;          //全局中断开
        EX0 = 1;         //外部中断0开
        IT0 = 1;                 //边沿触发,IT1=0表示电平触发
        OE = 0;          //关闭AD0808输出
        START = 0;

/*--------LCD图形初始化---------*/
        LCD_LoadPhoto();

        while(1)
        {
                switch(flag)
                {        
                        case 1:P1 = 0x00;
                        break;
                        case 2:P1 = 0x01;
                        break;
                        case 3:P1 = 0x02;
                        break;
                        //default :flag = 1;
                }
                START = 1;     //产生一个下降沿脉冲,起动AD0808
                delay();
                START = 0;
                delay();
                while(mark)        //检测中断标志mark=1,表明已进入中断
                {
                        mark = 0;//重置中断标志
                        outdata = DataProcessing(datatemp,flag);
                        a = outdata / 100;//十位
                        b = (outdata-a*100) / 10;//个位
                        c = outdata%10;//取小数点后一位
                        WriteOutData(flag,a,b,c);
                        flag++;//检测下一个端口
                        if(flag > 3)
                        {
                                flag = 1;//初始化地址标志
                        }
                }
        }
}
void SendData(void) interrupt 0         //-------------使用外部中断0,采用负边沿触发方式,进入中断后即转换完成
{
        delay();
        delay();
        OE = 1;
        delay();     //允许输出
        datatemp = P0;
        delay();        //将转换完成的数据写入缓存变量
        //OE = 0;     //关闭输出
        mark = 1;
        return ;
}
/*------------------3路数据写入LCD------------------*/
//取数组函数
char *GetArray(uchar number)
{        uchar i;
        switch(number)
        {
                case 0: i = 0;
                break;
                case 1:        i = 1;
                break;
                case 2:        i = 2;
                break;
                case 3:        i = 3;
                break;
                case 4:        i = 4;
                break;
                case 5:        i = 5;
                break;
                case 6:        i = 6;
                break;
                case 7:        i = 7;
                break;
                case 8:        i = 8;
                break;
                case 9:        i = 9;
                break;
        }
        return num + i;
}
//数据处理
void WriteOutData(uchar flag,uchar a,uchar b,uchar c)
{
        switch(flag)
        {
                case 1: LCD_Display(a,1,2,40,GetArray(a));
                                LCD_Display(b,1,2,48,GetArray(b));
                                LCD_Display(14,1,2,56,num+14); //写小数点
                                LCD_Display(c,2,2,64,GetArray(c));
                                break;
                case 2: LCD_Display(a,1,4,40,GetArray(a));
                                LCD_Display(b,1,4,48,GetArray(b));
                                LCD_Display(14,1,4,56,num+14);
                                LCD_Display(c,2,4,64,GetArray(c));
                                break;
                case 3: LCD_Display(a,1,6,40,GetArray(a));
                                LCD_Display(b,1,6,48,GetArray(b));
                                LCD_Display(14,1,6,56,num+14);
                                LCD_Display(c,2,6,64,GetArray(c));
                                break;
                //default :break;
        }        
}

/*----------------AD0808输出数据处理----------------*/
/*-----------测试版,以后根据详细公式更改-----------*/
uint DataProcessing(uint value1,uchar flag)
{        float valuetemp=0;
        uint value = 0;
        valuetemp = value1 * 10;
        switch(flag)//判断flag标志的类型,选择合适的处理公式
        {
                case 1: value = (uint)(valuetemp/256 * 5);
                break;
                case 2: value = (uint)(valuetemp/256 * 5);
                break;
                case 3: value = (uint)(valuetemp/256 * 5);
                break;
                //default :break;
        }
        return value ;
}

/*--------------------LCD函数区--------------------*/
void LCD_LoadPhoto()//LCD图像初始化
{
        InitLCD(); //初始化
        LCD_ClearScreen(0); //清屏
        LCD_SetLine(0); //显示开始行

//画第一行(智能节水控制系统)
        LCD_Display(99,1,0,0*16,CH_zhi);
        LCD_Display(99,1,0,1*16,CH_neng);
        LCD_Display(99,1,0,2*16,CH_jie);
        LCD_Display(99,1,0,3*16,CH_shui);
        LCD_Display(99,2,0,4*16,CH_kong);
        LCD_Display(99,2,0,5*16,CH_zhi2);
        LCD_Display(99,2,0,6*16,CH_xi);
        LCD_Display(99,2,0,7*16,CH_tong);
//画参数区(温度、浊度、水位,初始数据为0)
//绘制温度
        LCD_Display(99,1,2,0*16,CH_wen);
        LCD_Display(99,1,2,1*16,CH_du);
        LCD_Display(13,1,2,2*16,num+13);
        LCD_Display(0,2,2,64,num+0);
        LCD_Display(99,2,2,72,Temper);
//绘制浊度
        LCD_Display(99,1,4,0*16,CH_zhuo);
        LCD_Display(99,1,4,1*16,CH_du);
        LCD_Display(13,1,4,2*16,num+13);
        LCD_Display(0,2,4,64,num+0);
        LCD_Display(11,2,4,72,num+11);
        LCD_Display(12,2,4,80,num+12);
//绘制水位
        LCD_Display(99,1,6,0*16,CH_shui);
        LCD_Display(99,1,6,1*16,CH_wei);
        LCD_Display(13,1,6,2*16,num+13);
        LCD_Display(0,2,6,64,num+0);
        LCD_Display(10,2,6,80,num+10);
//绘制状态区
        LCD_Display(99,2,4,96,CH_zhuang);
        LCD_Display(99,2,4,96+16,CH_tai);

}

void LCD_ReadBusy()//读“忙”函数-----数据线的最高位DB71则busy
{
        LCD_DataBus = 0x00;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_E = 1;
        while(LCD_DataBus&0x80);
        LCD_E = 0;
}
void LCD_WriteCmd(uchar value)//LCD写入命令
{
        LCD_ReadBusy();//每次操作必须检测忙标志
        LCD_RS = 0;
        LCD_RW = 0;
        LCD_DataBus = value;
        LCD_E = 1;
        _nop_();
        _nop_();
        LCD_E = 0;
}
void LCD_WriteData(uchar value)//LCD写入数据
{
        LCD_ReadBusy();
        LCD_RS = 1;
        LCD_RW = 0;
        LCD_DataBus = value;
        LCD_E = 1;
        _nop_();
        _nop_();
        LCD_E = 0;
}
void LCD_SetPage(uchar page)//------设置页,共8页,8行点阵点
{
        page=0xb8|page;//页的首地址是0xb8
        LCD_WriteCmd(page);
}
void LCD_SetLine(uchar line)//------设置显示的起始行,一般从0行开始
{
        line=0xc0|line;            //------起始行地址0xc0
        LCD_WriteCmd(line);
}
void LCD_SetColumn(uchar column)
{
        column=column&0x3f;
        column= 0x40|column;
        LCD_WriteCmd(column);
}
void LCD_SetOnOff(uchar onoff) //显示开关
{
        onoff=0x3e|onoff;
        LCD_WriteCmd(onoff);
}
void LCD_SelectScreen(uchar screen) //选屏
{
        switch(screen)
        {
                case 0: LCD_CS1=0;LCD_CS2=0;break; //全屏
                case 1: LCD_CS1=0;LCD_CS2=1;break;//左半屏
                case 2: LCD_CS1=1;LCD_CS2=0;break;//右半屏
                default:break;
        }
}
void LCD_ClearScreen(uchar screen) //清屏
{
        uchar i,j;
        LCD_SelectScreen(screen);
        for(i=0;i<8;i++)//控制页数0-7,共8 页
        {
                LCD_SetPage(i);
                LCD_SetColumn(0);
                for(j=0;j<64;j++) //控制列数
                {
                        LCD_WriteData(0x00);
                }
        }
}
void InitLCD() //LCD 的初始化
{
        LCD_ReadBusy();
        LCD_SelectScreen(0);
        LCD_SetOnOff(0); //关显示
        LCD_SelectScreen(0);
        LCD_SetOnOff(1); //开显示
        LCD_SelectScreen(0);
        LCD_ClearScreen(0);//清屏
        LCD_SetLine(0); //开始行:0
}
void LCD_Display(uint flag,uchar ss,uchar page,uchar column,uchar *p) //显示汉字OR字母数字,uchar flag是标志位0-汉字,1-字母
{        
        uchar i;
        if(flag==99)
        {
        LCD_SelectScreen(ss);
        LCD_SetPage(page); //写上半页
        LCD_SetColumn(column); //控制列
        for(i=0;i<16;i++) //控制16 列
        {
                LCD_WriteData(p); //汉字的上半部分
        }
        LCD_SetPage(page+1); //写下半页
        LCD_SetColumn(column); //控制列
        for(i=0;i<16;i++) //控制16 列的数
        {
                LCD_WriteData(p[i+16]);//汉字的下半部分
        }
        }
        else
        {
                LCD_SelectScreen(ss);
                LCD_SetPage(page); //写上半页
                LCD_SetColumn(column); //控制列
                for(i=0;i<8;i++) //控制8 列
                {
                        LCD_WriteData(p); //字母的上半部分
                }
                LCD_SetPage(page+1); //写下半页
                LCD_SetColumn(column); //控制列
                for(i=0;i<8;i++) //控制8 列的数
                {
                        LCD_WriteData(p[i+8]);//字母的下半部分
                }
        }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。