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

📄 main.c

📁 这是一个模拟转速信号发生器的程序
💻 C
字号:
//***********************************
//单片机为16f877a  晶震为8m
//************************************
#include <pic.h>
#include    <math.h>
 __CONFIG(0x1f76);  
extern  void initset();  				//定义引用的函数
void delay_1000() ;
//extern void moniled (char led_data);
unsigned char fADConverter(unsigned char ChannelNum);         //函数声明
unsigned char comp(unsigned char temp4);
unsigned char dycomp(unsigned char temp9);
unsigned int Rpm(unsigned char temp);
void DYdisplay(unsigned int x1);
void Rpmdisplay(unsigned int x);
void DELAY11();
bit  rb0inc,compok,compok1;
persistent char lednum,lednuml,lednumh;
persistent unsigned char pinlv,pinlvback,count=0;

unsigned int Data,tempint,rpmyushu=0,dyback,tempback,dytemp,dyyushu=0,rpmtemp;
unsigned char pinlvtemp=0,temp=0;
const char ledtab[10]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XD8,0X80,0X90 }; //不带小数点LED段码表0-9,高电平灭  共阳LED
const char ledtab1[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X58,0X00,0X10 };//带小数点LED段码表0-9,高电平灭  共阳LED

#define nop() asm("nop")
#define FBOUT RA2                 //方波输出端口

#define GEWEI RC6                 //转速显示位控制端口
#define SHIWEI RC3 
#define BAIWEI RC5 
#define QIANWEI RC4 


#define DYGEWEI RC0                 //电压显示位控制端口
#define DYSHIWEI RC1 
#define DYBAIWEI RC2 


//********************************************************/
//中断子程序
//Timer2中断服务子程序,方波发生器  1ms中断一次
//********************************************************/
void interrupt IRQ(void)
{
 if(TMR2IF)
  {
   TMR2IF=0; 
   ++pinlvtemp;
   if(pinlvtemp==pinlv)
      {
       FBOUT=!FBOUT ;
        pinlvtemp=0;
      }
  }
}
//*********************************************************/
//*********************************************************/
inirb0int()              //中断初使化
{ 

 lednuml=0;
 lednumh=0;				

 }
//***************************************************/
//AD转换
//***************************************************/
unsigned char fADConverter(unsigned char ChannelNum)
{	
	unsigned char ad_result = 0;
	ADCON0 =ChannelNum;     //ADON

	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();
	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();
	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	
	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();
	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();
	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();	nop();
																			//sample time
     ADGO=1;
	 while(ADGO);
	ad_result = ADRESH; 
   
	return(ad_result);         //得到的数据为转速频率,或为电压数据
}

//***************************************************/
//比较两次转速数据,看是否刷新
//***************************************************/
unsigned char comp(unsigned char temp4)
{
  if(count==0)    //  第1次需要保存上次采集的数据
    {
      pinlvback=temp4;
      count=1;
      return(temp4);  //返回当前的转速的周期数据
    }
  else
    {
     if(pinlvback==temp4)    //如果上次采集的数据与这次相等,则标志成立
     {compok=1;return(temp4); }
     else
     {compok=0;pinlvback=temp4;return(temp4); }
    }
}
//***************************************************/
//比较两次电压数据,看是否刷新
//***************************************************/
unsigned char dycomp(unsigned char temp9)
{
  if(count==0)    //  第1次需要保存上次采集的数据
    {
      dyback=temp9;
      count=1;
      return(temp9);  //返回当前的转速的周期数据
    }
  else
    {
     if(dyback==temp9)    //如果上次采集的数据与这次相等,则标志成立
     {compok1=1;return(temp9); }
     else
     {compok1=0;dyback=temp9;return(temp9); }
    }
}
//***************************************************/
//求转速数据
//temp为当前转速的频率,此数据依据AD值得到
//***************************************************/
unsigned int Rpm(  unsigned char temp5)
{  unsigned int temp11;
 temp5=(unsigned char)temp5/2;    //除2   周期最大值为127MS,1代表周期时间为1ms的意思
 if(temp5<12) {temp5=12;}    //转速设置最高为6*2=12MS   rpm=1000/12*60=5000   最小为 =1000/127*60
 pinlv=temp5;
 pinlv=pinlv/2;  //除4,周期的一半
 
 
 temp11=(unsigned int)1000/temp5;     //强制转换成整形
 temp11=temp11*60  ;  //求转速
 nop();
 
 return(temp11);         //返回当前的转数值

}

