单片机交流
直播中

刘辉

7年用户 1083经验值
私信 关注
[问答]

萌新求助,求一个单片机实现数字频率计的方案

萌新求助,求一个单片机实现数字频率计的方案

回帖(1)

郑婷婷

2021-11-8 09:39:26
系统功能及指标

测量频率范围:10Hz~600kHz
测量精度:1%以内
系统设计方案及基本流程

unsigned char DispBuf[8]

显示缓冲区,分别对应8个数码管每个数码管应该显示的数字
主要函数及其功能概述:
void delay(unsigned int t)

t: 延时长度(ms)
延时函数,t 可以对 delay 函数的运行时间进行设置,delay 函数本身不进行任何有意义的操作,只实现空转等待的功能
void DispClear()

清空显示缓冲区DispBuf
void DispInit()

显示模块的初始化函数
清空显示缓冲区DispBuf,设置工作方式寄存器TMOD(T1的对应位),TH1,TL1 ,TH0,TL0初值,设置中断允许寄存器IE
void SysInit()

系统初始化函数
调用DispInit(),然后对工作方式寄存器TMOD(T0的对应位)进行设置
void display (unsigned long f)

显示函数
把频率的数值 f 转化为8位数显示在数码管上
void T1INTSVC() interrupt 3

中断函数,也是最为核心的函数
定时器1中断,实现对数码管的刷新和计算频率值
中断函数T1INTSVC的实现方式:





主函数

主函数的工作流程图:





完整代码


#include
#include
#include


***it KEY2 = P2^0;                //按键1       
***it KEY3 = P2^1;                //按键2       
***it KEY4 = P2^2;       //按键3
***it LED0=P0^0;
***it LED1=P0^1;
***it LED2=P0^2;




unsigned char DispBuf[8];
unsigned int t;//延时长度/毫秒
unsigned long count;
unsigned long f;
unsigned long j;//循环变量
unsigned int wait=0;


//直接引用模块
void delay(unsigned int t){           //延时函数
        do
        {
                TH1 = 0xFA;
                TL1 = 0x24;
                TR1 = 1;
                while ( !TF1 );
                TR1 = 0;
                TF1 = 0;
        } while ( --t != 0 );       
}
]


void DispClear(){            //清空缓存
        unsigned char i;
        for ( i=0; i<8; i++ )
        {
                DispBuf = 0x00;
        }
}


void DispInit(){
        DispClear();       
        EA = 0;
        TMOD &= 0x0F;
        TMOD |= 0x10;
        TH1 = 0xFA;
        TL1 = 0x24;
        TR1 = 1;
        ET1 = 1;
        EA = 1;
        TH0=0x00;
        TL0=0x00;
        TR0=0;
}


void SysInit(){
        TMOD &= 0xF0;
        TMOD |= 0x05;        //设置定时器T0为16位定时器
        DispInit();                //数码管扫描显示初始化
}
//
void display (unsigned long f)//把f的各位数字输入到显示缓冲区
{
  code unsigned char Tab[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};   //0-9的码字
        unsigned char i;
        for ( i=0; i<7; i++ ){
                unsigned long int c;
                c = f%10;
                f = (f-c)/10;
                DispBuf[i+1] = Tab[c];//DisBuf低位对应数值低位
        }
        DispBuf[0]=Tab[0];


}


void T1INTSVC() interrupt 3          //定时器1中断
{          
        code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//一共有8个数码管,但是一次扫描过程只能亮1个,哪个比特为1,就点亮数码管
        static unsigned char n = 0;
        unsigned int th0;
        unsigned int tl0;
       
        TR1 = 0;
        TH1 = 0xFA;
        TL1 = 0x24;
        TR1 = 1;
    //扫描数码管,第n个数码管显示它对应的数字
        XBYTE[0x7800] = 0xFF;               
        XBYTE[0x7801] = ~DispBuf[n];//显示的数字是第n个数码管对应的数字
        XBYTE[0x7800] = ~com[n];//点亮第n个数码管
        n++;
        n &= 0x07;//n计数到7后归0
       
        wait++;
        if(wait==201){wait==0;}
         if(wait==100) { TR0=1; count=0;TH0=0x00;
         TL0=0x00;}//把计数器T0归0
         if(wait==200) { TR0=0;
         th0=TH0;//计数器高位
         tl0=TL0;//计数器低位
         count=th0*256+tl0;display(count);//把频率值的各位数字更新到显示缓冲区}
}




void main()
{       
   
        LED0=0;
        LED1=1;
        t=10;
        SysInit();
        display(0);//数码管上显示0
        TR1=1;
        for(;;)
        {
                  
        }


}
实验过程讨论

1.首先确定测频方案,画出原理图,写出伪代码
2.确定各个函数的功能,逐个代码实现
3.编写主函数,实现调用各个函数
4.频率由低到高,观察测量值
学习建议

这个实验台没有51单片机芯片,是用FPGA芯片通过程序实现了51单片机的功能,细节不用我们管,我们就把它当单片机用就行了。
一些必须掌握的内容

1.51单片机有几个比较重要的寄存器,如TCON、TMOD等,还有T0,T1两个计时/计数两用的模块,这些模块的功能和调用务必熟悉,在课本上。
2.以下是实验台的系统原理图,标注了8051单片机的每个引脚分别和哪些原件相连,务必学会看










(图在一个叫《单片机最小系统.pdf》的文件里,实验台电脑上有)
3.Keil打开后的界面如下,学会用Keil创建新的工程文件和设置断点来调试程序等,按照课本上的流程操作几遍就能学会





注意










4.老师会给几个教学历程,务必推一遍,研究透每一行代码,都可能考到





小贴士

1 一次只能打开一个文件调试,不然很容易出问题
2 打代码键盘一定要设置成英文,不然中文符号混进来会是一个空白符号,不容易查
3 CPU工作主频18MHz,一个指令周期就是12个振荡周期
犯过的代码错误

1 unsigned char weixuan[]忘记加char
2 中断处理完后忘记TR1=1
3 用toint要引用
4 while(t)还是while(!t)
5 分清主函数中delay在for里面还是在for外面
6 LED前忘记加***it
实验课基本情况

课上2周,讲2次课,之后自己抽时间,在打卡系统约实验室位置去做实验,考试时间在第二周结束后的某个周一,因为和另一个班一起考所以在第三周的结束后的周一
教材:现代电子技术综合实践教程 EDA 单片机与SPOC实验第二版
打卡系统:eeclab.uestc.edu.cn
45min一个学时
实验室开放:中午12-2不开(可申请)
下午5-6不开
晚上9点关
模拟练习和历年试题

老师给的两个模拟练习
1 EDA
E盘带AAA 指定目录建立项目(3分);建立元件在中间点亮两位LED(3分);利用此元件点亮最左2位和最右2位LED(3分)仿真一个10分频器(5分);清楚显示左边两位LED闪烁(3分);拨码切换清楚显示最右边2位LED闪烁(3分)
2 单片机
E盘带学号目录建立正确项目(3分);中间点亮两位LED(3分),中间数码管显示“88” (4分); 每按键,字符左循环移动一位,LED循环一周(5);每转一周字符模10加1(5分)

举报

更多回帖

×
20
完善资料,
赚取积分