专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

电赛—简易直流稳压电源(源代码)

作者:肖邦   来源:本站原创   点击数:  更新时间:2014年03月08日   【字体:
小弟学艺不精!请多多包涵!!!分享下源代码有很多可以调用的函数,,,,谢谢     ADC0832与DAC0832处理数据。
/*****************************************************************
*************作者:张通  *****************************************
*************信息工程学院*****************************************
*************简易直流稳压代码*************************************
******************************************************************/
#include"reg52.h"
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define WR WR2
#define DAT P0
sbit K1=P3^1;
sbit K2=P3^2;
sbit K3=P3^3;
sbit CS=P2^5;     //片选信号
sbit SID=P2^2;  //数据信号
sbit SCLK=P2^1;  //时钟信号
sbit RST=P2^2;  //复位信号
sbit CH = P2^0;  //并行、串行选择信号
sbit clk0832=P3^6;
sbit DI0832=P3^4;
sbit DO0832=P3^5;
sbit ADCS=P3^7;
sbit WR=P2^6;
bit _Int=0;
bit state;
bit k=0;
bit m=0;
bit q=0;
bit fushu=0;
uint Ch0value,Ch1value;
uint x;
uchar ADdat;
uchar result;
uchar kyreg;
uchar go;
uint DAdat;
uchar hh;
uchar temp;     //存放功能状态 
void hzkdis(unsigned char code *s);
void delayms(int z)
{
 int x,y;
 for(x=z;x>0;x--)
 for(y=115;y>0;y--);
}
void delay(uint t)
{
 uint i,j;
 for(i=0; i<t;  i++)
    for(j=0; j<10; j++);
}
/**********
*读数值
***********/
uchar keyread()
{
 uchar kysta=1;//按键标志,kysta=1无按键
 while(kysta)//锁定P3口低三位
 {
  P3=0X0e;
  kyreg=P3;
  if(kyreg!=0x0e)
  {
  delay(20);
  kyreg=P3;
  if(kyreg!=0x0e)
  {
  if(kyreg==0x0c)return 11;     //第一个键
  if(kyreg==0x0a)return 12;     //第二个键
  if(kyreg==0x06)return 13;     //第三个键
   }
  }
    while(kyreg!=0x0c)//键复位
    {
      P3=0X0e;
   kyreg=P3;
    }
 }
}
uchar keyread2()
{
 if(K2==0)           //KEY键实现数据增加
 {
//  WR2=1;
//  delay(50);
//  WR2=0;
  if(K2==0)      //第二个键按下
  delay(50);     //P1口数值加1
  P0=go;
  go++;
  while(!K2);
 }
}
uchar keyread3()
{
 if(K3==0)//KEY3键实现数据减少
 {
//  WR2=1;
//  delay(50);
//  WR2=0;
  if(K3==0);//第三个键按下
  delay(50);
  P0=go;
  go--;//P1口数值减1
  while(!K3);
 }
}
/***********************
*ADC0832数据处理函数
***********************/
 uchar ADC0832(uchar channel)
{uchar i=0;
uchar j;
 uint dat=0;
 uchar ndat=0;
 if(channel==0)channel=2;
 if(channel==1)channel=3;
DI0832=1;        //DI为1  
 _nop_();    //延时两个指令周期  
 _nop_();    
 ADCS=0;    //拉低cs,选通;确定数据输入开始  
 
    clk0832=1;     //时钟信号为高 
  _nop_();
    _nop_(); 
    clk0832=0;     //时钟信号为低,此处为第一个下降沿 
  _nop_();    
_nop_(); 
    clk0832=1;     //时钟信号为高  
DI0832=channel&0x1;// 这句? 
  _nop_();     _nop_();   
  clk0832=0;     //时钟信号为低,此处为第二个下降沿 
  _nop_();
    _nop_();   
  clk0832=1;      //时钟信号为高  
 DI0832=(channel>>1)&0x1; //   ?
   _nop_();  
  _nop_();
 clk0832=0;       //时钟信号为低,此处为第三个下降沿
   DI0832=1;        //DI为1  
 _nop_();  
  _nop_();
    dat=0; 
   for(i=0;i<8;i++) 
   {      
  dat|=DO0832;//这句?      
   clk0832=1;     
   _nop_();
_nop_();     
    clk0832=0;//形成一次时钟脉冲  
      _nop_(); 
       _nop_();  
      dat<<=1;
        if(i==7) dat|=DO0832;
    }      
for(i=0;i<8;i++)  
  {         j=0;   
     j=j|DO0832;  
       clk0832=1;     
   _nop_();        
_nop_();   
      clk0832=0;//形成一次时钟脉冲  
      _nop_();     
   _nop_();    
    j=j<<7;    
    ndat=ndat|j;  
      if(i<7)ndat>>=1; 
   }   
ADCS=1;  //拉高CS端  
  clk0832=0;//拉低CLK端 
  DO0832=1;//拉高数据端回到初始状态 
  dat<<=8;    
dat|=ndat;
    return(dat);            //return ad k      
   }
