找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2489|回复: 5
打印 上一主题 下一主题
收起左侧

数控直流电流源设计方案(不完整)求帮助

[复制链接]
回帖奖励 30 黑币 回复本帖可获得 1 黑币奖励! 每人限 2 次(中奖概率 30%)
跳转到指定楼层
楼主
有木有哪个大佬指导我修改!!!
1)输出电流范围:200mA2000mA
2)可设置并显示输出电流给定值,要求输出电流与给定值偏差的绝对值≤给定值的1+10 mA
3)具有“+”、“-”步进调整功能,步进≤10mA
4)改变负载电阻,输出电压在10V以内变化时,要求输出电流变化的绝对值≤输出电流值的1+10 mA
5)输出电流范围为20mA2000mA,步进1mA
6)设计、制作测量并显示输出电流的装置 (可同时或交替显示电流的给定值和实测值),测量误差的绝对值≤测量值的0.1+3个字;
7)改变负载电阻,输出电压在10V以内变化时,要求输出电流变化的绝对值≤输出电流值的0.1+1 mA
8)另附:源程序
附录2程序清单
;************************************************************                           
;****;在本次课程设计的程序中,我用到的是液晶显示器,其使能***
;****;端接单片机的P3.0P3.1P3.2引脚,用到了DA转换等需要 ***
;****;的暂存单元分别为30H35H,其中还有一些必要的标志位存***
;****;在在36H4AH单元。按键接单片机的P2.0P2.7,液晶显示***                        
;****;显示器数据口接单片机的P0.0P0.7,本数控直流电流源有加 ***                        
;****;减调整,采用闭环控制系统进行调整,精确度更高。                ***
;************************************************************
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit rs=P3^0;     
sbit rw=P3^1;         
sbit lcden=P3^2;    //液晶显示屏相关位定义
sbit AD_OUT=P1^0;
sbit AD_IN=P1^1;
sbit AD_CS=P1^2;
sbit AD_CLOCK=P1^3;
sbit DA_IN=P3^3;
sbit DA_CK=P3^4;
sbit DA_CS=P3^5;
sbit x=P1^4;
uchar code table1[]="Are you sure    ";
uchar code table2[]="      to set I? ";
uchar code table3[]=" ERROR!RESET!   ";
unsigned long int temp0,temp1;
uint ADCdat,i,AD_DAstart;
float Voltage1,Voltage2,r;
int vol,rtt;
uchar set,volarry0[4],volarry1[4],rt[2];
char iset[5]={0,0,2,0,0,};

