2. 电路原理:按键接PB2口,蜂鸣器接PD4口,当按下按键时STM8利用TIM2的PWM模式驱动蜂鸣器就发出“123”的和弦声音。
3. 采用IAR FOR STM8开发环境,外部晶振16M。
4. 程序代码如下:
/********************************************************************************
* 文件名称:STM8_Buzzer.c
* 开发环境:IAR FOR STM8 1.20
* 作者: 电子熊
* http://www.dpjzj.com
********************************************************************************/
#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<MS; 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);
}
//端口设置
void Hard_Init(void)
{
PB_DDR_DDR2 = 0; // 配置PB端口的方向寄存器PB2输入
PB_CR1_C12 = 1; // 设置PB2带上拉输入
PB_CR2_C22 = 0; // 禁止外部中断
}
void Devices_Init(void)
{
Delay_ms(200);
CLK_Init();
Hard_Init();
SysClk_Init();
Buzzer_Init();
}
//主程序
void main( void )
{
Devices_Init();
while(1)
{
if(SysDeal_Flag == 1)
{
Key_Flag = Scan_Key();
if(Key_Flag >= 1)
{
Buzzer_Start( BELL_MODE2 );
}
SysDeal_Flag = 0;
}
if(SendData_Flag ==1)
{
SendData_Flag = 0;
Bell_DealFun();
}
if(K_Flag == 1)
{
Get_Key();
K_Flag = 0;
}
}
}
介绍如何使用STM8单片机通过PWM模式控制蜂鸣器发出和弦声音,包括电路连接、程序设计及定时中断实现。

1万+


被折叠的 条评论
为什么被折叠?