/**********
*DAC送数
**********/
void seDAC(uchar DAdat)
{
 WR=1;
 _nop_();
 _nop_();
 DAT=DAdat;
 WR=0;
  _nop_();
 _nop_();
 WR=1;
}
/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(unsigned char zdata)
{
 unsigned int h;
 for(h=0; h<8; h++)
 {
  if((zdata << h) & 0x80)
  {
   SID = 1;
  }
  else
  {
   SID = 0;
  }
  SCLK = 0;
  SCLK = 1;
 }
}
/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)
{
 CS = 1;
 sendbyte(0xf8);
 sendbyte(cmdcode & 0xf0);
 sendbyte((cmdcode << 4) & 0xf0);
 delay(2);
}
/********************************************************************
* 名称 : write_data()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_data(unsigned char Dispdata)
{
 CS = 1;
 sendbyte(0xfa);
 sendbyte(Dispdata & 0xf0);
 sendbyte((Dispdata << 4) & 0xf0);
 delay(2);
}
/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit()

 RST = 0;
 delay(100);
 RST = 1;
 delay(20000);
 write_com(0x30);
 delay(50);
 write_com(0x0c);
 delay(50);
 write_com(0x03);
 delay(50);   
 
}
/********************************************************************
* 名称 : hzkdis()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void hzkdis(unsigned char code *s)

 while(*s > 0)
    {
  write_data(*s);
  s++;
  delay(50);
    }
}
void Test()

 write_com(0x03);
 delay(50);   
 write_com(0x80);
 hzkdis("简易直流稳压电源");
// write_com(0x90);
// hzkdis("V=00.0v  A=00.0a ");
 write_com(0x98);
 hzkdis("张通  干顺  颜炜");;
//    write_com(0x98);
// hzkdis("  12级电子18班  ");
}
void writeNumber(uchar row,uchar rank,uint s)

  uchar addr;
  switch(row)
  {
    case 0:addr=0x80;break;
    case 1:addr=0x90;break;
    case 2:addr=0x88;break;
    case 3:addr=0x98;break;
  }
  write_com(0x80);
  hzkdis("简易直流稳压电源");  
  write_com(addr+rank);
  write_data('V');
  write_data('=');
  write_data(s/10000+'0');
  write_data(s%10000/1000+'0');
  write_data(s%1000/100+'0');
  write_data(s%100/10+'0');
   write_data(s%10+'0');
  write_data('m');
   write_data('v');
//  write_data(' ');
//  write_data(' ');
//  write_data('A');
//  write_data('=');
//  write_data(y/100+'0');
//  write_data(y%100/10+'0');
//  write_data('.');
//  write_data(y%10+'0');
//  write_data('a');
 }
 void writeNumber1(uchar row,uchar rank,uint s)

  uchar addr;
  switch(row)
  {
    case 0:addr=0x80;break;
    case 1:addr=0x90;break;
    case 2:addr=0x88;break;
    case 3:addr=0x98;break;
  }
  write_com(0x80);
  hzkdis("简易直流稳压电源");  
  write_com(addr+rank);
  write_data('A');
  write_data('=');
  write_data(s/10000+'0');
  write_data(s%10000/1000+'0');
  write_data(s%1000/100+'0');
  write_data(s%100/10+'0');
   write_data(s%10+'0');
  write_data('m');
   write_data('a');
  }
//void display()
//{
//writeNumber(1,1,Ch0value);
//
//}
///*********输出电压自增自减程序***********/
//void volchange()
//{
// uchar i,a,b,c,y,z;
//    if(temp==1&&(DAdat<511))
// {
//  if(q)
//  {
//   if(z==9)
//   {
//    DAdat+=3;z=0;
//   }              //进位
//   else DAdat+=2;
//  }
//  else DAdat+=3;
//  z++;
//  if(DAdat>=129)
//  {
//   Ch0value=Ch0value+1;
////   lcdcmd(0x80);
////   lcddata("V=0000mvA=0000ma");
////   c=x/100,a=x%100/10;
////   b=x%10;                                                //一位小数,个位,十位的运算
////   lcdcmd(0x90);
////   for(i=0;i<8;i++)
////   lcddata("V");                                    //电压显示
////   lcddata(Disp[c]);
////   lcddata(Disp[a]);
////   lcddata(".");
////   lcddata(Disp[b]);
////   lcddata("mv");
//         writeNumber(1,0, Ch0value*0.742); 
//   }
//   else if(temp==2&&(DAdat>1))
//   {
//   if(q)
//   {
//    if(y==9){DAdat-=3;y=0;}//借位
//    else DAdat-=2;
//   }
//   else
//   DAdat-=3;
//   y++;
//   if(DAdat>127)
//   {
//    Ch0value=Ch0value-1;
////    c=x/100,a=x%100/10;b=x%10;//一位小数,个位,十位的运算
////    lcdcmd(0x90);
////    for(i=0;i<8;i++)
////    lcdcmd("V=");//电压显示
////    lcdcmd(Disp[c]);
////    lcdcmd(Disp[a]);
////    lcdcmd('.');
////    lcdcmd(Disp[b]);
//                writeNumber(1,0, Ch0value*0.742);   
//   }
//
//  }
// hh=0;
// }
// }
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{     uchar A=0;
//  WR=1;
 EA=1;
 EX0=1;
// PX0=1;
 IT0=1;
    EX1=1;
    IT1=1;
// unsigned int vol;
// uchar i,j,l=0,a=0,b=0,e=0;
// bit dian=0; 
// bit o=0,p=0;   //负数标志位,确认标志位
// pp: a=b=0;dian=0;o=p=0,x=0;
//  P1=0;
 P0=0xff;
 CH = 0;
 delay(1);
 lcdinit();
 delay(10);
 Test();
  while(1)
  {
  //if((P3^1==0)&&(A==0))
 // {
   
 
 // }
    Ch0value=ADC0832(0);
  
 Ch1value=ADC0832(1);
 
  
//  if(!K)
//  {
//  for(i=0;i<10;i++)
//  {
//     Ch0value=ADC0832(0);
//  delayms(50);
//  n=n+Ch0value;
//  K=1;
// 
//  }
//  }
// 
//  m=n/10;
//  Ch0value=m;
// 
 if(DAT>Ch0value)//输出值大于显示值
 {
  result=DAT-Ch0value;//输出值减显示值
  state=0;
 }
    else
    {
     result=Ch0value-DAT;//显示值减输出值
     state=1;
    }
    if (result>=2)
    {
     result/=2;
     if(state)result=Ch0value-result;
     else result=Ch0value+result;
    }
    else result=Ch0value;
    _Int=1;
// Ch1value=ADC0832(1);
// delayms(50);
// Ch1value=read0832(1);
// delayms(50);
//Ch0value=Ch0value*3.922;
 writeNumber(1,0, Ch0value*79);
 writeNumber1(2,0, Ch1value/4.5);
         
// while(!k)
//   {
//    delay(200);
//    i=keyread();
   /* if(!m)
    {
     //lcdcmd(0x1);
     for(j=0;j<7;j++)
     //lcddata(0x90);
     m=1;
//       }*/
//    if(i==11){m=0;goto pp;}//复位
//    else if(i==12){temp=1;k=1;q=!q;hh=1;;}//加1
//     else if(i==13){temp=2;k=1;q=!q;hh=1;;}//减1
//
//  }
//  if(vol>100)
//  {
//   lcdcmd(0x01);//显示清0,数据指针清0
//   delay(2);
//   write_cmd(0x80);//从第一个位写数据
//      lcdcmd("V=0000mvA=0000ma");
//   p=1;//溢出标志,P=1溢出
//  }
//  if(!fushu&&!hh)//送入DAC的数字量
//  {
//   DAdat=256*vol/150+128;
//   if(DAdat==512)
//   DAdat=511;hh=0; 
//  }
//  else if(fushu&&!hh)
//  {
//   DAdat=256-256*vol/150;
//   fushu=0;
//   hh=0;
//  }
//  if((temp==0)&&(!p))
//  seDAC(DAdat);   //函数调用
//  else if(temp==1)
//  {
//   volchange();
//   seDAC(DAdat);
//   keyread2();
//   temp=0;
//  }
//  else if(temp==2)
//  {
//   volchange();
//   seDAC(DAdat);
//   keyread3();
//   temp=0;
//  }
//  p=0;
//  k=0;
//  }
  }
// delay(5000);
//    while(!k)
//    {
//     delay(200);
//   i=keyread();
//   if(!m) ;
 }  
   
//
void reADC() interrupt 2
{
 uchar result;
 bit state;
 DAT=0x80;
 ADdat=DAT;
 _nop_();
 _nop_();
 if(ADdat>DAdat)//输出值大于显示值
 {
  result=ADdat-DAdat;//输出值减显示值
  state=0;
 }
    else
    {
     result=DAdat-ADdat;//显示值减输出值
     state=1;
    }
    if (result>=2)
    {
     result/=2;
     if(state)result=DAdat-result;
     else result=DAdat+result;
    }
    else result=DAdat;
    _Int=1;
}
/******************
*反馈比较
*******************/
uchar cmp(uchar x,uchar y)
{
uchar result;
bit state;
if(x>=y)
{
 result=x-y;
 state=0;
}
else
{
result=y-x;
state=1;
}
if(result>=2)
{
 result/=2;
 if(state)result=y-result;
 else result=y+result;
}
else result=y;
return (result);
}
void keyzj()interrupt 2
{
 DAT-=0.7;
 delay(200);
}
void keyjs()interrupt 1
{
 DAT+=1;
  delay(200);
}
关闭窗口

相关文章