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

📄 main.c

📁 一个程控锁相环PLL程序,可以设定频率,步进
💻 C
字号:
 #include<reg52.h>

unsigned code ledmod[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
                    0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x00,0x00}; //显示段代码
unsigned code   ledsel[4]={0xfe,0xfd,0xfb,0xf7}; //显示位选代码
unsigned char data led[4];//显示缓冲,用于主程序和定时中断显示数据传递

 sbit key_set = P3^4;//设定键
 sbit key_clr = P3^5;//清除键(退出键)
 sbit key_add = P3^6;//加数键
 sbit key_mov = P3^7;//移位键

/****************************************************************************
*    函数原型: void function wait_5ms(void);
*    功    能: 提供5ms延时(时钟频率为12MHz)。
****************************************************************************/
void  wait_5ms( void ) {
	register int i ;
	for ( i=0 ; i<2000 ; i++ )
		;

 }
/***********************************************************************/
 void  delay( unsigned int ki )
  {for(;ki>0;ki--)
      {wait_5ms();}
  }

/***************************************************/
//键盘扫描程序,
//返回键值,无键按下返回0
//******************************************************/
 char key(void)
   {
    //*********扫描set键****************************
     key_set=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
     if(key_set==0)//初判断
      {
        key_set=1;wait_5ms();
        if(key_set==0);//再次确定按下
         {
           while(key_set==0)key_set=1;//等待按键释放
         }
         return 1; //返回键值
       }
    //*********扫描clr键****************************
     key_clr=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
     if(key_clr==0)//初判断
      {
        key_clr=1;wait_5ms();
        if(key_clr==0);//再次确定按下
         {
           while(key_clr==0)key_clr=1;//等待按键释放
         }
         return 2;//返回键值
       } 
      //*********扫描add键**********************
     key_add=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
     if(key_clr==0)//初判断
      {
        key_add=1;wait_5ms();
        if(key_add==0);//再次确定按下
         {
           while(key_add==0)key_add=1;//等待按键释放
         }
         return 3; //返回键值
       }
        //*********扫描clr键******************************
     key_mov=1;wait_5ms();//把按键口线置高设为输入,延时等待稳定
     if(key_mov==0)//初判断
      {
        key_mov=1;wait_5ms();
        if(key_mov==0); //再次确定按下
         {
           while(key_mov==0)key_mov=1;//等待按键释放
         }
         return 4;//返回键值
       }   

  return 0;//无键按下返回0
  
   }

// ******************************
//把dat拆成BCD码送显示缓冲
void set_disp(unsigned int dat)
 { 
   if(dat<9999)
    {
     led[3]=dat/1000;dat=dat%1000;
     led[2]=dat/100;dat=dat%100;
     led[1]=dat/10;led[0]=dat%10;
    }
 }
 //*****************************
 //设定琐相环输出频率
 void setF(unsigned int dat)
  {
  //使用 MOV @R0,A使PLL的分频器的分频系数高低8位数据同时输出
  //最大限度降低频率设定切换过程中的影响
  //参数传递时,dat的高8位在R6,低8位在R7
   #pragma ASM
       MOV A,R7
       MOV R0,A
       MOV A,R6
       MOV @R0,A 
   #pragma endasm   
  }

/*================================== */


void main(void)
{
  unsigned char  i=0,counter,set_S=255;
  unsigned int temp,tempf=500;
  unsigned char data ledbuf[4];//显示缓冲备份
  //counter为主程序循环次数计数器,
  //set_S为当前的设定操作状态,为255时为非设定状态,为0、1、2、3时分别表示当前设定的位
  //tempf为当前的频率值,
  //i和temp是在程序运行时的辅助变量 
   TMOD=0x01;TH0=0xfe;TL0=0x18; TR0=1;ET0=1;EA=1; 
       //初始定时器,16位定时模式
    setF(tempf);//设置PLL产生的频率
    set_disp(tempf);//刷新显示
   loop:                 
       for(;;)
          {
            i=key();//扫描键盘
            
            switch(i)
             {
                case 1 : //设定键按下
                       if (set_S>4)//如果原来为非设定状态
                            {
                             set_S=0;//进入设定状态
                              ledbuf[3]=led[3];//备份显示值,用于设定
                              ledbuf[2]=led[2];
                              ledbuf[1]=led[1];
                              ledbuf[0]=led[0];
                             }
                          else //如果原来为设定状态
                           { 
                            temp=ledbuf[3]*1000+ledbuf[2]*100+ledbuf[1]*10+ledbuf[0]; //转换设定值
                             if((temp>=500)&&(temp<=1000))//判断设定值是否合法
                              {
                                tempf=temp;//记录新的频率值
                                setF(tempf);//设置PLL产生新的频率
                              }
                              set_disp(tempf);//刷新显示
                              set_S=255;//退出设定状态
                            }
                        break;    
                  case 2 ://退出键按下
                         set_S=255;//退出设定状态
                         set_disp(tempf);//显示回原来的频率值
                         break; 
                  case 3 ://加值键按下
                         if(++ledbuf[set_S]>9)//设定值加1并判断是否大于9,
                          {
                           ledbuf[set_S]=0;//大于9,变为0
                           }
                           break;      
                  case 4: //移位键按下
                       if(++set_S>3)//指向下一位,如果超过最后一位,指回第一位
                          {
                           set_S=0;
                           }
                         break;                   
             }

           wait_5ms();
           
           if(set_S<4)//如果处于设定状态,控制当前显示位闪烁
            {
             if(++counter==100)//主程序运行了一百遍,约为100个wait_5ms()的时间
               {
                 led[set_S]=16;//不显示
                }
             if(counter==200)//主程序运行了2百遍,约为200个wait_5ms()的时间
               {
                 counter=0;//重新计数
                 led[set_S]=ledbuf[set_S];//显示
               }     
             }
             
          }
   goto loop;//避免程受干扰,跳出主循环
   goto loop;
   goto loop;
   goto loop;       
}

/*================TIME0显示=====================*/
void timer0 (void) interrupt 1 using 1
         {static unsigned char   k;//显示的位
            TH0=0xfc;TL0=0x18;//重装定时值
            P3=P3|0x0f; //灭显
            if(k==2)//是否应该显示小数点
              {                        
                P1=ledmod[led[k]]|0x80;//送段代码并点亮小数点 (|0x80点亮小数点)
              }
             else
              {
                 P1=ledmod[led[k]];//送段代码
              }
             P3=P3&ledsel[k];//送位选信号 
             k=(++k)&3;// 限制
         }


⌨️ 快捷键说明

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