学习51的时候看了定时器设计的门铃,在32之中我将其用滴答计时器实现。
将程序下载到开发板上之后,按下上键蜂鸣器会发出ding,dong的声音,然后停下不发声,程序中使用led1来检测我们的程序是否正常的在运作中
main.c
/************************************************************************** 实验现象 : 按下ZET6板子的上键会发出叮咚的响声,类似于门铃
* 2020-2-14 12:26**************************************************************************/#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "beep.h"
#include "key.h"#define ModeNum 2
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
int main()
{u16 j = 0, n, flag, i;u8 ding, dong;SysTick_Init(72);LED_Init();BEEP_Init();KEY_init();while(1){j = KEY_Scan(0); //使用j变量获取按键按下的键if(j == KEY_UP) //按下上键表示按下门铃{flag = 0;}if(flag != ModeNum) //在flag为0/1模式才进行i的++{ i++;}//if(i == 1000) 此处与后面的delay注释又是一组响声if(i == 2000){i = 0;if(flag < ModeNum){flag++;}}if(flag == 0) //flag为0的时候发出ding的声音{ding++;if(ding == 1){ding = 0;beep = ~beep;}}else if(flag == 1) //flag为1的时候发出dong的{dong++;if(dong == 2){dong = 0;beep = ~beep;}} n++;if(n%250 == 0)led1=!led1;delay_us(250);//delay_us(500);}
}
beep.h
#ifndef _beep_H
#define _beep_H#include "system.h"/* 蜂鸣器时钟端口、引脚定义 */
#define BEEP_PORT GPIOB
#define BEEP_PIN GPIO_Pin_5
#define BEEP_PORT_RCC RCC_APB2Periph_GPIOB#define beep PBout(5)void BEEP_Init(void);#endif
beep.c
#include "beep.h"/*******************************************************************************
* 函 数 名 : BEEP_Init
* 函数功能 : 蜂鸣器初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/void BEEP_Init() //端口初始化
{GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量,用来初始化GPIORCC_APB2PeriphClockCmd(BEEP_PORT_RCC,ENABLE); /* 开启GPIO时钟 *//* 配置GPIO的模式和IO口 */GPIO_InitStructure.GPIO_Pin=BEEP_PIN; //选择你要设置的IO口GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置推挽输出模式GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率GPIO_Init(BEEP_PORT,&GPIO_InitStructure); /* 初始化GPIO */
}
key.h
#ifndef _KEY_H
#define _KEY_H#include "system.h"
#define KEY_UP_Pin GPIO_Pin_0
#define KEY_DOWN_Pin GPIO_Pin_3
#define KEY_LEFT_Pin GPIO_Pin_2
#define KEY_RIGHT_Pin GPIO_Pin_4 #define KEY_PORT GPIOE
#define KEY_UP_PORT GPIOA//使用位操作定义
#define K_UP PAin(0)
#define K_DOWN PEin(3)
#define K_LEFT PEin(2)
#define K_RIGHT PEin(4)//定义各个按键值
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 3
#define KEY_RIGHT 4 void KEY_init(void);
u8 KEY_Scan(u8 mode);
#endif
key.c
#include "key.h"
#include "Systick.h"void KEY_init(void)
{GPIO_InitTypeDef GPIO_InitSturcture;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitSturcture.GPIO_Mode=GPIO_Mode_IPD;GPIO_InitSturcture.GPIO_Pin=KEY_UP_Pin;GPIO_InitSturcture.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(KEY_UP_PORT,&GPIO_InitSturcture);GPIO_InitSturcture.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitSturcture.GPIO_Pin=KEY_DOWN_Pin|KEY_LEFT_Pin|KEY_RIGHT_Pin;GPIO_InitSturcture.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(KEY_PORT,&GPIO_InitSturcture);
}
//0-单 1-多
u8 KEY_Scan(u8 mode)
{static u8 key = 1;if(key == 1 && (K_UP ==1 || K_LEFT==0||K_RIGHT==0||K_DOWN==0)){delay_ms(10);//单次key=0;if(K_UP ==1 ){return KEY_UP;}else if(K_LEFT==0){return KEY_LEFT;}else if(K_RIGHT == 0){return KEY_RIGHT;}else if(K_DOWN==0){return KEY_DOWN;}}else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1) //无按键按下{key=1;}if(mode == 1){key=1;}return 0;
}
Systick.h
#ifndef _SysTick_H
#define _SysTick_H#include "system.h"void SysTick_Init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);#endif
Systick.c
#include "SysTick.h"static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟的1/8
//SYSCLK:系统时钟频率
void SysTick_Init(u8 SYSCLK)
{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); fac_us=SYSCLK/8; fac_ms=(u16)fac_us*1000;
} //延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{ u32 temp; SysTick->LOAD=nus*fac_us; //时间加载 SysTick->VAL=0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器
}//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{ u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)SysTick->VAL =0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器
}
本文发布于:2024-02-03 01:28:53,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170689493247755.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |