有了前面的探索经验,现在终于又回到了问题的起点,即串口通信问题。
5.串口通信及蓝牙透传应用
在开发板上,提供了一个供串口使用的接口CN4,由此可知串口2使用的引脚为PA2和PA3,见图图23 所示。

图23 接口CN4
串口2的初始化函数为:
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}实现串口print功能测试的主程序为:
int main(void)
{
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED4);
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_GPIO_Init();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = LED3_PIN;
HAL_GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStruct);
while (1)
{
printf("** Test finished successfully. ** \n\r");
HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_PIN);
HAL_Delay(500);
}
}为进行串口测试,其器件连接见图24所示。

图24 器件连接
经程序的编译和下载,其测试效果见图25所示,说明其功能设计是正确的。

图25 测试结果
至此,在程序的调试过程就可以不再依赖OLED屏进行信息显示啦,而是可以借助串口的print功能。
但print功能并不是我们的终极目标,实现串口的数据收发才是目的所在。
实现串口收发数据的主程序为:
int main(void)
{
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED4);
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_GPIO_Init();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = LED3_PIN;
HAL_GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStruct);
while (1)
{
while(HAL_UART_Receive(&huart2, aString, 10, 100)!= HAL_OK);
HAL_UART_Transmit(&huart2,aString, 10, 100);
HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_PIN);
HAL_Delay(500);
}
}经实际测试,其测试结果见图图26和图27所示,说明它可将接收的数据原样反馈回来。

图26 字符串收发测试

图27 字节数据收发测试
这样,我们不仅能发送指令对外部的串口设备进行控制,还能接收外部发送的数据以进行相应的分析及显示处理。单凭串口的收发功能,就可令其平添更强的功能,如对MP3语音模块的控制来实现乐曲的播放控制及相应的语音提示功能,也可通过语音设备模块来设备语音指令,进而实现语音指令控制等等。
当然,目前更关心的是它与蓝牙透传模块相配合来记录与手机的信息传递,其连接形式见图28所示。

图28 连接形式
在此连接形式下,可实现检测数据的发送及手机控制LED或外设,板载LED的电路见图29所示。

图29 LED电路
相应的功能测试主程序为:
int main(void)
{
uint8_t temp=0;
uint8_t humi=0;
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED4);
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_GPIO_Init();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = LED3_PIN|JDQ_PIN;
HAL_GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStruct);
DHT11_Init();
while (1)
{
if(HAL_UART_Receive(&huart2, kzm, 1, 100)== HAL_OK)
{
if(kzm[0]==0X36)
{
HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(JDQ_GPIO_PORT, JDQ_PIN, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(JDQ_GPIO_PORT,JDQ_PIN, GPIO_PIN_SET);
}
}
else
{
DHT11_Read_Data(&temp,&humi);
printf("temp= %d humi= %d \n\r",temp,humi);
HAL_Delay(500);
}
}
}经实测,在手机发送数据0X36时即可电路LED灯,发送其它数据则会消灭LED灯。在连接继电器时,可控制相应的小家电。
在连接温湿度传感器的情况下,则可以定时地将检测的温湿度值发送到手机上,其测试效果见图30至图32所示。

图30 搜寻蓝牙设备

图31 手机发送控制码

图32 手机接收检测数据
6.温湿度检测
DHT11是一种数字式的单总线器件,单用一个GPIO引脚再配合延时函数的使用即可实现检测处理。
DHT11与开发板的连接关系如图33所示,即使用引脚PC15来收发数据。

图33 器件连接
对传感器所用引脚进行配置的函数为:
void DHT11_Init()
{
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = DHT11_PIN;
HAL_GPIO_Init(DHT11_GPIO, &GPIO_InitStruct);
}将引脚设置成输入模式的函数为:
void DHT11_IN()
{
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pin = DHT11_PIN;
HAL_GPIO_Init(DHT11_GPIO, &GPIO_InitStruct);
}将引脚设置成输出模式的函数为:
void DHT11_OUT()
{
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pin = DHT11_PIN;
HAL_GPIO_Init(DHT11_GPIO, &GPIO_InitStruct);
}读取温湿度的函数为:
int DHT11_Read_Data(char *temp,char *humi)
{
char buf[5],i;
DHT11_Reset();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}
else return 1;
return 0;
}实现温湿度检测的主程序为:
int main(void)
{
uint8_t temp=0;
uint8_t humi=0;
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED4);
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_GPIO_Init();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = LED3_PIN;
HAL_GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStruct);
DHT11_Init();
while (1)
{
DHT11_Read_Data(&temp,&humi);
printf("temp= %d humi= %d \n\r",temp,humi);
HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_PIN);
HAL_Delay(500);
}
}经程序的编译和下载,其测试结果如图34和图35所示,说明该功能设计正确。

图34 检测结果

图35 手触升温检测
至此,当初设置的全部目标就全部完成啦!
我要赚赏金
