📄 wpcacapture.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 + -