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

📄 51.c

📁 一个基于51单片机的PFM型开关电源代码
💻 C
字号:
#include"intrins.h"
#include"AT89X51.H"



#define uchar unsigned char
#define uint unsigned int


#define LCD_RS P2_7
#define LCD_RW P2_6
#define LCD_EN P2_5
#define LCD_DATA  P0
#define bflag  P0_7

/*函数原型*/
void init(void);            /*初始化硬件*/
void LCD_init(void);        /*初始化LCD*/
void LCD_cmd(uchar cmd);    /*写入控制命令*/
void delay(uint dly);
void setxy(char x,char y);
void LCD_string(char *s);
void LCD_char(char chr);/*写入要显示的字符*/
void wait_until_ready(void); /*检测忙标志,忙则等待*/
uchar freqH;
uchar freqL;
/*4行4列的按键编码*/
uchar list[4][4]={
  0x00,0x01,0x02,0x03,
  0x04,0x05,0x06,0x07,
  0x08,0x09,0x0a,0x0b,
  0x0c,0x0d,0x0e,0x0f
};
/* 0    1    2    3
   4    5    6    7
   8    9    A    B
   C    D    E    F
*/

//A确认键
//B启动频率输出键
//C停止频率输出健
//D频率步进增加键
//E频率步进减少键



/*初始化硬件*/
void init(void) 
{
  IE=0x88;  	//10001000b允许TIMER1中断
  IP=0x08;	  //00001000b定义定时器为高优先级中断
  TMOD=0x10;	//定时器1采用方式1
  TH1=0xfe;   //初始化输出频率1kHz
  TL1=0x0c;
  freqH=0xfe;
  freqL=0x16;

}

void LCD_init(void)
{ 
	LCD_cmd(0x38);/*8位数据,2行显示*/   
	LCD_cmd(0x08);/*显示关闭*/
	LCD_cmd(0x06);/*写入数据后光标右移*/   
	LCD_cmd(0x0f);/*显示开,显示光标,光标闪烁*/
	LCD_cmd(0x01);/*清屏*/
	setxy(1,1);
    LCD_string("Press b to start");

}


void LCD_cmd(uchar cmd)  
{   
	  
	  LCD_RS=0;                   
	  LCD_RW=0; 
	  LCD_DATA=cmd;
	  LCD_EN=1;  
	  delay(20);
	  LCD_EN=0;
      wait_until_ready();
}

void LCD_char(char chr)/*写入要显示的字符*/
{   LCD_RS=1;   
    LCD_RW=0;   
	LCD_DATA=chr;   
	LCD_EN=1;
    delay(20);
	LCD_EN=0;
	wait_until_ready();
}
void wait_until_ready(void) /*检测忙标志,忙则等待*/
{   
    LCD_RS=0;   
    LCD_RW=1;   
	LCD_DATA=0x0ff;   
	LCD_EN=1;   
	delay(20);   
	do{ACC=LCD_DATA;} 
	while(bflag==1);  
	LCD_EN=0;	
}

/*设定显示位置,行x=1或2,列y=1~16的任意整数*/
void setxy(char x,char y) 
{    
	char temp;    
	if(x==1)  
		{
            temp=0x80+y-1;  
			LCD_cmd(temp);  
		} 
	else  
		{
			temp=0xC0+y-1;  
			LCD_cmd(temp);  
		}
}

void LCD_string(char *s)
{ 
	for(;*s!='\0';s++)
	LCD_char(*s);
}

/*延时*/
void delay(uint dly)
	{ uint j;
 		for(j=0;j<dly;j++);
	}


