|
- /*
- 贺卡音乐IC的制作方法,音乐数据可修改,可反复擦写,接上3v电池就会响。
- 单片机STC15L104E蜂鸣器放歌程序 精准频率延时 晶振频率:12Mhz 蜂鸣器连接VCC和P3.5
- 通过配置特殊功能寄存器的方法实现IO口输出指定频率方波,若用其他芯片代替的没有该功能寄存器无法进行输出。
- 最高鸣叫频率65535Hz,最长延迟时间65535Ms,频率过低导致计算溢出则自动修改为65535Hz。
- */
- #include "STC15F104E.h"//定义头文件,包含各种特殊功能寄存器定义。
- #define FOSC 12000000L //晶振频率,可直接修改。
- sbit T1CLKO = P3^5; //蜂鸣器连接VCC和P3.5,不同芯片可能会有不同,由特殊功能寄存器决定,无法直接修改。
- unsigned int T1MS=65536-FOSC/1000; //通过晶振频率计算定时器定时1毫秒的时间。
- unsigned int ms=0;//毫秒计数延迟替减,减到0切换下一个频率并且获取该频率的延时继续替减。
- unsigned int music_pc=0;//音乐数据指针,加满或者是奇数则清零,避免看门狗出错导致该指针为奇数而导致频率和延迟数据读取错乱。
- unsigned int code music_data[130]={ //音乐频率与延迟毫秒数据,偶数地址为频率数据,奇数地址为延迟时间毫秒数据,只读数据在rom中。
- 440,500,659,375,783,125,659,250,
- 440,250,523,500,440,125,523,125,
- 440,125,523,125,659,500,659,125,
- 587,125,659,125,523,125,440,500,
- 659,375,783,125,880,250,880,250,
- 880,250,659,250,783,500,659,125,
- 783,125,659,125,783,125,880,250,
- 880,250,880,250,659,250,783,500,
- 783,250,440,250,783,250,440,250,
- 659,250,659,250,523,500,587,500,
- 587,500,587,250,523,125,587,125,
- 659,250,783,250,880,500,1318,500,
- 659,500,1318,500,659,250,1318,250,
- 659,250,1318,250,659,250,659,250,
- 523,500,587,500,587,500,587,250,
- 523,125,587,125,659,250,783,250,
- 880,1000
- };
- void InitTimer0(void){ //1毫秒定时器初始化
- TMOD = 0x01; //配置定时器工作方式
- TL0 = T1MS; //设置计数器低8位
- TH0 = T1MS >> 8; //设置计数器高8位
- EA = 1; //开全局中断
- ET0 = 1; //开定时器中断
- TR0 = 1; //开定时器计数功能
- }
- void beep(unsigned int hz){ //设置蜂鸣器频率
- if(0 < (int)(65536-FOSC/2/hz)){ //频率过低导致计算溢出
- hz=65535; //设置频率为65535hz,避免出现错误
- }
- TMOD &= 0xBF; //对内部时钟进行时钟输出
- TL1 = (65536-FOSC/2/hz); //设置计数寄存器低8位
- TH1 = (65536-FOSC/2/hz) >> 8; //设置计数寄存器高8位
- INT_CLKO = 0x02; //开时钟输出功能
- TR1 = 1; //开定时器计数
- }
- void main(){ //入口函数,所有程序从这里开始执行
- AUXR |= 0xC0; //配置AUXR寄存器,两个定时器都没有被12分频
- InitTimer0(); //初始化1毫秒定时器,每1毫秒触发1次定时器中断
- while (1); //进入死循环,只有中断后进入处理最后返回到这里
- }
- void Timer0Interrupt() interrupt 1{ //1毫秒定时器中断程序
- TL0 = T1MS; //重置1毫秒计数寄存器低8位
- TH0 = T1MS>>8;//重置1毫秒计数寄存器高8位
- WDT_CONTR=0x30; // 看门狗喂狗,避免出现错误
- if(ms==0){ //毫秒计数减到0,开始修改频率和延迟数据
- ms=music_data[music_pc+1];//修改替减时间
- beep(music_data[music_pc]); //修改鸣叫频率
- music_pc+=2;//数据指针加2,下次读取下一个频率和延迟数据
- if(music_pc>=130||music_pc&1==1){ //指针加到数据最后或者是奇数
- music_pc=0; //数据指针清零,从头开始读取音乐数据
- }
- } else { //毫秒计数没有减到0
- ms--; //每次进入中断执行毫秒减1
-
- }
- }
复制代码
|
|