8051/2单片机基础 实现开关,驱动2位的共阳极数码管显示小数,驱动喇叭播放音乐

1. 实现开关,开关2次后,LED闪烁4次 
2. 实现驱动共阳极数码关显示 3.1
3. 驱动喇叭播放 ,dao,re,mi,fa,sao,la,xi

C代码:

/**
* 8051 DEMO 2
* 1. 实现开关,开关2次后,LED闪烁4次 
* 2. 实现驱动共阳极数码关显示 3.1
* 3. 驱动喇叭播放 ,dao,re,mi,fa,sao,la,xi
* 8051 规定中断号如下
* INT0  中断号  0
* INT1  中断号  2
* T0    中断号  1
* T1    中断号  3
* 串口  中断号   4
*/

#include "REG52.H"
#include "intrins.h"

//LED
sbit led  = P2^0;
//控制数码管
sbit ls1 = P2^1;
sbit ls2 = P2^2;
//输出脉冲信号让蜂鸣器工作
sbit sound = P2^3;

//类型定义
typedef unsigned char U8;
typedef unsigned int I8;

//声明全局计数变量 count
I8 count;

//使用定时器,给端口上输出一个脉冲,从而形成声音进行播放

//定义频率
#define DAO 262 //低音"1"的频率262Hz
#define RE 286  //低音"2"的频率286Hz
#define MI 311  //低音"3"的频率311Hz
#define FA 349  //低音"4"的频率349Hz
#define SAO 392 //低音"5"的频率392Hz
#define LA 440  //低音"6"的频率440Hz
#define XI 494  //低音"7"的频率494Hz

//定义节拍
#define B4_1 2000   // 4/1拍,2000ms
#define B3_1 1500   // 3/1拍,1500ms
#define B2_1 1000   // 2/1拍,1000ms  
#define B3_2 750    // 3/2拍,750ms
#define B1_1 500    // 1拍,500ms
#define B3_4 313    // 3/4拍,313ms
#define B1_2 250    // 1/2拍,250ms
#define B1_3 125    // 1/3拍,125ms
#define B1_4 63     // 1/4拍,63ms

//音乐延迟ms
void delay_ms(I8 ms)   //误差 -0.651041666667us
{
    unsigned char a,b;
    I8 z;
    for(z=0;z<ms;z++){
        for(b=102;b>0;b--)
            for(a=3;a>0;a--);
    }
}

//音乐,dao,re,mi,fa,sao,la,xi
int code music[] = {
    DAO,RE,MI,FA,SAO,LA,XI
};


//声明中断
void int0_init()
{
    IT0 = 1; //低电平触发
    EX0 = 1; //打开外部中断0
    EA = 1; //打开全局中断
}

//中断处理
void int0_start() interrupt 0
{
    EX0 = 0;//停止中断,进行业务逻辑处理
    count = count+1; //统计开关闭合的次数
    EX0 = 1 ;//处理完毕,打开中断
}

//数码管显示 3.1 , 由于人体的视觉暂留想象,对于刷新频率<20ms ,则看到的是一起显示的
void display31()
{
    ls1 = 0; //打开第1个数字通到
    P1 = 0xF9; //显示数字:1
    delay_ms(10);
    P1 = 0xFF; //消隐
    ls1 = 1; //关闭第1个数字通到

    ls2 = 0; //打开第2个数字通到
    P1 = 0xB0; //显示数字:3
    delay_ms(10);
    P1 = 0x7F; //显示数字:.
    delay_ms(10);
    P1 = 0xFF; //消隐
    ls2 = 1; //关闭第2个数字通到
}

//初始化定时中断
void timer_init()
{
    TMOD = 0X00;
    ET0 = 1; //打开定时器0 的中断
    EA = 1; //打开总中断
    TR0 = 1; //打开定时器0
}

int pv;  //频率切换
I8 ii; //计频率切换
void timer_start() interrupt 1
{   
    pv = music[ii];
    TH0 = (65536 - pv*1000) / 256;//(65536-X)为定时器初值,如定时1ms
    TL0 = (65536 - pv*1000) % 256;
    sound = !sound;
}
//播放音乐 一遍后继续下面操作
void play_music(){
    while(1){
        //使用2拍
        if(ii>7)
        {
            ii= 0;
            break;
        }
        delay_ms(B2_1);
        ii = ii + 1;
    }
}

void main()
{
    I8 i;

    count = 0;
    led = 1;
    ls1 = 1;
    ls2 = 1;
    sound = 1;
    ii = 0;

    //中断
    int0_init();

    //定时器
    timer_init();
    //播放
    play_music();
    
    while (1)
    {   
        if(count == 2 ){ //次数超过2次后
            for(i=0;i<4;i++){
                led = 0;
                delay_ms(1000);
                led = 1;
                delay_ms(1000);
            }
            //执行完毕,则把count赋值为0
            count = 0;
        }
        display31();
    } 
}

感谢您的支持,写的文章如对您有所帮助,开源不易,请您打赏,谢谢啦~

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值