5849|0

1

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

单片机LCD1602显示程控测量放大器 [复制链接]

  因为这学期的课程设计我做了这个测量放大器,并且给他加上了单片机的功能以及串行通信的功能,可以说是非常全面的。

刚开始的时候是放大1000倍,然后放大1000倍的数值可以在单片机中显示。然后我们通过第一模块对他进行筛检,并且通过五个按键实现零到1000倍的衰减衰减后再通过D A C输出。整个过程,我们在测量放大器的基础上做了很多的改进单片机程序相对复杂,然后再试相比来说我们用了七天的时间。还是挺成功的

总体电路图

对应的单片机部分程序:

#include<reg51.h>
#include "lcd.h"
#include<absacc.h>
#define DAC1208 XBYTE[0X7FFF]
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

sbit k2 = P3^2;
sbit k3 = P3^3;
sbit k4 = P3^4;
sbit k5 = P3^5;
sbit relay=P2^4;
sbit relayAD=P3^7;

char temp=-1;
int cent;
ulong volt;//测量的电压值
ulong sum;
uchar mode,a,b,y=0,t=0,y1=0,t1=0,y2=0,t2=0,abs=5;
uchar KEY_Scan(uchar mode);
uchar timebit[5],multiplebit[5];
uchar vol_buf[7],multiple_buf[5],out_buf[7];
uint multiple=500;
char time=-1;
void delay1us(uint i);
void communication();
void kai_display();
void kai_display1();
void count();
void display1();
void display();

uint vtime;    // 用来控制测量地址位的改变
uchar addr;//测量地址位,指示测量的是哪一个模拟值 (其实就是TLC2543的控制字)


sbit CLK=P2^3;//定义时钟信号口
sbit DIN=P2^1;//定义2543数据写入口
sbit DOUT=P2^0;//定义2543数据读取口
sbit CS=P2^2;//定义2543片选信号口

void delay1us(uint i)
{
    while(i--);
}
/**********************************************************/
//函数名:read2543(uchar addr)
//功能:2543驱动程序
//调用函数:
//输入参数:addr
//输出参数:
//说明:进行ad转换将结果存于volt变量中 addr为测量位地址
/**********************************************************/
void read2543(uchar addr) //读取数值volt是被缩小两倍的电压
{
    uint ad=0;
    uchar i;
    CLK=0;
    CS=0;//片选段,启动2543
    addr<<=4;//对地址位预处理
    for(i=0;i<12;i++) //12个时钟走完,完成一次读取测量
    {
        if(DOUT==1)
            ad=ad|0x01;//单片机读取ad数据
        DIN=addr&0x80;//2543读取测量地址位
        CLK=1;
        ;;;//很短的延时
        CLK=0;//产生下降沿,产生时钟信号
        ;;;
        addr<<=1;
        ad<<=1;//将数据移位准备下一位的读写
    }
    CS=1;//关2543
    ad>>=1;
    volt=ad;//取走转换结果
    volt=volt*1221*2;//例子的满量程为5V,转换分辩率为12位(2的12次方=4096) 。即最大值是255,5/4096=1221mV,即例子中的1V代表实际1221mV        
}

void communication()
{
    if(RI != 0)
              {
              RI = 0;    //接收收据后进行清0
              temp = SBUF;      //读取数据存入temp中
              }
              if(temp==0)
              {                  
                time=0;//选择相应的指令
                abs=0;
                temp=-1;
              }
              else if(temp==1)
              {              
                time=1;
                abs=1;
                temp=-1;
              }
               else if(temp==2)
              {               
                time=2;
                abs=2;
                temp=-1;
              }
              else if(temp==3)
              {                
                time=3;
                temp=-1;
              }
              else if(temp==4)
              {
                time=4;
                temp=-1;
              }
}
#define  K0  0
#define  K1_MODE  1
#define  K2_ADD  2
#define  K3_DEC  3
#define  K4 4
uchar KEY_Scan(uchar mode)
{
    uchar key=1;
    if(key&&(time>=0&&time<=4))
    {
        key=0;
        if(time==0)
        {
             return K0;
        }
        else if(time==1)
        {
            return K1_MODE;
        }
        else if(time==2)
        {
            return K2_ADD;
        }
        else if(time==3)
        {
            return K3_DEC;    
        }
        else if(time==4)
        {
            return K4;    
        }
    }
    else if(time>=5&&time<=-1)
    {
        key=1;    
    }
    if(a)
    {
        key=1;
    }
    return 5;    
}

void kai_display()
{
    LCD_Dispstring(0,0,"WangZheng And");
    LCD_Dispstring(0,1,"GuoXuKang's Work");
}

void kai_display1()
{
    uchar key;
    key=KEY_Scan(0);
    if(key==K4||b==K4)   //模式选择    直流
    {
            relay=1;
            relayAD=1;
            display();
            b=K4;    //便于按一次直流,之后一直是直流
            LCD_Dispstring(2,0,"DIR:       V");
            LCD_Dispstring(0,1,"M:    O:       V");            
    }
    if(key==K3_DEC||b==K3_DEC) //交流档位
    {
            relay=0;
            relayAD=0;
            display1();
            b=K3_DEC;
            LCD_Dispstring(2,0,"ALT:       V");
            LCD_Dispstring(0,1,"M:    O:       V");    
    }
}
void display()//直流显示
{
    ulong invol;
    float ivol;
    count();
    ivol=(volt*1.000*multiple)/1000;
    invol=(long)ivol;
    vol_buf[0]=volt/10000000+0x30; 
    vol_buf[1]=volt/1000000+0x30;  
    vol_buf[2]='.';
    vol_buf[3]=(volt/100000)%10+0x30;
    vol_buf[4]=(volt/10000)%10+0x30;
    vol_buf[5]=(volt/1000)%10+0x30;
    vol_buf[6]='\0';

    multiple_buf[0]=multiple/1000+0x30; 
    multiple_buf[1]=multiple/100%10+0x30;  
    multiple_buf[2]=multiple/10%10+0x30;
    multiple_buf[3]=multiple%10+0x30;
    multiple_buf[4]='\0';

    out_buf[0]=invol/10000000+0x30; 
    out_buf[1]=invol/1000000+0x30;  
    out_buf[2]='.';
    out_buf[3]=(invol/100000)%10+0x30;
    out_buf[4]=(invol/10000)%10+0x30;
    out_buf[5]=(invol/1000)%10+0x30;
    out_buf[6]='\0';

    LCD_Dispstring(6,0,vol_buf);
    LCD_Dispstring(2,1,multiple_buf);
    LCD_Dispstring(8,1,out_buf);
}
void display1()//交流显示
{
    ulong invol,trans;
    float ivol;
    count();
    trans=volt*0.825;
    ivol=(volt*0.825*multiple)/1000;
    invol=(long)ivol;
    vol_buf[0]=trans/10000000+0x30; 
    vol_buf[1]=trans/1000000+0x30;  
    vol_buf[2]='.';
    vol_buf[3]=(trans/100000)%10+0x30;
    vol_buf[4]=(trans/10000)%10+0x30;
    vol_buf[5]=(trans/1000)%10+0x30;
    vol_buf[6]='\0';

    multiple_buf[0]=multiple/1000+0x30; 
    multiple_buf[1]=multiple/100%10+0x30;  
    multiple_buf[2]=multiple/10%10+0x30;
    multiple_buf[3]=multiple%10+0x30;
    multiple_buf[4]='\0';

    out_buf[0]=invol/10000000+0x30; 
    out_buf[1]=invol/1000000+0x30;  
    out_buf[2]='.';
    out_buf[3]=(invol/100000)%10+0x30;
    out_buf[4]=(invol/10000)%10+0x30;
    out_buf[5]=(invol/1000)%10+0x30;
    out_buf[6]='\0';

    LCD_Dispstring(6,0,vol_buf);
    LCD_Dispstring(2,1,multiple_buf);
    LCD_Dispstring(8,1,out_buf);

}

void count()
{
    if(multiple<=999&&multiple>=0)
    {
       if(abs==0)
       {
         multiple++;
         if(multiple%10==9||t==1)
         {
             y++;
            t=1;   //到9后下一次变为0
            if(y==2)
            {
            t=0;
              multiple=multiple-10;
            y=0;
            }
         }
          
        abs=5;
       }
       if(abs==1)
       {
           multiple=multiple+10;
          if((multiple/10%10==9)||t1==1)
         {
             y1++;
            t1=1;
            if(y1==2)
            {
            t1=0;
              multiple=multiple-100;
            y1=0;
            }
         }
        abs=5;
       }
       if(abs==2)
       {  
        multiple=multiple+100;
         if((multiple/100==9)||t2==1)
         {
             y2++;
            t2=1;
            if(y2==2)
            {
            t2=0;
              multiple=multiple-1000;
            y2=0;
            }
         }
         abs=5;
       }
    }
    if(multiple<0)//y用来监视从1减小,然后维持,最小为0
    {
       multiple=0;
    }
    if(multiple>999)//y用来监视从1减小,然后维持,最小为0
    {
       multiple=999;
    }
}

void main(void)
{
       LCD_Init(); //LCD初始化
        kai_display();//最初显示
        delay1us(50);
        LCD_Clear();//清除

        TMOD = 0x22;     //设置定时器T1为方式2
       TH1 = 0xfd;          
       TL1 = 0xfd;
       TH0=0x06;
        TL0=0x06;
        EA=1;
        ET0=1;
        TR0=1;
       SCON = 0x50;      //设置串口为方式1接收,REN = 1
       PCON = 0x00;      //SMOD = 0;,波特率不加倍
       TR1 = 1; //开启定时器T1
       TI = 1;
       relay=0;
       relayAD=0;
       while(1)
       {
               read2543(addr);//调用2543驱动程序测量地址为0
          communication(); 
           kai_display1();
       }
}
void DA_OUT(int i)
{
    int num,num1,num2;
    num=i*4.099*8;
    num=num>>3;
    num1=num>>8;
    num2=num&0xff;
    DAC1208=num2;
    k2=num1&0x01;
    k3=num1&0x02;
    k4=num1&0x04;
    k5=num1&0x08;
}
void f1 () interrupt 1
{
     cent++;
    if(cent==5000)
    {
         cent=0;
        DA_OUT(multiple);
    }
}

数字电路与FPGA课程设计.zip

253.11 KB, 下载次数: 5

此帖出自电子竞赛论坛
点赞 关注(1)
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表