void main(void)
{uint  i1;
 uint  i2;
 uint  i=0;
 uint  j;
 uint  start=0;
 uchar Key;
 uchar Keycode[2]={0,1};
 uchar Keydata;
 uchar temp1;
 uint Tinit;
 float freq=1;
 init(); 
 LCD_init();
while(1)
{
	P3_3=0;
	P3_2=0;
	P3_1=0;
	P3_0=0;

  if(P3_4==0||P3_5==0||P3_6==0||P3_7==0)   //初次判断有键
	delay(1000);
else 
  continue;
	P3_3=0;
	P3_2=0;
	P3_1=0;
	P3_0=0;

  if(P3_4==0||P3_5==0||P3_6==0||P3_7==0)  //第二次判断有键
	{	
		delay(1000);
        if(P3_4==0)
			i1=0;
		else if(P3_5==0)
			i1=1;
		else if(P3_6==0)
			i1=2;
		else if(P3_7==0)
			i1=3;
				
	}
else 
	continue;

	P3_3=0;
	P3_2=0;
	P3_1=0;
	P3_0=0;
if(P3==0xe0||P3==0xd0||P3==0xb0||P3==0x70)
	{	
		delay(1000);
        if(P3_4==0)
			i2=0;
		else if(P3_5==0)
			i2=1;
		else if(P3_6==0)
			i2=2;
		else if(P3_7==0)
			i2=3;
			
	}
else 
	continue;
if(i1==i2)//判断出有按键,查具体位置
	{	
		P3_3=0;            //检查第一行
		P3_2=1;
		P3_1=1;
		P3_0=1;                  
	if((P3&0xf0)!=0xf0)
		  j=0;
		  
		P3_3=1;            //检查第二行
		P3_2=0;
		P3_1=1;
		P3_0=1;
	if((P3&0xf0)!=0xf0)
		  j=1;
		  
		P3_3=1;            //检查第三行
		P3_2=1;
		P3_1=0;
		P3_0=1;	
	if((P3&0xf0)!=0xf0)
		  j=2;
		  
		P3_3=1;            //检查第四行
		P3_2=1;
		P3_1=1;
		P3_0=0;
	if((P3&0xf0)!=0xf0)
		  j=3;
		
    


	do{	
		delay(5000);
		P3_3=0;
		P3_2=0;
		P3_1=0;
		P3_0=0;}
	while(P3!=0xf0);      //等到按键放开
   
	

	}
else 
	continue;
  
  Key=list[j][i1];
  if(Key==0x0b)             //启动频率输出
  {
     start=1;
     freqH=0xfe;
     freqL=0x16;
    // freqH=0xff;
    // freqL=0xdf;
	 freq=1;
	 i=0;
     TR1=1;                  //启动timer1
     LCD_cmd(0x01);/*清屏*/ 
     setxy(1,1);
     LCD_string("Start at:");
	 setxy(2,1);
	 LCD_string("01kHz");
  }
  
  if(Key==0x0c)             //停止频率输出
  {
     start=0;
	 i=0;
     TR1=0;                  //停止timer1
     setxy(1,1);
     LCD_cmd(0x01);/*清屏*/ 
     LCD_string("Stop");
	 setxy(2,1);
	 LCD_string("Press b to start");
  }
  
  if(start==1)
  {
  
     if(0x00<=Key&&Key<=0x09)  //存储用户选择频率值
     {
       Keycode[i]=Key;
       i++;
	   if(i==1)
	   {
         setxy(2,0);
	     LCD_string("               ");  //清第二行
	   }
       setxy(2,i);
       Keydata=Key+48;
       LCD_char(Keydata);
	   
       if(i==2)
         i=0;
     }
                 
     if(Key==0x0a)	           //A为确认键
     { 
	   if(i==1)
	   continue;
	   i=0;
       freq=Keycode[0]*10+Keycode[1];
       if(freq<=20)
       {
         TR1=0;                 //停止timer1
         Tinit=0x10009-(uint)(500/freq);             //12M晶振 10009的值可微调
        // Tinit=0x10009-(uint)(1000/freq);          //24M晶振替换上一句
         freqH=(uchar)((Tinit&0xff00)>>8);
         freqL=(uchar)(Tinit&0x00ff);            //改变频率
         TR1=1;                 //启动timer1    
         LCD_string("kHz");
       }
       else
       {	 
		setxy(2,1);
        LCD_string("Out of range!");
       }
     }
     if(Key==0x0d)            //频率步进增加,步进0.5kHz
     {
        freq=freq+0.5;
        if(freq>20)
          freq=20;              //超出20kHz不再增加
        TR1=0;                 //停止timer1
        Tinit=0x10009-(uint)(500/freq);               //12M晶振 10009的值可微调
        // Tinit=0x10009-(uint)(1000/freq);           //24M晶振替换上一句
        freqH=(uchar)((Tinit&0xff00)>>8);
        freqL=(uchar)(Tinit&0x00ff);            //改变频率
        TR1=1;                 //启动timer1
        setxy(2,1);
        Keydata=(uchar)(freq/10);            //取十位        
        temp1=Keydata;
        LCD_char(Keydata+48);
        Keydata=(uchar)(freq-Keydata*10);    //取个位
        LCD_char(Keydata+48);
        if((freq-temp1*10-Keydata)!=0)
        	LCD_string(".5kHz");
        else
        	LCD_string(".0kHz");
     }
     if(Key==0x0e)            //频率步进减小,步进0.5kHz
     {
        freq=freq-0.5;
        if(freq<1)
          freq=1;              //小于1kHz不再减小
        TR1=0;                 //停止timer1
        Tinit=0x10009-(uint)(500/freq);              //12M晶振 10009的值可微调
        // Tinit=0x10009-(uint)(1000/freq);          //24M晶振 替换上一句
        freqH=(uchar)((Tinit&0xff00)>>8);
        freqL=(uchar)(Tinit&0x00ff);            //改变频率
        TR1=1;                 //启动timer1
        setxy(2,1);
        Keydata=(uchar)(freq/10);            //取十位        
        temp1=Keydata;
        LCD_char(Keydata+48);
        Keydata=(uchar)(freq-Keydata*10);    //取个位
        LCD_char(Keydata+48);
        if((freq-temp1*10-Keydata)!=0)
        	LCD_string(".5kHz");
        else
        	LCD_string(".0kHz");
     }
  }
}

}

void timer1(void)  interrupt 3
{   
    TH1=freqH;
	TL1=freqL;
    P2_0=~P2_0;           //输出方波
}















⌨️ 快捷键说明

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