• 51单片机演奏兰亭序


    使用开发板为普中51-实验板 普中-2
    时钟频率:11.001081MHZ
    演示视频:
    【51单片机演奏兰亭序】 https://www.bilibili.com/video/BV12G411D7uK/?share_source=copy_web&vd_source=0f48f7cc0fef720b95e067122ac83437

    源码如下:

    数组较大,请在数组前加上code关键字

    delay.h
    #ifndef __DELAY_H__
    #define __DELAY_H__
    
    void Delayxms(unsigned int xms); //@11.0592MHz
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    delay.c
    #include 
    
    void Delayxms(unsigned int xms) //@11.0592MHz
    {
    	while (xms--)
    	{
    		unsigned char i, j;
    
    		_nop_();
    		i = 2;
    		j = 199;
    		do
    		{
    			while (--j)
    				;
    		} while (--i);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    Timer0.h
    #ifndef __TIMER0_H__
    #define __TIMER0_H__
     
    void Timer0_Init();
     
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    Timer0.c
    #include 
     
    /**
     * @brief 计时器0初始化
     */
    void Timer0_Init() // 1毫秒@11.0592MHz
    {
    	TMOD &= 0xF0; // 设置定时器模式
    	TMOD |= 0x01; // 设置定时器模式
    	TL0 = 0x66;	  // 设置定时初值
    	TH0 = 0xFC;	  // 设置定时初值
    	TF0 = 0;	  // 清除TF0标志
    	TR0 = 1;	  // 定时器0开始计时
    	// 配置中断
    	ET0 = 1;
    	EA = 1;
    	PT0 = 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    main.c
    #include 
    #include "delay.h"
    #include "Timer0.h"
    
    // 蜂鸣器端口
    sbit Buzzer = P2 ^ 5;
    
    #define SPEED 500 // 速度
    
    // 音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音#
    #define P 0
    #define L1 1
    #define L1_ 2
    #define L2 3
    #define L2_ 4
    #define L3 5
    #define L4 6
    #define L4_ 7
    #define L5 8
    #define L5_ 9
    #define L6 10
    #define L6_ 11
    #define L7 12
    #define M1 13
    #define M1_ 14
    #define M2 15
    #define M2_ 16
    #define M3 17
    #define M4 18
    #define M4_ 19
    #define M5 20
    #define M5_ 21
    #define M6 22
    #define M6_ 23
    #define M7 24
    #define H1 25
    #define H1_ 26
    #define H2 27
    #define H2_ 28
    #define H3 29
    #define H4 30
    #define H4_ 31
    #define H5 32
    #define H5_ 33
    #define H6 34
    #define H6_ 35
    #define H7 36
    
    unsigned int FreqTable[] = {
        0,
        63628, 63731, 63835, 63928, 64021, 64103, 64185, 64260, 64331,
        64400, 64463, 64524, 64580, 64633, 64684, 64732, 64777, 64820,
        64860, 64898, 64934, 64968, 65000, 65030, 65058, 65085, 65110,
        65134, 65157, 65178, 65191, 65217, 65235, 65252, 65268, 65283};
    // 音,结束标志:0xFF
    code unsigned char Music[] = {0, 0, 0, M5, M6, H1, H2, H1, H2, H3, H2, H1, H2, H3, H5, H3, H2, H1, M6, M5, H3, H5, H6, H3, H2, H2, H1, H3, H2, H2, H1, H1, H2, H3, H2, H1, M6, M5, H2, H3, H1, 0, M5, M3, M5, M6, M3, M5, M6, M5, M3, M2, M3, 0, M3, M2, M3, H1, M6, H1, M6, M5, M3, M1, M3, M2, M2, 0, M5, M5, M5, M6, M6, H1, H2, H1, M6, M5, M6, M5, M3, M2, M5, M3, M3, M2, M1, M2, M3, M2, M1, M3, M1, M1, M1, M1, 0xFF};
    // 音长,标准音为4
    code unsigned char MusicTime[] = {4, 4, 2, 2, 2, 2, 8, 2, 4, 2, 2, 12, 2, 2, 8, 2, 2, 2, 2, 2, 12, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4};
    unsigned char FreqSelect, MusicSelect;
    void main()
    {
        Timer0_Init();
        while (1)
        {
            if (Music[MusicSelect] != 0xFF)
            {
                FreqSelect = Music[MusicSelect];
                Delayxms(500 / 4 * MusicTime[MusicSelect]);
                MusicSelect++;
                TR0 = 0;     // 计时器停
                Delayxms(5); // 每个音间隔5ms
                TR0 = 1;
            }
            else
            {
                TR0 = 0;
                MusicSelect = 0;
            }
        }
    }
    
    void Timer0_Routine() interrupt 1
    {
        if (FreqTable[FreqSelect])
        {
            TL0 = FreqTable[FreqSelect] % 256; // 设置定时初值
            TH0 = FreqTable[FreqSelect] / 256; // 设置定时初值
            Buzzer = !Buzzer;                  // 翻转蜂鸣器IO口
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
  • 相关阅读:
    项目实战:中央控制器实现(1)-基本功能实现-调用Controller中的方法
    【Go入门】struct类型
    大漠插件普通定制版内存调用与com对象调用方法
    电脑如何查找重复文件?轻松揪出它!
    实现堆的各种基本运算的算法(数据结构)
    光栅投影三维重建
    C/C++调用Python
    858. Prim算法求最小生成树
    Redis之集群部署、哨兵集群
    腾讯云CentOS7下安装GUI图形界面
  • 原文地址:https://blog.csdn.net/jihuaTEL/article/details/134540208