硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6205|回复: 4
收起左侧

EMP570实验一:蜂鸣器

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107294
QQ
发表于 2013-9-30 16:12:07 | 显示全部楼层 |阅读模式
1.  程序分析
2.  RTL分析
3.  功能仿真
4.  时序仿真



1.  程序分析(参考iCore在CPLD上面实现):
//--------------------Timescale---------------------------//
`timescale 1 ns / 1 ps
//--------------------Module_Beep-------------------------//
module beep(
    CPLD_CLK,
    Beep
    );


    input  CPLD_CLK;
    output Beep;
                                    //板载晶振CPLD_CLK为50MHz
//--------------------RST_n-------------------------------//
/*
    下面的这个程序非常的好,方便于那些没有外置复位按键的。
*/
    reg [1:0] cnt = 2'd0;


    always @(posedge CPLD_CLK)
        if (cnt == 2'd3)
            cnt <= 2'd3;
        else
            cnt <= cnt + 1'd1;


    wire RST_n = (cnt == 2'd3); //上电复位,3个时钟周期后RST_n一直为1


//--------------------CLK_5MHz----------------------------//
/*
    下面的这个程序做一个十分频
*/
    reg [4:0] cnt_5MHz = 4'd0;
   
    always @(posedge CPLD_CLK or negedge RST_n)
        if (!RST_n)
            cnt_5MHz <= 4'd0;
        else if (cnt_5MHz == 4'd9)
            cnt_5MHz <= 4'd0;
        else
            cnt_5MHz <= cnt_5MHz + 1'd1;
            
    wire CLK_5MHz = (cnt_5MHz == 4'd9); //经10分频得到CLK_5MHz


//--------------------T_600ms-----------------------------//
/*
    这里是每过600毫秒状态切换一次
*/
    parameter T_600ms = 22'd300_0000; //定时600ms


    reg [2:0] state = 3'd0; //8个发音状态
    reg [21:0] cnt_600ms = 22'd0; //定时600ms计数器


    always @(posedge CPLD_CLK or negedge RST_n)
        if (!RST_n)
            begin
                state <= 3'd0;
                cnt_600ms <= 22'd0;
            end
        else if (CLK_5MHz)
            begin
                if (cnt_600ms == T_600ms) //计时600ms
                    begin
                        cnt_600ms <= 22'd0;
                        state <= state + 1'd1; //每600ms,state加1,从0~7循环计数
                    end                                    //在8个状态之间一直循环
                else
                    cnt_600ms <= cnt_600ms + 1'd1; //定时计数器计数
            end


//--------------------Scale-------------------------------//
/*
   选择相应的状态进行输出
*/
    parameter scale1 = 12'd3822, //“duo”音对应的频率值
              scale2 = 12'd3405, //“rui”音对应的频率值
              scale3 = 12'd3034, //“mi”音对应的频率值
              scale4 = 12'd2865, //“fa”音对应的频率值
              scale5 = 12'd2551, //“se”音对应的频率值
              scale6 = 12'd2273, //“la”音对应的频率值
              scale7 = 12'd2024, //“xi”音对应的频率值
              scale8 = 12'd1911; //“duo”音(比第一个“duo”音高一个八度)
              
    reg [11:0] scale = 12'd0; //控制在每个状态的频率值


    always @(posedge CPLD_CLK or negedge RST_n)
        if (!RST_n)
            scale <= 12'd0;
        else
            case (state)
                3'd0: scale = scale1;
                3'd1: scale = scale2;
                3'd2: scale = scale3;
                3'd3: scale = scale4;
                3'd4: scale = scale5;
                3'd5: scale = scale6;
                3'd6: scale = scale7;
                3'd7: scale = scale8;
            endcase //在8个音之间一直循环,每个音发声时长600ms


//--------------------Beep--------------------------------//
    reg Beep_r = 1'd0; //蜂鸣器寄存器
    reg [11:0] cnt_scale = 12'd0; //频率计数器
   
    always @(posedge CPLD_CLK or negedge RST_n)
        if (!RST_n)
            begin
                Beep_r <= 1'd0;
                cnt_scale <= 12'd0;
            end
        else if (CLK_5MHz)
            begin
                if (cnt_scale >= scale) //达到设定频率值
                    begin
                        cnt_scale <= 12'd0;
                        Beep_r <= !Beep_r; //蜂鸣器发出与设定频率值对于的音
                    end
                else
                    cnt_scale <= cnt_scale + 1'd1; //频率计数器计数
            end
            
    assign Beep = Beep_r; //蜂鸣器发音
        
//--------------------Endmodule---------------------------//
endmodule
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107294
QQ
 楼主| 发表于 2013-9-30 16:39:05 | 显示全部楼层
看RTL视图是一个好习惯
1.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107294
QQ
 楼主| 发表于 2013-9-30 16:44:29 | 显示全部楼层
功能仿真

`timescale 1 ns/ 1 ns
module beep_vlg_tst();


reg CPLD_CLK;                                             
wire Beep;
                     
beep i1 (
    .Beep(Beep),
    .CPLD_CLK(CPLD_CLK)
);
initial
    begin
      CPLD_CLK = 0;
       forever
          #10  CPLD_CLK = ~CPLD_CLK;
     end
                                       
endmodule
2.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107294
QQ
 楼主| 发表于 2013-9-30 16:47:22 | 显示全部楼层
做完系统时钟的时钟约束以后的,modelsim仿真图如下
3.png


4.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107294
QQ
 楼主| 发表于 2013-10-1 09:19:43 | 显示全部楼层
1_beep.zip (2.75 MB, 下载次数: 91)
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-25 02:56 , Processed in 0.170218 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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