//**********************************************
//转速数据显示
//**********************************************
void Rpmdisplay(unsigned int x)
  {int qian,bai,shi,ge;
   unsigned int temp;
     PORTC=0;
     temp=x;
     qian=temp/0x3e8;
     PORTD=ledtab[qian];       //查表得千位显示的代码
     NOP();
     NOP();
     PORTD=ledtab[qian];       //查表得千位显示的代码
     QIANWEI=1;            //千位输出低电平,点亮千位显示
   //  DELAY11();                //延时一定时间,保证显示亮度
     QIANWEI=0;
     bai=(temp%0x3e8)/0x64; 
     PORTD=ledtab[bai];        //查表得百位显示的代码
     BAIWEI=1;              //点亮百位显示
   //  DELAY11(); 
     BAIWEI=0;   
     shi=((temp%0x3e8)%0x64)/0xa;           
     PORTD=ledtab[shi];       //查表得十位显示的代码
     SHIWEI=1;             //点亮十位显示
   //  DELAY11();  
     SHIWEI=0; 
     ge=((temp%0x3e8)%0x64)%0xa;           
     PORTD=ledtab[ge];        //求个位显示的代码
     GEWEI=1;           //点亮个位显示
    // DELAY11(); 
     GEWEI=0;
  } 
//****************************************************/
//电压数据显示
//****************************************************/
void DYdisplay(unsigned int x1)
  {int DYbai,DYshi,DYge;
   unsigned int temp;
     PORTC=0;
     temp=x1;
     DYbai=temp/0x64; 
     PORTD=ledtab1[DYbai];        //查表得百位显示的代码
     DYBAIWEI=1;              //点亮百位显示
     DELAY11(); 
     PORTC=0;   
     DYshi=(temp%0x64)/0xa;           
     PORTD=ledtab[DYshi];       //查表得十位显示的代码
     DYSHIWEI=1;             //点亮十位显示
     DELAY11();  
     PORTC=0; 
     DYge=(temp%0x64)%0xa;           
     PORTD=ledtab[DYge];        //求个位显示的代码
     DYGEWEI=1;          //点亮个位显示
     DELAY11(); 
     PORTC=0;
  }   
//**********************************************
//**********************************************
void DELAY11()
  {
   int i;
   for(i=0;i<=30;i++)
   continue;
  }
//***************************************************/
//求电压数据,
//temp为当前转速的频率,此数据依据AD值得到
//***************************************************/
 unsigned int DYDATA(unsigned char temp)
{unsigned int temp1=0;
 temp1=temp*1.96 ;

 return(temp1);         //返回当前的电压值,当数据为255时,返回的值为499  ,此处的数据为*100的数据
}

//*********************1ms精确延时*************************** 
void delay_1000()           //1.008ms
{
    unsigned char i,j;
    for(i=0x03;i>0;i--)
    for(j=110;j>0;j--);
}
//*************************************************************
//延时程序(Xms)
void    DELAY(unsigned int x)
{  
   unsigned   char  j;
   for(;x--;)
     {
      for(j=110;--j;) continue;
     }    
}

//****************************************************************/
//****************************************************************/
void main()
{

  initset();
  compok=0;
  compok1=0;
  GIE=1  ;
 while(1)
 {	 
   CLRWDT();       //看门狗    
   DELAY(80);
   rpmtemp=fADConverter(0x49)  ;   //求频率  AN1通道  fose=32  AN1为0x89
   rpmtemp=comp(rpmtemp);
   if(compok!=1)     
   { 
     rpmyushu=Rpm(rpmtemp);     //求转速数据
     Rpmdisplay(rpmyushu);   //转速数据显示
    }
   CLRWDT();       //看门狗   
   DELAY(80);
    dytemp=fADConverter(0x41)  ;   //电压值  AN0通道  fose=32 
   dytemp=dycomp(dytemp);

   if(compok1!=1) 
   {dyyushu=DYDATA(dytemp);        //返回当前的电压数据
   DYdisplay(dyyushu); 
   }
   
  }
}

⌨️ 快捷键说明

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