找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7108|回复: 11
收起左侧

51单片机简易信号发生器仿真设计 含误差分析+源码+波形图

  [复制链接]
ID:191542 发表于 2019-1-9 21:22 | 显示全部楼层 |阅读模式
本人的课程设计,和大家分享分享,多谢大家的指导和建议!

后面的附件有完整的工程文件实习报告、仿真文件和部分误差分析(完整的交给老师了,所有要求均满足,误差很小)
一、课程设计内容及基本要求利用单片机IO口作输出,通过定时器的周期性中断输出一个占空比可调、频率可调的简易方波信号发生器,具体要求如下:
1、完成频率范围为0.1Hz5KHz的方波发生器,要求如下:
1)占空比5%~95%连续可调;
2)可键盘输入信号发生的频率。
2、可完成脉宽范围为100μs1s的脉冲信号发生器,要求如下:
1)可键盘输入发生脉冲宽度;
2)每按一次触发键,可发出一个单脉冲。
3、根据已经描述的C语言控制程序,运用Proteus画出硬件连接图,并将运用C语言描述的程序下载到Proteus虚拟单片机中,在Proteus中实现简易方波信号发生器的各项功能。  

目录
一、Proteus仿真
1、仿真电路图
2、0.1HZ波形
3、5KHZ波形
4、10%占空比波形(10HZ)
5、90%占空比波形(10HZ)
6、工程文件框架
二、主程序部分
1、主函数
2、定时器初始化函数及中断服务函数
三、顶层驱动文件
1、顶层驱动 .C 文件
2、顶层驱动 .H 文件
四、底层驱动文件
1、矩阵按键
1.1 矩阵按键 .C 文件
1.2 矩阵按键 .H 文件
2、四段数码管
2.1 四段数码管.C 文件
2.2 四段数码管.H 文件


一、      Proteus仿真1、仿真电路图
2、0.1HZ波形
3、5KHZ波形
4、10%占空比波形(10HZ)
5、90%占空比波形(10HZ)
6、工程文件框架

二、主要程序部分


主要是根据不同频率段分不同的最小计数时长
/*******************************************************************************
* FunctionName  : Function_1_Serve
* Description    : 模式1服务函数 定时器0单位定时周期配置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Function_1_Serve(void)
{
        float temp = 0.0;
        temp = Calculate_Data();//计算方波频率
        /*对应不同频率段 设置不同的单位定时器周期*/
        if(temp<=1)
                TIMEO = 10000;
        else if(temp<=10)
                TIMEO = 1000;
        else if(temp<=100)
                TIMEO = 100;
        else if(temp<=1000)
                TIMEO = 50;
        else if(temp<=10000)
                TIMEO = 20;
        switch(TIMEO)// 设置不同的单位定时器周期
        {        
                /*0.1hz-1hz*/
                case 10000:
                        TIMEO_H = 0xdc;TIMEO_L = 0x00;
                        time0_all_num=100/temp;time0_high_num=time0_low_num=time0_all_num/2;break;
                /*1hz-10hz*/
                case 1000:        
                        TIMEO_H = 0xfc;TIMEO_L = 0x75;
                        time0_all_num=1000/temp;time0_high_num=time0_low_num=time0_all_num/2;break;
               /*10hz-100hz*/
                case 100:        
                        TIMEO_H = 0xff;TIMEO_L = 0xb2;
                        time0_all_num=10000/temp;time0_high_num=time0_low_num=time0_all_num/2;break;
                /*100hz-1000hz*/
                case 50:        
                        TIMEO_H = 0xff;TIMEO_L = 0xdf;
                        time0_all_num=20000/temp;time0_high_num=time0_low_num=time0_all_num/2;break;
                /*1000hz-10khz*/
                case 20:        
                        TIMEO_H = 0xff;TIMEO_L = 0xff;
                        time0_all_num=23000/temp;time0_high_num=time0_low_num=time0_all_num/2;break;
                default:break;
        }
}
/*******************************************************************************
* FunctionName  : Function_3_Serve
* Description    : 模式3服务函数  定时器1单位定时周期配置
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Function_3_Serve(void)
{
    float temp = 0.0;
    temp = Calculate_Data();
   
    time1_all_num = (uint)temp;
    TIME1_H = ((65536-80)/256);
    TIME1_L = ((65536-80)%256);
}
/*******************************************************************************
* FunctionName  : Time_Init
* Description    :系统定时器初始化
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
voidTime_Init(void)
{
    TMOD = 0X11;   
    TR0 = 0;            
    TR1 = 0;
    ET0 = 1;   
    ET1 = 1;
    EA = 1;
}
/*******************************************************************************
* FunctionName  : Time0(void) interrupt 1
* Description    :定时器0中断服务函数
* Input          : None
* Output         : None
*******************************************************************************/
void Time0(void)interrupt 1
{   
    TH0 = TIMEO_H;
    TL0 = TIMEO_L;
    time0_num++;        //记录一个周期进入定时器中断的次数
    if(time0_num > time0_high_num)  //输出口由高电平跳变为低电平
        OUTPUT=0;   
    if(time0_num > time0_all_num)   //输出口由低电平跳变为高电平
    {
        OUTPUT=1;
        time0_num = 0;
    }
}
/*******************************************************************************
* FunctionName  : Time1(void) interrupt 3
* Description    : 定时器1中断服务函数
* Input          : None
* Output         : None
*******************************************************************************/
void Time1(void)interrupt 3
{
    TH1 = TIME1_H;
    TL1 = TIME1_L;  
    time1_num++;        //记录进入定时器中断的次数
    if(time1_all_num>time1_num) //输出口由高电平跳变为低电平
        OUTPUT = 1;
    if(time1_all_num<time1_num) //输出口由低电平跳变为高电平
    {
        OUTPUT = 0;
        time1_num = 0;
        TR1 = 0;//高电平输出结束 关闭定时器
    }
}


