历史上的今天
今天是:2025年01月02日(星期四)
2020年01月02日 | 基于STM8单片机的蜂鸣器和弦声音的设计
2020-01-02 来源:eefocus
1. 实验功能:本实验的功能是利用STM8单片机控制蜂鸣器发出和弦声音。
2. 电路原理:按键接PB2口,蜂鸣器接PD4口,当按下按键时STM8利用TIM2的PWM模式驱动蜂鸣器就发出“123”的和弦声音。
3. 采用IAR FOR STM8开发环境,外部晶振16M。
4. 程序代码如下:
/********************************************************************************
* 文件名称:STM8_Buzzer.c
* 开发环境:IAR FOR STM8 1.20
********************************************************************************/
#include "iostm8s105s4.h"
#define uchar unsigned char
#define uint unsigned int
uchar SysDeal_Flag = 0;
uchar Sys_Count = 0;
uchar SendData_Flag =0;
uchar K_Flag = 0;
#define Sys_Time 99 //100*4us = 400us
#define Sys_Prescaler 6 //2^6 = 64
#define Key_In_Power PB_IDR_IDR2
#define Key_Delay 10
uchar Key_In = 0;
uchar Key_Value = 0;
uchar Key_Flag = 0;
#define BELL_PWM1 640 //320us
#define BELL_PWM2 564 //282us
#define BELL_PWM3 540 //270us
#define BELL_PWM4 460 //230us
#define BELL_PWM5 408 //204us
#define Buzzer_Stop() (TIM2_CR1 = 0x00)
#define BELL_MODE2 0
uchar Buz_Time = 0;
uchar Buz_State = 0;
uchar Buz_Mode = 0;
uchar Buz_Start = 0;
const uint BUZ_PWMTAB[][11]=
{
{BELL_PWM3,BELL_PWM3, BELL_PWM4,BELL_PWM4, BELL_PWM5,BELL_PWM5, 0xff,0xff,0xff,0xff,0xff}
};
const uchar BUZ_TIMETAB[][11]=
{
{8,10,6,10,6,20,0xff,0xff,0xff,0xff,0xff}
};
void Delay_ms( uint ms )
{
uint i,j;
for( j=0; j
for( i=0; i<1000; i++ )
{;}
}
}
void CLK_Init(void)
{
CLK_ECKR=0x03;//外部时钟寄存器 外部时钟准备就绪,外部时钟开
CLK_SWCR=0x02;//切换控制寄存器 使能切换机制
CLK_SWR=0xB4;//主时钟切换寄存器 选择HSE为主时钟源*/
while (!(CLK_SWCR & 0x08));
CLK_CSSR=0x01;//时钟安全系统寄存器
}
void SysClk_Init(void)
{
asm("sim");
TIM4_IER = 0x00; //禁止中断
TIM4_EGR = 0x01; //允许产生更新事件
TIM4_PSCR = Sys_Prescaler;
TIM4_ARR = Sys_Time;
TIM4_CNTR = Sys_Time;
//定时周期= 400us
TIM4_CR1 = 0x01;
TIM4_IER = 0x01;
asm("rim");
}
#pragma vector = TIM4_OVR_UIF_vector
__interrupt void TIM4_OVR_UIF(void)
{
TIM4_SR = 0x00;
Sys_Count ++;
//---------------------------------------
if( Sys_Count % 5 == 1 ) //2ms
{
SysDeal_Flag = 1;
}
else if(Sys_Count == 5)
{
SendData_Flag =1;
}
else if(Sys_Count >= 15)
{
Sys_Count = 0;
}
else
{
K_Flag = 1;
}
}
void Buzzer_Init(void)
{
PD_DDR |= 0x90; // 配置PD4方向为输出
PD_CR1 |= 0x90; // 设置PD4推挽输出
PD_CR2 &= 0x6f;
//------------------------------------
TIM2_PSCR = 3; //8分频。f=16m/8=2m----0.5us
TIM2_CCMR1 = 0x70; // PWM 模式 2
TIM2_CCER1 = 0x03; // CC1配置为输出
}
void Buzzer_Pwm(uint timenum)
{
TIM2_ARRH = (uchar)(timenum>>8);
TIM2_ARRL = (uchar)(timenum);
TIM2_CCR1H = (uchar)(timenum>>9);
TIM2_CCR1L = (uchar)(timenum>>1);
TIM2_CR1 = 0x01; // 计数器使能,开始计数
}
void Bell_DealFun(void)
{
static uchar index = 0;
switch( Buz_State )
{
case 0:
Buz_Time = 0;
Buzzer_Stop();
index = 0;
if( Buz_Start == 1 )
{
Buz_State ++;
Buzzer_Pwm( BUZ_PWMTAB[Buz_Mode][index] );
}
break;
case 1:
Buz_Time++;
if( Buz_Time >= BUZ_TIMETAB[Buz_Mode][index] )
{
Buz_Time = 0;
Buz_State = 2;
index ++;
if( BUZ_TIMETAB[Buz_Mode][index] == 0xff )
{
Buz_State = 0;
Buzzer_Stop();
Buz_Start = 0;
}
else
{
Buzzer_Pwm( BUZ_PWMTAB[Buz_Mode][index] );
}
}
break;
case 2:
Buz_Time++;
if( Buz_Time >= BUZ_TIMETAB[Buz_Mode][index] )
{
Buz_Time = 0;
Buz_State = 1;
index ++;
if( BUZ_TIMETAB[Buz_Mode][index] == 0xff )
{
Buz_State = 0;
Buzzer_Stop();
Buz_Start = 0;
}
else
{
Buzzer_Pwm( BUZ_PWMTAB[Buz_Mode][index] );
}
}
break;
default:
Buz_State = 0;
Buz_Time = 0;
index = 0;
break;
}
}
void Buzzer_Start(uchar mode)
{
if( Buz_Start == 0 )
{
Buz_Mode = mode;
Buz_Start = 1;
}
}
void Get_Key(void)
{
Key_In = 0;
if(!Key_In_Power)
{
Key_In |= 0x01;
}
}
uchar Scan_Key(void)
{
static uchar Key_Task=0,Key_Count=0;
switch( Key_Task )
{
case 0:
if( Key_In != 0 )
{
Key_Task = 1;
Key_Count = 0;
}
break;
case 1:
Key_Count++;
if( Key_Count >= Key_Delay )
{
Key_Task = 2;
Key_Count = 0;
}
break;
case 2:
if( Key_In != 0 )
{
Key_Task = 3;
Key_Count = 0;
Key_Value = Key_In;
return(1);
}
else
{
Key_Task = 0;
}
break;
case 3:
if( Key_In == 0 )
{
Key_Task = 0;
Key_Count = 0;
}
break;
default:
Key_Task = 0;
Key_Count = 0;
break;
}
return(0);
}
史海拾趣
|
我在这个网站得到一个解决方法:http://www.mscto.com/VC/25800105.html,但是存问题。 摘录如下: Microsoft eMbedded Visual C V3.0或更高版本,该软件是免费的(您需要支付运 ...… 查看全部问答> |
|
void read_from_binary_file(char * instream, int & count) { int size=0; long curpos; FILE *fp=NULL; if((fp=fopen ...… 查看全部问答> |
|
在驱动程序里面,在XXX_IOControl()里面定义的...IOCTL_POWER_OFF...,我在应用程序里面,用DeviceIoControl(hFile,IOCTL_POWER_OFF,NULL,0,NULL,0,NULL,NULL)....结果程序报错: \'IOCTL_POWER_OFF\' : undeclared identifier... 是不是不能 ...… 查看全部问答> |
|
我刚重装的系统,可是发现没有图片查看器!这是怎么一回事!害的我要查看图片还要另外装个专门的看图软件 acdsee 呢,真是麻烦,那为高手帮我解决一下,帮我找回它!… 查看全部问答> |
|
通知:下载中心论坛专版在今天调整了主题,由原来的“随便聊聊、我要推荐、求资源、精华汇总、活动专区、我的建议”调整为现在的“单片机、电子电路、嵌入式系统、其他资源、电子书专区、活动公告、资源讨论”7个新主题。 每个主题中都有很多 ...… 查看全部问答> |
|
请教各位朋友!!如题设一IO口为输入,初始为低电平,收到一高平信号,相对这个高电平采100个点,如果这100个点都是高,则这个收到的高电平信号有效。不知道该怎么写这个程序??请帮帮忙吧… 查看全部问答> |




