/*****************************************************************************
** 移植配置
****************************************************************************/
#define HC08_UARTx USART3
#define HC08_ROLE 0 // 主从模式,0=slave, 1=master;与手机APP互连必须配置为从机模式
/*****************************************************************************
** 全局变量
****************************************************************************/
typedef struct
{
uint8_t flag_UARTConnect; // 标记:与开发板间的通信是否正常; 0=失败, 1=成功
uint8_t flag_TargetConnect; // 标记:与目标设备通信是否正常;0=失败, 1=成功
}xHC08_TypeDef;
extern xHC08_TypeDef xHC08; // 声明为全局变量,方便记录信息、状态
/*****************************************************************************
** 声明全局函数
****************************************************************************/
void HC08_Init(void); // 初始化串口及中断优先、AT参数配置级;
void HC08_SendData(uint8_t* data, uint16_t cnt); // 发送指定长度的数据;
void HC08_SendString(char* strTemp); // 发送字符串;
GPIO_InitTypeDef GPIO_InitStructure;
// 时钟使能
RCC->APB1ENR |= RCC_APB1ENR_USART3EN; // 使能USART1时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 使能GPIOA时钟
// GPIO_TX引脚配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // TX引脚,配置为复用推挽工作模式
GPIO_Init (GPIOB, &GPIO_InitStructure);
// GPIO_RX引脚配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; // RX引脚,配置为浮空输入工作模式
GPIO_Init (GPIOB, &GPIO_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 中断配置
NVIC_InitStructure .NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure .NVIC_IRQChannelPreemptionPriority=2 ; // 抢占优先级
NVIC_InitStructure .NVIC_IRQChannelSubPriority = 2; // 子优先级
NVIC_InitStructure .NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
//USART 初始化设置
USART_DeInit(USART3);
USART_InitStructure.USART_BaudRate = baudrate; // 串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式
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(USART3, &USART_InitStructure); // 初始化串口
USART_ITConfig(USART3, USART_IT_TXE , DISABLE );
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 使能接受中断
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); // 使能空闲中断
USART_Cmd(USART3, ENABLE); // 使能串口, 开始工作
// 发送AT指令,或字符串
void HC08_SendString(char* strTemp)
{
HC08_SendData((uint8_t *)strTemp, strlen(strTemp));
}
// 发送指定长度的数据
void HC08_SendData(uint8_t* dataBuf, uint16_t cnt)
{
while(cnt--)
{
while((HC08_UARTx->SR & 0X40)==0); // 等待上一次串口数据发送完成
HC08_UARTx->DR = *dataBuf; // 写DR,串口将的发送数据
dataBuf++;
}
}
void USART3_IRQHandler(void)
{
static uint8_t cnt=0;
static uint8_t RxTemp[256];
// 接收中断
if(USART3->SR & (1<<5))
{
RxTemp[cnt++] = USART3->DR ; // 读取数据寄存器值;注意:读取DR时自动清零中断位;
}
// 空闲中断, 用于配合接收中断,可判断一帧数据接收完成
if(USART3->SR & (1<<4)) // 检查IDLE中断标志
{
memcpy(xUSART.USART3RecivedBuffer , RxTemp , 256); // 临时数据转存为全局数据, 等待处理,注意:复制的是整个数组,包括0值,以方便字符串数据
xUSART.USART3RecivedFlag = 1; // 标记;外部程序通过检查xUSARTFlag.USART_2_Recived是否等于1, 可判断是否有新一帧数据
xUSART.USART3RecivedCNT = cnt;
cnt=0;
memset(RxTemp ,0, 256); // 临时数据空零,准备下一次的接收
USART3 ->SR; USART3 ->DR; // 清零IDLE中断标志位!! 序列清零,顺序不能错!!
/********************************************************************************
方式1:可在这里调用外部函数,处理接收到数据(不推荐)
方式2:可在外部判断USARTxRecivedFla==1,然后处理数据区xUSART.USARTxRecivedBuffer
禁 止:不可在中断里调用printf等不可重入函数!!!
示 例: 下面这一行代码, 只作示例, 输出到上位机以观察所收到的最新一帧数据, 可删除
*********************************************************************************/
USART1_printf((char*)xUSART.USART3RecivedBuffer); // 这行代码只作示例,输出USART3收到的最新一帧数据,可删除
}
}
// 本函数为main函数中的while函数
while(1) // while函数死循环,不能让main函数运行结束,否则会产生硬件错误
{
// Scheduler_Run(); // 任务轮询器; 如要使用, 清除while中其它函数(移到Scheduler文件中去), 以保证计时的准确
System_DelayMS(100); // 上面已初始化SysTick, 可直接使用delay_ms()、delay_us()
LED_RED_TOGGLE; // 红色LED 每0.5秒闪灭一次,以监察系统正常工作
if(xUSART.USART1RecivedFlag==1) // 判断上位机(USART1)是否收到新的数据
{
HC08_SendString((char *)xUSART.USART1RecivedBuffer); // 如果收到新数据,就从蓝牙发送出去
xUSART.USART1RecivedFlag=0; // 处理完了,标记清0,不然下一个while循环又会重复操作
}
// 处理HC08收到的数据
if(xUSART.USART3RecivedFlag==1) // 判断蓝牙HC08(USART3)是否收到新的数据
{
if(xUSART.USART3RecivedBuffer[0]=='0') { LED_BLUE_OFF;} // 判断收到的数据
if(xUSART.USART3RecivedBuffer[0]=='1') { LED_BLUE_ON;}
if(xUSART.USART3RecivedBuffer[0]=='3') { LED_BLUE_TOGGLE;}
xUSART.USART3RecivedFlag=0; // 处理完了,标记清0,不然下一个while循环又会重复操作
}
}
1:CSDN资源:两个开发板用HC08通信.zip-嵌入式文档类资源-CSDN下载