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

📄 wpcacapture.c

📁 C8051F系列单片机外围电路功能模块程序
💻 C
字号:
//参考程序B:WPCACAPTURE.C  用PCA模块0负边沿触发的捕捉方式测量方波的频
//率.测量固定频率方波的100个周期的时间宽度,再求平均,可得方波的频率和
//周期.测量结果用LCD显示. 打开VIEW/DEBUG WINDOW/SFR'S/PCA窗口,
// 可直接从PCA0CPH0和PCA0CPL0中看到十六进制表达的测量结果.

#include <c8051f020.h>                    // SFR declarations
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
sbit  BELL=P3^5;
unsigned char *lcdpoint;         /*指向 lcddata数组的指针*/
void SYSCLK_Init (void);         /*时钟初始化*/
void LCD_Init(void);             /*LCD初始化*/
void LCD_disp_line1(void);       /*显示第一行数据*/
void LCD_disp_line2(void);       /*显示第二行数据*/
void  handle(void);   /*处理数据*/
void delay(uchar time);//延时
void PORT_Init (void); //I/O口初始化
void PCA_Init (void);  //PCA初始化
void PCA_ISR (void);   //PCA中断服务子程序
float freq,data0;
unsigned int i,j,data2;
unsigned char FRE[8]={" FREQ:  "},KHZ[10]={0x0,0x00,0x0,0x0,"Khz"};
signed char T[8]={" TIME:  "},TIME0[10]={0x0,0x00,0x0,0x0,0x0,"us"};	
unsigned char aa,bb,cc,ee;
void main (void) {
   BELL=1;
   /*关看门狗*/
   WDTCN = 0xde;
   WDTCN = 0xad;
   LCD_Init();             /*LCD初始化*/  
   SYSCLK_Init ();         /*时钟初始化*/
   PORT_Init ();			/*IO口初始化*/
   BELL = 0;              /*响蜂鸣器*/   
   delay(100);            /* 延时*/
   BELL  =1;               /*关闭蜂鸣器*/   
while (1) {    
   j=0;	
   EA = 1;		            /*开中断*/
   PCA_Init ();	     	    /*PCA初始化*/   
   while (j<0x64) ;       /*PCA发生中断100次 到否?;*/
   PCA0CN=0x0;		      /*禁止PCA定时器/计数器*/
   EIE1 = 0x0;		      /*禁止PCA0中断*/
    handle();              /*处理数据*/
   LCD_disp_line1();
    LCD_disp_line2();
	 delay(65000);            /* 延时*/
	  delay(65000);            /* 延时*/
	   delay(65000);            /* 延时*/
	    delay(65000);            /* 延时*/
		 delay(65000);            /* 延时*/
		  delay(65000);            /* 延时*/
		   delay(65000);            /* 延时*/
    }
}
void  handle(void)/*处理数据*/
{
data0=(PCA0CPH0*256+PCA0CPL0);/*处理来自PCA0CPH0,CA0CPL0的数据*/
data0=(PCA0CPH0*256+PCA0CPL0)/11.0592;
   freq=(100000)/data0;        /*计算被测波形的频率*/
   aa=data0/1000;  //计算周期(TIME)
   bb=(data0-aa*1000)/100;
   cc=(data0-aa*1000-bb*100)/10;
   ee=(data0-aa*1000-bb*100-cc*10);
   TIME0[0]=aa;   //存放万位数
   TIME0[1]=bb;   //存放千位数
   TIME0[2]=0x2e;  //"."
   TIME0[3]=cc;   //存放百位数
   TIME0[4]=ee;   //存放十位数
   aa=freq/1000;  //计算频率(FREQ)
   bb=(freq-aa*1000)/100;
   cc=(freq-aa*1000-bb*100)/10;
   ee=(freq-aa*1000-bb*100-cc*10);
   KHZ[0]=aa;    //存放千位数
   KHZ[1]=bb;    //存放百位数
   KHZ[2]=cc;    //存放十位数
   KHZ[3]=ee;    //存放个位数
   }
