⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demo.c

📁 单片机实现直流数控稳压电源,可调电压为0-9.9伏,步进为0.1伏,可以自动扫描键盘以增加或者减少电压
💻 C
字号:
/**************************************************************************************************

  项目名称:		  简易数控直流电源

  设计任务:设计出有一定输出电压范围和功能的数控电源.

  设计要求:
					1.基本要求
      (1)输出电压:范围0~+10V,步进1V,纹波不大于10mV;
	  (2)输出电流:500mA;
	  (3)由"+","-"两键分别控制输出电压步进增减;

					2.发挥部分
	  (1)输出电压步进可达到0.1V并可预置在0~9.9V之间的任意一个值;
	  (2)输出电压值由数码管显示;
	  (3)采用单片机控制,用自动扫描代替人工按键,实现输出电压变化.

  
  键盘按键盘说明:16号键-------------设定初值键;
				 0~9号键------------数字键;
				 11号键-------------复位键;
				 13号键-------------加法键,步进0.1V,长按时自动增加0.1V到松开为止;
				 12号键-------------减法键,步进0.1V,长按时自动减少0.1V到松开为止.



  项目开发者:  张运福   ,   蔡龙    ,王珂

  项目开发时间    2005 年 05 月 20 日    到  2005 年 05 月 21日 

***************************************************************************************************/

#include <reg51.H>
sbit CS=P1^0;
sbit CLK=P1^1;
sbit DIO=P1^2;
sbit AD_OK=P3^2;
char KeyCode;
char dispbuff[8];
unsigned char adconvert(char channel);
char ReadKeyCode();
char ReadKB();
void sent(unsigned char sent_buf);
void delay(unsigned int time);
void display();
char TICK;
unsigned char ADresult;
char xdata *DAResult=0x6000;
char ResetBuff[2]={0x00,0x00};
char flag=0x00;
char MidKeyCode=0x00;

/******************************************************************
函数名称:unsigned char DASource()
函数功能:将数字量转换成模拟量
入口参数:无
出口参数:MidDAresult     DA转换所需的中间数据
全局变量:ResetBuff
调用模块:main
******************************************************************/

unsigned char DASource()
{
  unsigned char MidDAresult;
  MidDAresult=(ResetBuff[0]*10+ResetBuff[1])*5.12;
  return MidDAresult;
}

/******************************************************************
函数名称:char adconvert(char channel)
函数功能:将模拟量转换为数字量
入口参数:char channel AD转换的通道
出口参数:char result 转换结果
全局变量:sbit AD_OK=p3^2;
调用模块:void Timer0() interrupt 1
		 main()
******************************************************************/

unsigned char adconvert(char channel)
{
   unsigned char result;
   char xdata *adport;
   adport=0x0000+channel;                          //AD转换通道选择
   *adport=0;                                      //启动转换
   while(AD_OK==1);                                //等待转换结束
   result=*adport;                                 //读转换结果
   return result;
}

/******************************************************************
函数名称:void Timer0() interrupt 1
函数功能:定时中断
入口参数:无
出口参数:无
全局变量:TICK
调用模块:
******************************************************************/

void Timer0() interrupt 1
{
   TMOD=0x01;                                        //定时器初始化
   TH0=0x3c;
   if(TICK==15)
   {
    display();
	TICK=0;
    
	}
	TICK++;
}

/******************************************************************
函数名称:void KeyBoard() interrupt 2
函数功能:按键后产生中断,如果按下的是11号键,则复位,否则标志位+1
入口参数:无
出口参数:无
全局变量:KeyCode
 		 ResetBuff
		 dispbuff
		 flag;
调用模块:
******************************************************************/

void KeyBoard() interrupt 2
{  
   KeyCode=ReadKB();
   if(KeyCode==0x0b)                           //判断是否为11号复位键
   {
     ResetBuff[0]=0x00;
	 ResetBuff[1]=0x00;
     dispbuff[0]=ResetBuff[0]%16;
	 dispbuff[1]=ResetBuff[1]%16;
	 flag=0x00;
   }
   else flag++;
}

/******************************************************************
函数名称:char ReadKB()
函数功能:按键的处理
入口参数:无
出口参数:kb 按下的一个键
全局变量:CS
 		 CLK
调用模块:KeyBoard
******************************************************************/

char ReadKB()
{  char kb=0;
   kb=ReadKeyCode();
   ET0=1;
   return(kb);
}

/******************************************************************
函数名称:char ReadKeyCode()
函数功能:加/减的处理
入口参数:无
出口参数:char RKC 键位代码
全局变量: CS
 		  CLK
		  DIO
调用模块:ReadKeyCode
		 ReadKB 
******************************************************************/

char ReadKeyCode()
{
   char RKC=0x00,i;	
   CS=1;
   CLK=0;
   delay (50);
   sent(0x15);                                    //发送读键盘指令
   delay(10);

   DIO=1;
   CLK=1;
   delay(50);
   for(i=0;i<8;i++)
   {
     CLK=0;
     RKC=RKC*2+(char)DIO;                         //读1位数据
     delay(10);
     CLK=1;
     delay(10);
   } 
   CS=1;
   if(RKC==0x0c)                                 
	       {
            if(ResetBuff[1]==0x00)
                if(ResetBuff[0]==0x00)
				   ;
                else
	               {ResetBuff[1]=0x09; ResetBuff[0]--;}
	        else ResetBuff[1]--;
			dispbuff[0]=(ResetBuff[0]%16)|0x80;
            dispbuff[1]=ResetBuff[1]%16;
            display();
			delay(10000);
			RKC=ReadKeyCode();          
		 }
   else if(RKC==0x0d)
        {
		 if(ResetBuff[1]==0x09)
             if(ResetBuff[0]==0x04)
				;
             else
	            { ResetBuff[1]=0x00; ResetBuff[0]++;	}
	     else ResetBuff[1]++;
		 dispbuff[0]=(ResetBuff[0]%16)|0x80;
         dispbuff[1]=ResetBuff[1]%16;
         display();
		 delay(10000);
         RKC=ReadKeyCode();
			}
  else return RKC;
}


/******************************************************************
函数名称:void FlagSign()
函数功能:通过按键输入一个初始电压,取值范围:0~9.9V
入口参数:无
出口参数:无
全局变量:flag 
 		 KeyCode
		 ResetBuff[0],ResetBuff[1]
		 dispbuff[0],dispbuff[1]
		 MidKeyCode
调用模块:main
******************************************************************/

void FlagSign()
{
       
	  if(flag==0x01)
         if(KeyCode==0x0f)                                //判断是否为16号置初值键
             ;
	     else flag=0x00;
	  else if(flag==0x02)
	         if(KeyCode>=0x00 && KeyCode<=0x04)
			    {  MidKeyCode=ResetBuff[0]; ResetBuff[0]=KeyCode; }		 
			 else flag=0x00;
	  else if(flag==0x03)
             if(KeyCode>=0x00 && KeyCode<=0x09)
	         {
              ResetBuff[1]=KeyCode;
			  dispbuff[0]=ResetBuff[0]%16;
	          dispbuff[1]=ResetBuff[1]%16;
			  flag=0x00;
			 }
		     else { ResetBuff[0]=MidKeyCode;  flag=0x00;  }
}


/******************************************************************
函数名称:void sent(unsigned char sent_buf)
函数功能:发读键盘命令
入口参数:sent_buf 
出口参数:无
全局变量:CS
		 CLK
		 DIO
调用模块:display
		 ReadKeyCode
		 ReadKB
******************************************************************/

void sent(unsigned char sent_buf)
{
char i;
CLK=0;                                        //置SPI时钟线为低
CS=0;                                         //置SPI片选线为低
delay (50);                                   //延时50us

for(i=0;i<8;i++)                              //发送8位数据
{
sent_buf=sent_buf<<1;                         //从数据最高位开始,将要发发送的数据位移入进位位CY
DIO=CY;                                       //数据位送数据线
CLK=1;                                        //置SPI时钟线为高
delay (10);                                   //延时10us
CLK=0;                                        //置SPI时钟线为低,发送完1位数据
delay (10);                                   //延时10us
}
delay (50);
DIO=0;
}
/******************************************************************
函数名称:void delay(char time)
函数功能:延迟
入口参数:time    延迟时间
出口参数:无
全局变量:无
调用模块:ReadKeyCode
		 ReadKB
		 sent
******************************************************************/

void delay(unsigned int time)
{
  unsigned int i;
  for(i=0;i<time;i++);
}


/******************************************************************
函数名称:void display()
函数功能:显示输出缓冲池dispbuff[0]~dispbuff[7]的内容
入口参数:无
出口参数:无
全局变量:CS
调用模块:Timer0
		 ReadKeyCode
******************************************************************/	

void display()
{
 char i;
 for(i=0;i<2;i++)
   {
     CS=1;
	 sent(0xc8+i);
	 sent(dispbuff[i]);
	 CS=1;
     sent(0xc8+6+i);
	 sent(dispbuff[6+i]);
	 CS=1;
   }
}


/******************************************************************
函数名称:main()
函数功能:主函数
入口参数:无
出口参数:无
全局变量:CS
 		 TICK
 		 dispbuff       输出缓冲池 
		 ResetBuff
		 ADresult       AD转换结果
调用模块:无
******************************************************************/

main()
{
   int mid1;
   char i;
   EX1=1;
   EA=1;
   CS=1;
   IT1=1;
   TMOD=0x01;                                             //定时器初始化
   TH0=0x3c;
   TL0=0xb0;
   ET0=1;
   TR0=1;
   TICK=0;
   dispbuff[0]=(ResetBuff[0]%16)|0x80;
   dispbuff[1]=ResetBuff[1]%16;
   for (i=2;i<6;i++)
   { 
   dispbuff[i]=1+i;
   }
   ADresult=0x00;
   dispbuff[6]=(ADresult/16)|0x80;
   dispbuff[7]=(ADresult%16)&0x0f;
   while(1)
   {
      FlagSign();
      
	  *DAResult=DASource();                                //数据送DA转换器
	  ADresult=adconvert(2);                               //读取AD转换结果
      
      dispbuff[0]=(ResetBuff[0]%16)|0x80;
      dispbuff[1]=ResetBuff[1]%16;
	  
	  mid1=ADresult*0.196;
	  dispbuff[6]=mid1/10+128;
      dispbuff[7]=mid1%10;
   }

 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -