基于STC15单片机的频率计与方波发生器设计说明.docx
- 文档编号:12956215
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:34
- 大小:365.27KB
基于STC15单片机的频率计与方波发生器设计说明.docx
《基于STC15单片机的频率计与方波发生器设计说明.docx》由会员分享,可在线阅读,更多相关《基于STC15单片机的频率计与方波发生器设计说明.docx(34页珍藏版)》请在冰点文库上搜索。
基于STC15单片机的频率计与方波发生器设计说明
课程设计论文
课题:
基于STC15单片机的频率计及方波发生器设计
基于STC15单片机的频率计及方波发生器设计
基于STC15单片机的频率计及方波发生器设计
一、设计要求
一)基础部分
1.数字频率计设计要求:
1)被测信号为正弦波或方波,频率范围为1Hz~5MHz;
2)测量相对误差的绝对值不大于百分之一;
3)门限电压2V-5V;
4)测量数据刷新时间不大于2s,测量结果稳定。
2.方波发生器设计要求:
1)方波发生器可以分为低频和高频2个端口产生,频率范围1Hz-6MHz;
2)通过不同按键实现频率的粗调和微调。
二)发挥部分
1.频率计范围为大于5MHz;
2.测量相对误差的绝对值不大于千分之一;
3.增加脉冲信号占空比的测量功能。
二、课程设计的意义与目的
1.在电子技术中,频率是最基本的参数之一,并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此频率的测量就显得更为重要。
2.在通信技术中,波形的发生和频率的控制是最基本的要求,也是通信技术的基础,因此设计波形的发生与控制器就显得尤为重要。
3.单片机数字频率计与可调方波发生器,具有可靠性高、体积小、价格低、功能全,广泛应用与各种职能仪器中,能使在测量过程的控制中达到自动化,省掉很多繁琐的人工操作,同时也提高了测试精度。
4.其次,课程设计以学生自主学习为主,是课堂内容的扩展和延伸,巩固前序教学内容,提升学生设计能力,使学生掌握小规模单片机系统的软硬件设计,培养学生的自主学习能力,自主学习掌握单片机相关的新知识,自主解决问题的能力。
三、方案设计
单片机数字频率计与可调方波发生器程序设计流程图
四、硬件设计原理图:
五、硬件设计实物图:
六、程序框架:
USER:
用户区main
Driver:
驱动区keypwmdigital(数码管)
Apply:
应用区measure(测量)
Sys:
系统区globaldelayusart
七、功能说明:
开机后默认进入方波发生器状态,输出引脚为P3.7,此时K2切换粗调细调,K4,K4分别为粗调和细调模式下的增加、减少频率按钮;
按下K1,此时切换为频率计测量,P3.4为测量输入口,注意和测量信号之间的共地。
测量范围为1Hz-8MHz,精度误差稳定达到千分之一,附误差分析。
可以用P3.7产生方波给P3.4测量,两个函数从机器上电开始就一直运行,互不干扰。
八、测量:
低频测量:
高频测量:
九、误差分析:
第一次误差分析:
小结:
频率计可以突破5M,平均误差为千分之二。
第二次误差分析:
由于不能稳定达到千分之一的测量设计误差值,并且从上图的测试表中得到误差满足线性关系,因此加入补偿值,第二次误差测试如下:
由上图可知,低频、中频、高频部分误差分别万分之五、万分之一、万分之二,整体平均误差为0.00030759,即万分之三,大幅度超过课程设计要求的误差值。
十:
实现功能情况表:
数字频率计设计要求
课程设计要求
实现情况
结论
1.被测信号为正弦波或方波,频率范围为1Hz~5MHz;
频率测量范围为1Hz~8MHz
完成,并且大幅度超过设计要求
2.测量相对误差的绝对值不大于百分之一;
测量相对误差的绝对值为万分之三
完成,并且大幅度超过设计要求
3.门限电压2V-5V;
门限电压2V-5V
完成
4.测量数据刷新时间不大于2s,测量结果稳定;
测量数据刷新时间为1s,测量结果稳定
完成,并且大幅度超过设计要求
方波发生器设计要求
课程设计要求
实现情况
结论
1.方波发生器可以分为低频和高频2个端口产生,频率范围1Hz-6MHz;
方波发生器可以产生70Hz~8MHz频率范围的方波
完成,基本满足设计要求
2.通过不同按键实现频率的粗调和微调。
可通过不同按键实现频率的粗调和微调
完成
发挥部分
课程设计要求
实现情况
结论
1.频率计范围为大于5MHz;
频率计测量范围上限为8MHz
完成
2.测量相对误差的绝对值不大于千分之一;
测量相对误差的绝对值为万分之三
完成,并且大幅度超过设计要求
3.增加脉冲信号占空比的测量功能。
能完成500Hz以内的测量功能
未完成
自行发挥部分
1.方波发生器可调占空比输出,调节范围为5%~100%
完成,通过按键调节
2.方波发生器和频率计可同时运行
完成,通过按键切换
十一、心得与体会
十二、参考资料
十三、附录:
附录一:
源程序
Main主函数:
#include"STC15Fxxxx.H"
#include"global.h"
#include"measure.h"
#include"pwm.h"
#include"key.h"
#include"delay.h"
#include"Digital.h"
voidmain()
{
while
(1)
{
PWM_Work();//打开测量功能函数
}
}
按键扫描函数
#include"global.h"
#include"delay.h"
#include"key.h"
UINT8KEY_Scan(UINT8mode)
{
staticUINT8key_up=1;//按键按松开标志
if(mode)key_up=1;//支持连按mode=1的时候连按,mode=0时不支持连按
if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
{
Delay10ms();//去抖动
key_up=0;
if(KEY1==0){while(!
KEY1);returnKEY1_PRES;}//当key1按下,返回KEY1_PRES的值
elseif(KEY2==0){while(!
KEY2);returnKEY2_PRES;}//当key2按下,返回KEY2_PRES的值
elseif(KEY3==0){while(!
KEY3);returnKEY3_PRES;}//当key3按下,返回KEY3_PRES的值
elseif(KEY4==0){while(!
KEY4);returnKEY4_PRES;}//当key4按下,返回KEY4_PRES的值
}elseif(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)key_up=1;
return0;
}
数码管显示相关函数:
#include"global.h"
#include"digital.h"
#include"STC15Fxxxx.H"
UINT8codeLedChar[]={//段码
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
UINT8LedBuff[8]={
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF//数码管显示缓存区
};
voidDigital_Init()
{
P0M0=P0M1=P1M0=P1M1=P2M0=P2M1=P3M0=P3M1=0;//配置IO口模式
Timer2Init();//定时器2初始化
IE2|=0x04;//开启定时器2中断
EA=1;//开启总中断
}
voidDigital_New(UINT32num)//数码管显示数值的更新函数
{
LedBuff[0]=LedChar[num%10];
LedBuff[1]=LedChar[num/10%10];
LedBuff[2]=LedChar[num/100%10];
LedBuff[3]=LedChar[num/1000%10];
LedBuff[4]=LedChar[num/10000%10];
LedBuff[5]=LedChar[num/100000%10];
LedBuff[6]=LedChar[num/1000000%10];
LedBuff[7]=LedChar[num/10000000%10];
}
voidTimer2Init(void)//1毫秒@33.1776MHz
{
AUXR&=0xFB;//定时器时钟12T模式
T2L=0x33;//设置定时初值
T2H=0xF5;//设置定时初值
AUXR|=0x10;//定时器2开始计时
}
voidInterruptTime2()interrupt12//数码管显示的更新
{
staticUINT8i=0;
P0=0xFF;//关闭残影
switch(i)
{//动态扫描显示
case0:
P2=0x01;i++;P0=LedBuff[0];break;
case1:
P2=0x02;i++;P0=LedBuff[1];break;
case2:
P2=0x04;i++;P0=LedBuff[2];break;
case3:
P2=0x08;i++;P0=LedBuff[3];break;
case4:
P2=0x10;i++;P0=LedBuff[4];break;
case5:
P2=0x20;i++;P0=LedBuff[5];break;
case6:
P2=0x40;i++;P0=LedBuff[6];break;
case7:
P2=0x80;i=0;P0=LedBuff[7];break;
default:
break;
}
}
PWM发生器函数:
#include"global.h"
#include"STC15Fxxxx.H"
#include"pwm.h"
#include"key.h"
#include"digital.h"
#include"intrins.h"
#include"measure.h"
#include"delay.h"
voidDigital_Init(void);
voidDigital_New(UINT32num);
sbitBELL=P4^5;
#defineTick0.0000000301408179L//时间片长度
#defineLTick0.0000004822530864L//16分频后的时间片长度
#definestepH5000//粗调步进值
#definestepL100//细调步进值
#definestepD5//占空比步进值
doublefreq=50000;//PWM波频率
UINT32Duty=50;//定义占空比50%
//计算,根据PWM频率计算出15位增强型PWM发生器装载值
doubleCalculate(doublen)
{
doublei;
BELL=0;
if(n<=1500)
{
i=(1/n)/LTick;//(1/n)算出相应频率的周期,(1/n)/Tick得出装载值
if(n<=70)
{
n=70;
freq=70;
BELL=1;
Delay100ms();
BELL=0;
i=(1/n)/LTick;//(1/n)算出相应频率的周期,(1/n)/Tick得出装载值
returni;
}
returni;
}
elseif(n>=8000000)//上限
{
n=8000000;
freq=8000000;
BELL=1;
Delay100ms();
BELL=0;
}
i=(1/n)/Tick;//(1/n)算出相应频率的周期,(1/n)/Tick得出装载值
returni;
}
voidPWM_Init(UINT32fre)
{
doubletemp1;//Calculate返回给temp1赋值给PWMC寄存器
freq=fre;
temp1=Calculate(freq);
P3M0=P3M1=0x00;//要输出PWM波形的引脚要配置为准双向或者强推挽输出,这里设置为准双向输出
P4M1=0x00;
P4M0=0x20;
PIN_SW2|=0x80;//使能访问XSFR
PWMCFG=0x00;//配置PWM的输出初始电平为低电平
if(fre>1500)
{
PWMCKS=0x00;//选择PWM的时钟为Fosc/(0+1)
}
elseif(fre<=1500)
{
PWMCKS=0x0F;
}
PWMC=temp1;//设置PWM周期
PWM2T1=0x0000;//设置PWM2第1次反转的PWM计数
PWM2T2=temp1*Duty/100;//设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM2CR=0x00;//选择PWM2输出到P3.7,不使能PWM2中断
PWMCR=0x01;//使能PWM信号输出
PWMCR|=0x80;//使能PWM模块
PIN_SW2&=~0x80;//关闭访问XSFR
}
voidPWM_Adjust(UINT32fre,UINT8duty)//功能大体同上,为粗调细调改变频率时使用
{
doubletemp2;
if(fre<=1500)
{
doubletemp2;
freq=fre;
temp2=Calculate(fre);
PIN_SW2|=0x80;//使能访问XSFR
PWMCR=0x00;//关闭模块
_nop_();
_nop_();
PWMCKS=0x0F;//选择PWM的时钟为Fosc/(0+1)
PWMC=temp2;//设置PWM周期
PWM2T1=0x0000;//设置PWM2第1次反转的PWM计数
PWM2T2=temp2*duty/100;//设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWMCR=0x01;//使能PWM信号输出
PWMCR|=0x80;//使能PWM模块
PIN_SW2&=~0x80;
}
elseif(fre>1500)
{
freq=fre;
temp2=Calculate(fre);
PIN_SW2|=0x80;//使能访问XSFR
PWMCR=0x00;//关闭模块
_nop_();
_nop_();
PWMCKS=0x00;//选择PWM的时钟为Fosc/(0+1)
PWMC=temp2;//设置PWM周期
PWM2T1=0x0000;//设置PWM2第1次反转的PWM计数
PWM2T2=temp2*duty/100;//设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWMCR=0x01;//使能PWM信号输出
PWMCR|=0x80;//使能PWM模块
PIN_SW2&=~0x80;
}
}
UINT8PWM_KeyConl()
{
staticUINT8k=0,swch=0;
UINT8key_value;
key_value=KEY_Scan(0);
if(key_value==1)//当第一个按键按下
{
//Close_PWM();//关闭PWM发生器功能
P35=1;
MeasureH_Work();//频率计开始工作
}
elseif(key_value==2)//当按键2按下,切换粗、细调
{
P34=~P34;
swch=k;//判定粗调、细调状态变量
k++;
if(k==3)k=0;
}
if(swch==0)
{
Digital_New(freq);
if(key_value==4)//加频率(细)
{
freq=freq+stepL;//在原有频率基础上加10Hz
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;//更新完成
}
elseif(key_value==3)//减频率(细)
{
if(stepL>freq)
{
freq=70;
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;
}
else
{
freq=freq-stepL;//在原有频率基础上减10Hz
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;//更新完成
}
}
}
elseif(swch==1)
{
Digital_New(freq);
if(key_value==4)//加频率(粗)
{
freq=freq+stepH;//在原有频率基础上加1000Hz
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;//更新完成
}
elseif(key_value==3)//减频率(粗)
{
if(stepH>freq)
{
freq=70;
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;
}
else
{
freq=freq-stepH;//在原有频率基础上减1000Hz
PWM_Adjust(freq,Duty);//更新上面的调整结果
return1;//更新完成
}
}
}
elseif(swch==2)
{
Digital_New(Duty);
if(key_value==4)//占空比
{
Duty=Duty+stepD;
if(Duty>=100)
{
Duty=100;
BELL=1;
Delay100ms();
BELL=0;
}
PWM_Adjust(freq,Duty);//更新上面的调整结果
return2;//更新完成
}
elseif(key_value==3)
{
Duty=Duty-stepD;
if(Duty<=5)
{
Duty=5;
BELL=1;
Delay100ms();
BELL=0;
}
PWM_Adjust(freq,Duty);//更新上面的调整结果
return2;//更新完成
}
}
return0;
}
voidPWM_Work()
{
charflag=0;//判断这个值是否已经调节了频率
Digital_Init();//初始化数码管
Digital_New(freq);//初始化数码管显示数值
PWM_Init(freq);//初始化PWM
while
(1)
{
flag=PWM_KeyConl();//键控
if(flag==1)
{
Digital_New(freq);//显示
}
elseif(flag==2)
{
Digital_New(Duty);//显示
}
}
}
voidClose_PWM()
{
Digital_New(0);//关闭数码管显示
PIN_SW2|=0x80;//使能访问XSFR
PWMCR=0x00;//关闭15位增强型PWM发生器
PIN_SW2&=~0x80;//关闭访问XSFR
}
频率计测量功能相关函数:
#include"measure.h"
#include"STC15Fxxxx.H"
#include"digital.h"
#include"key.h"
#include"pwm.h"
voidPWM_Work(void);
////////////////////////以下函数功能只能实现低频测量0-700K(外部中断)/////////////////////////
/*UINT32countL=0;
UINT32frequency=0;
UINT8FLAG=0;
UINT8i=0;
voidMeasureL_Init()
{
Timer1InitL();//此定时器用于更新频率,1S一次
Digital_Init();//数码管初始化
INT_CLKO|=0x20;//使能INT3中断
ET1=1;//开启定时器1中断
EA=1;
}
voidMeasureL_Work()
{
MeasureL_Init();
while
(1)
{
if(FLAG==1)
{
Digital_New(frequency);
FLAG=0;
}
}
}
voidTimer1InitL(void)//20毫秒@33.1776MHz
{
AUXR&=0xBF;//定时器时钟12T模式
TMOD
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STC15 单片机 频率计 方波 发生器 设计 说明