void PORT_Init (void)    //I/O口初始化
{
   XBR0 = 0x08;			//CEX0-->P0.0
   XBR2    = 0x40;      // Enable crossbar and weak pull-ups
   P74OUT  = 0xf0;	    /*P6,P7为推挽输出*/
}
void PCA_Init (void)   //PCA初始化
{
	EIE1 = 0x08;		/*使能PCA0中断*/	 
	PCA0MD = 0x09;	    /*PCA定时器时钟源SYSCLK选择:01(1/12),03(1/4),09(1)*/
	PCA0L	 = 0x00;
	PCA0H	 = 0x00;
PCA0CPM0 = 0x11;/*PCA0负边沿捕捉方式,CCF0=1,允许辅捉/比较标志的中断申请*/
	PCA0CPL0 = 0x00;
	PCA0CPH0 = 0x00;
    PCA0CN=0x40;		/*允许PCA定时器/计数器*/
}
/*PCA中断服务子程序*/
void PCA_ISR (void) interrupt 9
{
	j++;				/*计中断次数*/
	CCF0 = 0;			/*清匹配中断标志*/
}
void delay(uint time)    //延时
{
	uint k,h;
	for(h=0;h<time;h++)
    	for(k=0;k<0x900;k++);
}
void LCD_disp_line1(void)
 { 	uint x;
 unsigned data1,count;
            P7=0x80;   // 显示第一行,DDRAM地址为00
		    P6 = 0x1;
	        P6 = 0x0;     
	   for(x=0;x<1000;x++);
	    lcdpoint=&T;
	    for(count=8;count>0;count--)     //显示文字"TIME :"
	    {  
		    data1=*lcdpoint;
	        P7 = data1; 		/*送字符数据*/
			P6 = 0x04;
	        P6 = 0x05;
	        lcdpoint++;
			for(x=0;x<1000;x++);
		}                        //准备送数据
	    lcdpoint=&TIME0;
for(count=7;count>0;count--) //显示数字"XXXXXns"
	 {		    
            data1=*lcdpoint;
			if(data1<0x40)
            if(data1 !=0x2e)
			data1 += 0x30;		/*转化成ASCII码*/
		    P7 = data1; 		/*送字符数据*/
			P6 = 0x04;
	        P6 = 0x05;
	        lcdpoint++;
			for(x=0;x<100;x++);
		}
    }
 void LCD_disp_line2(void)// 显示第二行
 { 	uint x;
 unsigned data1,count;
            P7=0xc0;       // 显示第二行,DDRAM地址为40H
		    P6 = 0x1;
	        P6 = 0x0;    
	   for(x=0;x<1000;x++);
	    lcdpoint=&FRE;     //显示文字"FREQUENCE :"
	    for(count=8;count>0;count--)    
	    { 
		    data1=*lcdpoint;
	        P7 = data1; 		/*送字符数据*/
			P6 = 0x04;
	        P6 = 0x05;
	        lcdpoint++;
			for(x=0;x<1000;x++);
		}                        //准备送数据
	    lcdpoint=&KHZ;
for(count=7;count>0;count--) //显示数字"XXXXKhz"
	 {		    data1=*lcdpoint;
			if(data1<0x40)
			data1 += 0x30;		/*转化成ASCII码*/
		    P7 = data1; 		/*送字符数据*/
			P6 = 0x04;
	        P6 = 0x05;
	        lcdpoint++;
			for(x=0;x<100;x++);
		}
    }
void LCD_Init(void)   /*LCD初始化*/
{	uint x;
   P6 = 0x09;
   for(x=0;x<50000;x++);
  //P7 = 0x30;				/*设定一行显示*/
   P7 = 0x38;				/*设定两行显示*/
   P6 = 0x08;
   P6 = 0x09; 
   for(x=0;x<1000;x++);
   P7 = 0x0e;				/*显示开,光标显示,光标不闪烁*/
   P6 = 0x08;
   P6 = 0x09;
   for(x=0;x<1000;x++);
   P7= 0x06;				/*显示增加,不平移*/
   P6 = 0x08;
   P6 = 0x09;
   for(x=0;x<5000;x++);
   P7 = 0x01;				/*清屏*/
   P6 = 0x08;
   P6 = 0x09; 
   for(x=0;x<5000;x++);
}
void SYSCLK_Init (void)  /*时钟初始化*/
{
 int k;                              /*延时计数器*/
  OSCXCN = 0x67;                      /*启动外部晶振*/
for (k=0; k < 255; k++) ;           /*等待外部晶体起振*/
  while ((OSCXCN & 0x80)==0x00) ;     /*查询标志位*/
OSCICN=0x88 ;                        /* 选择外部时钟为11.0592MHZ*/                                                  
}
 

⌨️ 快捷键说明

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