0.png

全部资料51hei下载地址:
单片机课程设计.rar (2.1 MB, 下载次数: 169)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:191542 发表于 2020-5-30 15:22 | 显示全部楼层
这个系统的使用讲解网站   https://b23.tv/Bxez2n
回复

使用道具 举报

ID:191542 发表于 2019-1-10 14:57 | 显示全部楼层
本帖最后由 总是离人泪 于 2019-1-11 21:48 编辑

晶振是11.0592Mhz的 ,实物运行的误差补偿已经调整好了(仿真的误差需要自己补偿)
回复

使用道具 举报

ID:191542 发表于 2019-3-16 15:26 | 显示全部楼层
在reg52.h头文件中添加这两句代码#define uint unsigned int
#define uchar unsigned char
回复

使用道具 举报

ID:284667 发表于 2019-3-30 11:59
为什么不能用呢

ID:191542 发表于 2019-5-6 22:29 | 显示全部楼层
您好,您遇到什么问题了?可以找我的,我给您解决。
回复

使用道具 举报

ID:745905 发表于 2020-6-4 11:46 | 显示全部楼层
可以调节频率吗
回复

使用道具 举报

ID:191542 发表于 2020-7-10 16:29 | 显示全部楼层
尴尬 发表于 2020-6-4 11:46
可以调节频率吗

频率可调,占空比可调,脉宽可调。全部均可通过矩阵按键实现
回复

使用道具 举报

ID:801177 发表于 2020-7-10 18:16 | 显示全部楼层
可以调节频率吗
回复

使用道具 举报

ID:191542 发表于 2020-7-18 08:42 | 显示全部楼层
郎中 发表于 2020-7-10 18:16
可以调节频率吗

频率可调,占空比可调,脉宽可调。全部均可通过矩阵按键实现
回复

使用道具 举报

ID:821033 发表于 2020-10-29 23:06 来自手机 | 显示全部楼层
好文章谢谢分享
回复

使用道具 举报

ID:88606 发表于 2020-10-31 16:27 | 显示全部楼层
这个有料!看看能不能在实际中应用到!
回复

使用道具 举报

ID:859787 发表于 2020-12-23 11:21 来自手机 | 显示全部楼层
好文章
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表