点击查看代码
/**
******************************************************************************
* @file main.c
* @author
* @version
* @date 2024/06/28
* @brief 实现利用手机蓝牙控制开发板的蜂鸣器的开启/关闭,需要制定数据协议
BEEP_ON 0x01 启动
BEEP_OFF 0x00 关闭
******************************************************************************
**/
#include "stm32f4xx.h" //必须包含
#define BEEP_ON 0x01 //启动
#define BEEP_OFF 0x00 //关闭
uint8_t data;
//延时微秒 注意:Systick是24bit的递减计数器 约等于798915us,所以参数不可以超过这个值
void delay_us(u32 nus)
{
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
SysTick->LOAD = (nus * 21) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
SysTick->VAL = 0; // 清除当前数值寄存器的值
SysTick->CTRL = 1; // 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
}
//延时毫秒 注意:Systick是24bit的递减计数器 约等于798ms,所以参数不可以超过这个值
void delay_ms(u32 nms)
{
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
SysTick->LOAD = (nms * 21*1000) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
SysTick->VAL = 0; // 清除当前数值寄存器的值
SysTick->CTRL = 1; // 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
}
//前台程序就是中断服务程序,该程序是不需要手动调用的,当中断触发之后CPU会自动跳转过来执行该函数
void USART2_IRQHandler(void)
{
//判断中断是否发生
if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
{
//从USART2中接收一个字节
data = USART_ReceiveData(USART2); //一次只能接收一个字节
}
}
void BEEP_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打开了GPIO端口时钟 PF8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
void USART2_Config(u32 baud)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//打开了GPIO端口时钟 PA2和PA3
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//打开USART2的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//选择GPIO引脚的复用功能
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2 , GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3 , GPIO_AF_USART2);
//配置GPIO引脚 注意:复用模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置串口参数+对串口初始化
USART_InitStructure.USART_BaudRate = baud; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure);
//配置NVIC参数 + 对NVIC初始化
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//选择USART2的中断源,接收到数据则触发中断
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//打开串口
USART_Cmd(USART2, ENABLE);
}
//利用串口发送一个字符串
void USART2_SendString(const char *str)
{
while(*str)
{
USART_SendData(USART2,*str++);
while( USART_GetFlagStatus(USART2,USART_FLAG_TXE) == RESET );
}
}
int main()
{
//1.硬件的初始化
BEEP_Config();
USART2_Config(9600); //蓝牙
// USART2_SendString("AT\r\n"); //发送测试指令
// delay_ms(100);
//
// USART2_SendString("AT+NAMEgz2416\r\n"); //修改名称,重启生效
// delay_ms(100);
//
// USART2_SendString("AT+RESET\r\n"); //重启指令
// delay_ms(100);
while(1)
{
//判断接收到的数据
switch(data)
{
case BEEP_ON : GPIO_SetBits(GPIOF,GPIO_Pin_8);delay_ms(100);break;
case BEEP_OFF: GPIO_ResetBits(GPIOF,GPIO_Pin_8);break;
}
}
}