- 打卡等级:初来乍到
- 打卡总天数:1
- 最近打卡:2025-04-18 13:30:15
已绑定手机
新手上路
- 积分
- 21
|
我使用8G1K08A-8pin的单片机实现精准的PWM频率值测量(0-300Hz)的功能,目前无论是用高低电平计数,定时器计时,以及中断检测,在调节信号发生器的PWM频率值时用该单片机检测,都会出现频率偶发性的不精准测量,下面的代码是用高低电平持续时间计数的方法测量PWM 的周期,进而求得PWM频率值的方法。使用的是P33引脚进行高低电平检测计数,信号发生器不断增大频率,如图中所示,频率值缓慢上升,频率值本应该是58的位置,出现了53这个值,这是什么原因?应该怎么解决这种问题
#include <stc8.H>
#include <stdio.h>
#include <INTRINS.H>
#include <tm1651.h>
#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4)
#define ADC_Power 0x80 //使能ADC模块 打开ADC 将ADC引脚设置到
#define ADC_Start 0x40 //开始ADC转换
#define ADC_Flag 0x20 //转换完成标志位
#define ADC_SYS 0x2f //将ADC系统时钟设定为SYSclk/2/16
//******************************************
//延时ms函数,参数:ms
//使用条件:晶振/系统频率30.000MHz
//******************************************
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 57;
j = 27;
k = 112;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay5us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 5;
while (--i);
}
void Delay101us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 112;
do
{
while (--j);
} while (--i);
}
//******************************************
//函数说明:串口初始化
//******************************************
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xE0; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
}
void Sendbyte(unsigned char dat){//发送8位数据到串口
SBUF = dat;
while(!TI);
TI=0;
}
char putchar(char c){//重定义printf()函数,用于串口打印信息
Sendbyte(c);
return c;
}
//******************************************
//函数说明:读取指定ADC引脚值。参数:ADC引脚编号(编号见上单片机引脚图)
//******************************************
//unsigned int analogRead(unsigned char ADC_Pin){
//
// ADC_CONTR = ADC_Power + ADC_Pin; //使能ADC,向寄存器写入将要读的ADC引脚
// ADCCFG = ADC_SYS; //将ADC系统时钟设定为SYSclk/2/16
// ADC_CONTR |= ADC_Start; //开始ADC转换
// _nop_();
// _nop_();
// while(!(ADC_CONTR & ADC_Flag)); //等待完成
// ADC_CONTR &=~ ADC_Flag; //清除完成标志位
// return (ADC_RES<<8) | ADC_RESL; //合并高8位低8位,返回合并后结果
//}
//******************************************
//主程序
//******************************************
void main(){
unsigned long a=0,b=0;
unsigned int c,d,e,f,sx;
unsigned long temp;
unsigned int period;
unsigned int frequency;
unsigned int low_time = 0; // 用于检测P30长时间低电平的计数器
bit pwm_detected = 0; // 标志位,用于标记是否检测到PWM信号
P1M0=0X00;
P1M1=0X00;
P3M0=0X00;
P3M1=0X00;
P5M0=0X00;
P5M1=0X00;
P3PU |= (1 << 0); // 启用P30的内部上拉电阻
UartInit();//初始化串口
a=0;
b=0;
ES = 1;
EA = 1;
e=30;
while(1){
c=P33;
if((c!=P33)&(P33==1))
{
a = 0; // 重置计数器
b = 0;
for(sx=4;sx>0;sx--)
{
while(P33)
{
a++;
Delay5us();
if(a>500000)
break;
}
while(!P33)
{
b++;
Delay5us();
if(b>500000)
break;
}
}
period = a/10 + b/10; // 计算周期
if(period > 0) {
P55=0;
Delay1000ms();
P55=1;
Delay1000ms();
frequency = 70000 / period; // 计算频率
printf("频率 = %u\n",frequency);
if(e<frequency) {
P54 = 0; // 输出高电平
d=0;
} else {
P54 = 1; // 输出低电平
d=1;
}
}
printf("继电器状态 = %u\n",d);
}
}
}
使用的是P33引脚进行高低电平检测计数,信号发生器不断增大频率,如图中所示,频率值缓慢上升,频率值本应该是58的位置,出现了53这个值,这是什么原因?应该怎么解决这种问题
|
-
串口输出PWM频率值
|