void led_init();               //函数声明
void delayms(uint z);
void delay(uint t);
void write_com(uchar com);
void write_date(uchar date);
void display_AD();
uint read2543(uchar port);
void Send1456(uint DACdat);
void keyscan();
;************************************************************
;****;                       主程序                              ****
;************************************************************
main()
{
        led_init();
        i=20;
        display_AD();
        Send1456(20);
        while(1)
        {
                keyscan();
                if(AD_DAstart==1)
                {
                        display_AD();
                        Send1456(iset[1]*1000+iset[2]*100+iset[3]*10+iset[4]);
                }
        }
}
void delayms(uint z)  //延时函数,参数为z
{
        uint x,y;
         for(x=z;x>0;x--)
            for(y=110;y>0;y--);  //z=1测试为大约1微秒
}
void delay(uint t)         //极短延时
{
   while(t--);
}
void write_com(uchar com)    //写命令函数
{
        rs=0;        //rs0表示写命令
        lcden=0;       //按时序图置低
        P0=com;        //位声明,按原理图接P0口,输入数据
        lcden=1;     //置高
        delayms(5);       //时序图中须有thd2时间延时
        lcden=0;       //按时序图置低
}
void write_date(uchar date)  //写数据函数
{
        rs=1;      //rs1表示写数据
        lcden=0;     
    P0=date;     //将数据赋到P0
        delayms(5);     
        lcden=1;     
        delayms(5);     
        lcden=0;     
}
void led_init()      //初始化函数
{
        lcden=0;
        rw=0;
        write_com(0x38);    //显示模式设置:16X2显示,5X7点阵,8位数据
        write_com(0x0c);    // 开显示,关光标,光标不闪烁
        write_com(0x06);    // 写一个数据后地址指针加一,光标加一
        write_com(0x01);    // 数据指针及数据清0
        write_com(0x80);    // 设置数据地址指针,第一行        
        write_com(0x80+5);
        write_date(0x6d);
        write_date(0x41);
        write_com(0x80);   
        write_date(0x53);
        write_date(0x30+iset[1]);
        write_date(0x30+iset[2]);
        write_date(0x30+iset[3]);
        write_date(0x30+iset[4]);
}
;************************************************************
;****;              A/D转换子程序                                     ****
;************************************************************
void display_AD()
{
        uchar num;
        temp0+= read2543(0x00);        //进行AD转换
        temp1+= read2543(0x01);
        i--;                                                //20AD转换的结果,求平均值
        if(i==0)
        {        
                ADCdat=temp1/20;
                temp1=0;
                Voltage2=(ADCdat*5.0)/4096; //基准电压为5.0V
                   vol=(int)((Voltage2*4)*1000);// 扩大1000
                volarry1[3]=vol/1000;
                volarry1[2]=vol%1000/100;
                   volarry1[1]=vol%100/10;
                volarry1[0]=vol%10;
                ADCdat=temp0/20;
                temp0=0;
                i=20;
                Voltage1=(ADCdat*5.0)/4096; //基准电压为5.0V
                   vol=(int)(Voltage1*1000+1);// 扩大1000
                   volarry0[3]=vol/1000;
                   volarry0[2]=vol%1000/100;
                   volarry0[1]=vol%100/10;
                volarry0[0]=vol%10;
                write_com(0x80+0x40);
                write_date(0x54);
                write_date(0x30+volarry0[3]);
                write_date(0x30+volarry0[2]);
                write_date(0x30+volarry0[1]);
                write_date(0x30+volarry0[0]);
                write_date(0x6d);
                write_date(0x41);
                if(vol>2000||vol<200||volarry1[3]>10||volarry1[3]==10)
                {
                        write_com(0x01);    // 数据指针及数据清0
                        write_com(0x80);    // 设置数据地址指针,第一行
                        for(num=0;num<16;num++)
                        {
                                write_date(table3[num]);
                                delayms(1);     //循环方式写第一行数据
                        }
                        set=1;
                        AD_DAstart=0;        
                }
                else
                {
                         write_com(0x80+0x40+13);
                         write_date(0x4f);
                         write_date(0x4b);
                         write_date(0x21);
                         write_com(0x80+9);
                         write_date(0x30+volarry1[3]);
                         write_date(0x2e);
                         write_date(0x30+volarry1[2]);
                         write_date(0x30+volarry1[1]);
                         write_date(0x30+volarry1[0]);
                         write_date(0x56);
                         r=Voltage2*4/Voltage1;
                     rtt=(int)(r*10);
                         rt[1]=rtt/10;
                         rt[0]=rtt%10;
                         write_com(0x80+0x49);
                         write_date(0x30+rt[1]);
                         write_date(0x52);
                         write_date(0x30+rt[0]);
                }
        }        
}
;************************************************************
;****;                  D/A转换子程序                                  ****
;************************************************************
uint read2543(uchar port)   //DA转换子程序
{
        uint ad=0,j;
    AD_CLOCK=0;
    AD_CS=0;
    port<<=4;
    delay(50);
    for(j=0;j<12;j++)
    {
                   if(AD_OUT)
        {
                ad=0x01;
        }
        AD_IN=(bit)(port&0x80);
        AD_CLOCK=1;
        delay(6);
        AD_CLOCK=0;
        delay(3);
        port<<=1;
        ad<<=1;
    }
    AD_CS=1;
    ad>>=1;
    return(ad);
}
void Send1456(uint DACdat)
{
        uchar i=0;
        DA_CK=0;
        delay(2);
        DA_CS=0;
        delay(2);
        for(i=0;i<12;i++)
        {
                DA_IN=(bit)(DACdat&0x800);
                DA_CK=1;
                DACdat<<=1;
                DA_CK=0;               
        }
        DA_CS=1;
        DA_CS=0;
}
;************************************************************
;****;              按键键扫子程序                                     ****
;************************************************************
void keyscan()  //矩阵键盘
{
        uchar temp,keycount,num;   // 定义局部变量
        P2=0xfe; // 检测最上面一行各键是否有按键按下
    temp=P2;      // P2口的值赋给temp
    temp=temp&0xf0;     // 位与
    if(temp!=0xf0)     
    {
            delayms(100);
              temp=P2;
             temp=temp&0xf0;   
                  if(temp!=0xf0)    //确认被按下,防止抖动
                  {
                           temp=P2;
                                   switch(temp)
                                   {
                                    case 0xee:       //检测到7被按下
                                         if(keycount!=0)
                                         {
                                                 write_date(0x30+7);
                                                 iset[keycount++]=7;
                                      }
                                         break;
                                    case 0xde:                 //检测到8被按下
                                         if(keycount!=0)
                                         {
                                                 write_date(0x30+8);
                                                 iset[keycount++]=8;
                                         }
                         break;
                                    case 0xbe:                 //检测到9被按下
                                         if(keycount!=0)
                                         {
                                                 write_date(0x30+9);
                                                 iset[keycount++]=9;
                                         }
                                      break;
                                        case 0x7e:                 //检测到取消键被按下
                                     write_com(0x01);    // 数据指针及数据清0
                                         write_com(0x0c);
                                         write_com(0x80+5);
                                         write_date(0x6d);
                                         write_date(0x41);
                                         write_com(0x80);
                                         write_date(0x53);
                                          write_date(0x30+iset[1]);
                                     write_date(0x30+iset[2]);
                                     write_date(0x30+iset[3]);
                                     write_date(0x30+iset[4]);
                                          AD_DAstart=1;               
                           }
                        while(temp!=0xf0)    //松手检测
                           {
                            temp=P2;
                            temp=P2&0xf0;
                           }
                }
        }
        P2=0xfd; // 检测最二行各键是否有按键按下
    temp=P2;      // P2口的值赋给temp
    temp=temp&0xf0;     // 位与
    if(temp!=0xf0)     
    {
            delayms(100);
              temp=P2;
             temp=temp&0xf0;   
                  if(temp!=0xf0)    //确认被按下,防止抖动
                  {
                           temp=P2;
                           switch(temp)
                           {
                            case 0xed:       //检测到4被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+4);
                                         iset[keycount++]=4;
                                 }
                              break;
                            case 0xdd:                 //检测到5被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+5);
                                         iset[keycount++]=5;
                                 }
                 break;
                            case 0xbd:                 //检测到6被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+6);
                                         iset[keycount++]=6;
                              }
                                 break;
                                case 0x7d:                 //检测到+被按下
                                 iset[4]++;
                                 if(iset[4]==10)
                                 {
                                          iset[4]=0;
                                         iset[3]++;
                                         if(iset[3]==10)
                                         {
                                                 iset[3]=0;
                                                iset[2]++;
                                                if(iset[2]==10)
                                                {
                                                        iset[2]=0;
                                                        iset[1]++;
                                                }
                                         }
                                 }
                                 write_com(0x80+5);
                                 write_date(0x6d);
                                 write_date(0x41);
                                 write_com(0x80);
                                 write_date(0x53);
                                 write_date(0x30+iset[1]);
                                 write_date(0x30+iset[2]);
                                 write_date(0x30+iset[3]);
                                 write_date(0x30+iset[4]);
                                 AD_DAstart=1;
                                 break;               
                           }
                        while(temp!=0xf0)    //松手检测
                           {
                            temp=P2;
                            temp=P2&0xf0;
                           }
                }
        }
        P2=0xfb; // 检测第三行各键是否有按键按下
    temp=P2;      // P2口的值赋给temp
    temp=temp&0xf0;     // 位与
    if(temp!=0xf0)     
    {
            delayms(100);
              temp=P2;
             temp=temp&0xf0;   
                  if(temp!=0xf0)    //确认被按下,防止抖动
                  {
                           temp=P2;
                           switch(temp)
                           {
                            case 0xeb:       //检测到1被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+1);
                                         iset[keycount++]=1;
                              }
                                 break;
                            case 0xdb:                 //检测到2被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+2);
                                         iset[keycount++]=2;
                                 }
                 break;
                            case 0xbb:                 //检测到3被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30+3);
                                         iset[keycount++]=3;
                                 }
                              break;
                                case 0x7b:                  //检测到-被按下
                                 iset[4]--;
                                 if(iset[4]==-1)
                                 {
                                          iset[4]=9;
                                         iset[3]--;
                                         if(iset[3]==-1)
                                         {
                                                 iset[3]=9;
                                                iset[2]--;
                                                if(iset[2]==-1)
                                                {
                                                        iset[2]=9;
                                                        iset[1]--;
                                                }
                                         }
                                 }
                                 write_com(0x80+5);
                                 write_date(0x6d);
                                 write_date(0x41);
                                 write_com(0x80);
                                 write_date(0x53);
                                 write_date(0x30+iset[1]);
                                 write_date(0x30+iset[2]);
                                 write_date(0x30+iset[3]);
                                 write_date(0x30+iset[4]);
                                 AD_DAstart=1;
                                 break;               
                           }
                        while(temp!=0xf0)    //松手检测
                           {
                            temp=P2;
                            temp=P2&0xf0;
                           }
                }
        }
        P2=0xf7; // 检测第四行各键是否有按键按下
    temp=P2;      // P2口的值赋给temp
    temp=temp&0xf0;     // 位与
    if(temp!=0xf0)     
    {
            delayms(100);
              temp=P2;
             temp=temp&0xf0;   
                  if(temp!=0xf0)    //确认被按下,防止抖动
                  {
                           temp=P2;
                           switch(temp)
                           {
                            case 0xe7:       //检测到0被按下
                                 if(keycount!=0)
                                 {
                                         write_date(0x30);
                                         iset[keycount++]=0;
                                 }
                              break;
                            case 0xd7:                 //检测到删除键被按下
                                if(keycount<5&&keycount>0)
                                 {
                                         if(keycount!=1)
                                         keycount--;
                                        write_com(0x80+keycount);
                                 }
                 break;
                            case 0xb7:                 //检测到确认键被按下
                                 if(set==1)
                                 {
                                         write_com(0x01);    // 数据指针及数据清0
                                        write_com(0x80+5);
                                        write_date(0x6d);
                                        write_date(0x41);
                                        write_com(0x80);
                                        write_date(0x53);
                                        write_com(0x0f);
                                        write_com(0x80+1);
                                        set=0;
                                        keycount=1;
                                 }
                              break;
                                case 0x77:
                                 write_com(0x01);    // 数据指针及数据清0
                                 write_com(0x80);    // 设置数据地址指针,第一行
                                 for(num=0;num<16;num++)
                                         {
                                                write_date(table1[num]);
                                                delayms(1);     //循环方式写第一行数据
                                        }
                                 set=1;
                                 write_com(0x80+0x40);    // 设置数据地址指针,第二行
                                 for(num=0;num<16;num++)
                                         {
                                                write_date(table2[num]);
                                                delayms(1);     //循环方式写第二行数据
                                        }
                                 AD_DAstart=0;
                                 break;     
                           }
                        while(temp!=0xf0)    //松手检测
                           {
                            temp=P2;
                            temp=P2&0xf0;
                           }
                }
        }
        if(keycount==5)
        {
                keycount=0;
                AD_DAstart=1;
            write_com(0x0c);         
         }
}

one.png (95.37 KB, 下载次数: 54)

不完整

不完整

数控直流电流源设计方案.doc

968 KB, 下载次数: 14

不完整

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:328014 发表于 2020-9-29 23:37 | 只看该作者
你遇到的问题是什么?
回复

使用道具 举报

板凳
ID:530559 发表于 2020-10-4 20:52 | 只看该作者
51hei团团 发表于 2020-9-29 23:37
你遇到的问题是什么?

就是OP37的4和7引脚要分别接什么,或者说要怎么接?
回复

使用道具 举报

地板
ID:530559 发表于 2020-10-4 20:53 | 只看该作者
51hei团团 发表于 2020-9-29 23:37
你遇到的问题是什么?

就是OP37的4和7引脚要怎么接?
回复

使用道具 举报

5#
ID:155507 发表于 2020-10-4 21:01 | 只看该作者
OP37的4和7引脚要接电源,怎么接不知道
回复

使用道具 举报

6#
ID:692132 发表于 2020-10-4 21:06 来自手机 | 只看该作者
sener201314 发表于 2020-10-4 20:52
就是OP37的4和7引脚要分别接什么,或者说要怎么接?

那个一看就是运算放大器的供电端
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表