目录
-
1. 环境 -
2. 相关配置 -
3. 相关资料 -
4. mqtt服务搭建(EMQX) -
5. mqtt协议代码
1.环境配置
- 开发环境 STM32IDE
- STM32H743_NUCLEO开发板(LAN8742A芯片)
- 开发板图片通过以太网口通信
2. 相关配置
3. 相关资料
4.mqtt服务器搭建(EMQX)
5. mqtt协议代码
1.这里为了能够看到输出信息,printf重定向,通过窗口打印。这里我使用的UART2打印。
#include "stdio.h"
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
PUTCHAR_PROTOTYPE
{
if(ch =='\n')
{
HAL_UART_Transmit(&huart2, (void *)"\r", 1, 30000);
}
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
2.在使用LWIPping通时,我们的功能已经包含的MQTT协议相关的代码库,因此我们用就完事了 根据http://www.nongnu.org/lwip/2_0_x/group__mqtt.htmlMQTT client 配置说明 复制粘贴过来。main.c代码中添加mqtt相关
#include "main.h"
#include "adc.h"
#include "lwip.h"
#include "usart.h"
#include "gpio.h"
#include "mqtt_opts.h"
#include "mqtt_priv.h"
#include "mqtt.h"
#include "string.h"
void SystemClock_Config(void);
static void MPU_Config(void);
uint8_t Get_Value,Get_Volt;
uint8_t buff[64];
void GetAdcValue()
{
if(HAL_OK == HAL_ADC_Start(&hadc3))
{
if(HAL_OK == HAL_ADC_PollForConversion(&hadc3, 10000))
{
Get_Value = (int32_t)((uint16_t)HAL_ADC_GetValue(&hadc3) * 100 /(0xFFF));
Get_Volt = ((Get_Value * 0xFFF) / 100) * 0.8;
printf("Current Volt : %d mv\r\n",Get_Value);
}
}else
{
printf("Conversion Wait!\r\n");
}
}
void example_do_connect(mqtt_client_t *client);
static void mqtt_connection_cb(mqtt_client_t *client,void *arg, mqtt_connection_status_t status);
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len);
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags);
void mqtt_sub_request_cb(void *arg, err_t err);
void mqtt_pub_request_cb(void *arg, err_t result);
void example_publish(mqtt_client_t *client, void *arg);
int main(void)
{
MPU_Config();
SCB_EnableICache();
SCB_EnableDCache();
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_LWIP_Init();
u32_t base;
Get_Value = 0;
base = HAL_GetTick();
printf("MQTT Start!\r\n");
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
mqtt_client_t static_client;
static_client.conn_state=0;
example_do_connect(&static_client);
while (1)
{
if((HAL_GetTick() - base) >= 1000)
{
base = HAL_GetTick();
HAL_GPIO_TogglePin(LD1_GPIO_Port,LD1_Pin);
example_publish(&static_client,(void *)mqtt_pub_request_cb);
}
MX_LWIP_Process();
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
__HAL_RCC_D2SRAM3_CLK_ENABLE();
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_CSI|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.CSIState = RCC_CSI_ON;
RCC_OscInitStruct.CSICalibrationValue = RCC_CSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 2;
RCC_OscInitStruct.PLL.PLLN = 16;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
#include "stdio.h"
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
PUTCHAR_PROTOTYPE
{
if(ch =='\n')
{
HAL_UART_Transmit(&huart2, (void *)"\r", 1, 30000);
}
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
void example_do_connect(mqtt_client_t *client)
{
struct mqtt_connect_client_info_t ci;
ip_addr_t mqttServerIpAddr;
err_t err;
memset(&ci, 0, sizeof(ci));
ci.client_id = "lwip_test";
IP4_ADDR(&mqttServerIpAddr, 172, 20, 35, 200);
err = mqtt_client_connect(client, &mqttServerIpAddr, 1883, mqtt_connection_cb, 0, &ci);
if (err != ERR_OK) {
printf("mqtt_connect return %d\n", err);
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
}
}
static void mqtt_connection_cb(mqtt_client_t *client,void *arg, mqtt_connection_status_t status)
{
err_t err;
if(status == MQTT_CONNECT_ACCEPTED)
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
printf("mqtt_connection_cb: Successfully connected!\r\n");
mqtt_set_inpub_callback(client, mqtt_incoming_publish_cb,
mqtt_incoming_data_cb, arg);
err = mqtt_subscribe(client, "subtopic", 2, mqtt_sub_request_cb, arg);
if (err != ERR_OK) {
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
}
}
else
{
printf("mqtt_connection_cb: Failed %d\r\n",status);
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
example_do_connect(client);
}
}
void mqtt_sub_request_cb(void *arg, err_t err)
{
printf("Subscribe result: %d\n", err);
}
static int inpub_id;
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
printf("Incoming publish at topic \" %s \" with total length %u\r\n", topic, (unsigned int)tot_len);
if(strcmp(topic,"subtopic") == 0)
{
inpub_id = 0;
}
else if (topic[0] == 'A')
{
inpub_id = 1;
}
else
{
inpub_id = 2;
}
}
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
uint8_t tempBuff[20] = {0};
uint8_t i ;
for(i = 0; i < len; i++)
{
tempBuff[i] = data[i];
}
tempBuff[i] = 0;
printf("Incoming publish payload with length %d, flags %u\n", len, (unsigned int)flags);
if(flags & MQTT_DATA_FLAG_LAST)
{
if(inpub_id == 0 )
{
if(tempBuff[len] == 0)
{
printf("mqtt_incoming_data_cb: %s\n", (const char *)data);
}
}
else if(inpub_id == 1)
{
}
else
{
}
}
}
void example_publish(mqtt_client_t *client, void *arg)
{
const char *pub_payload = "Hello,MQTT!\r\n";
err_t err;
u8_t qos = 2;
u8_t retain = 0;
err = mqtt_publish(client, "pub_topic", pub_payload, strlen(pub_payload),
qos, retain, mqtt_pub_request_cb, arg);
if (err != ERR_OK) {
printf("Publish err: %d.\r\n", err);
} else {
printf("Publish Success.\r\n");
}
}
void mqtt_pub_request_cb(void *arg, err_t result) {
if (result != ERR_OK) {
printf("Publish result: %d\n", result);
}
}
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
HAL_MPU_Disable();
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30044000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif
TIPS:只需要修改MQTTServer地址,这个地址就是你搭建EMQX服务器机器的IP地址。端口号1883
IP4_ADDR(&mqttServerIpAddr, xxx, xxx, xxx, xxx);
注意: MQTTServer地址,必须和你开发板的IP地址处于同一网段。
测试结果
在main函数中,我们设定主题 “pub_topic” ,发布“Hello,MQTT”信息。因此我们需要在另外一个客户段订阅“pub_topic”主题,能够接收“Hello, MQTT”说明MQTT搭建完成。
- 打开端口查看是否发布成功
- 通过我们搭建的EMQX中的tools来订阅“pub_topic”主题,需要修改的只有我们订阅的主题改为“pub_topic”。其余默认。
可以看到消息已接收到,说明MQTT搭建成功。
|