[MM32生态] MM32与DeepSeek的融合:智能交互技术的突破与创新

[复制链接]
 楼主| 发表于 2025-2-6 17:47 | 显示全部楼层 |阅读模式
#申请原创#   @21小跑堂

1.DeepSeek
2025春节期间,DeepSeek火了……DeepSeek是由杭州深度求索人工智能基础技术研究有限公司开发的大型语言模型,不仅性能超过ChatGPT,运行的成本还远低于它。DeepSeek目前提供了2种使用方式,一是通过网页在线或者是APP软件可以进行免费的对话,二是通过API开放平台与DeepSeek服务器进行对接交互。
1.png


2.网页版DeepSeek
我们可以通过打开DeepSeek官网(https://www.deepseek.com),点击开始对话,就可以跳转到DeepSeek网页版(https://chat.deepseek.com/),与DeepSeek进行交流了。这个是免费使用的,当前使用人也比较多,经常会出现服务器忙的提示……
2.png


3.DeepSeek API开放平台
通过DeepSeek的API开放平台,我们可以将DeepSeek应用到我们的应用程序当中,通过接口调用与DeepSeek之间完成交互;在DeepSeek在线接口文档(https://api-docs.deepseek.com/zh-cn/)中阐述了当前支持的开发方式有CURL、PYTHON、GO、NODEJS、RUBY、CSHARP、PHP、JAVA、POWERSHELL等等……
在使用DeepSeek API开发平台之前,我们需要先注册一个DeepSeek账号,然后在API开放平台中创建一个API key,这个API key就是我们通过其它开发软件连接到DeepSeek的凭证。
3.png
通过API开放平台使用DeepSeek是收费的,收费标准是根据每百万输出tokens来计费的;对于我们想体验一下通过API开放平台来操作DeepSeek的开发人员,DeepSeep赠送了10块钱的体验优惠,前期足够我们来熟悉了掌握DeepSeek的API开放平台开发了。
4.png


4.MM32与DeepSeek
想要MM32 MCU与DeepSeek之间实现交互,在接口层面我们可以使用CURL方式,通过HTTP协议与DeepSeek的API开放平台完成;在硬件层面,我们需要扩展网络模块与MM32进行连接,达到联网的功能。这里我们使用Air724这个4G模组,与MM32之间通过串口通讯,基于AT指令来进行联网、HTTP等功能的操作。

5.硬件连接
硬件连接如下图所示,将Air724接口的RXD与Mini-F5333开发板上Arduino接口的TXD进行连接,将Air724接口的TXD与Mini-F5333开发板上Arduino接口的RXD进行连接,将Air724接口的GND与Mini-F5333开发板上Arduino接口的GND进行连接,将Air724接口的RST与Mini-F5333开发板上Arduino接口的INT进行连接;同时给Air724模块供12V电源,给Mini-F5333开发板供5V电源。
5.jpg


6.功能实现
首先是基于Mini-F5333开发板创建基础工程,实现板载LED灯和KEY按键检测,通过移植MultiButton开源软件实现按键处理操作;通过AT指令操作来实现Air724模组的初始化配置,在按下按键后,实现HTTP与DeepSeek的交互;在接收到DeepSeek反馈的数据后,通过cJSON来进行解析;处理过程和解析的结果通过SWD接口打印到电脑监视软件上(这边是通过移植SEGGER_RTT来实现打印的)。具体的代码模块如下所示:
6.png
6.1.基础工程配置
  1. #include "platform.h"
  2. #include "SEGGER_RTT.h"

  3. volatile uint32_t PLATFORM_DelayTick = 0;

  4. void PLATFORM_InitSysTick(void)
  5. {
  6.     RCC_ClocksTypeDef  RCC_Clocks;
  7.     RCC_GetClocksFreq(&RCC_Clocks);

  8.     if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000))
  9.     {
  10.         while (1)
  11.         {
  12.         }
  13.     }

  14.     NVIC_SetPriority(SysTick_IRQn, 0x0);
  15. }

  16. void PLATFORM_ConfigDelay(void)
  17. {
  18.     NVIC_InitTypeDef        NVIC_InitStruct;
  19.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;

  20.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

  21.     TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
  22.     TIM_TimeBaseStruct.TIM_Prescaler         = (TIM_GetTIMxClock(TIM6) / 100000 - 1);
  23.     TIM_TimeBaseStruct.TIM_CounterMode       = TIM_CounterMode_Up;
  24.     TIM_TimeBaseStruct.TIM_Period            = (100 - 1);
  25.     TIM_TimeBaseStruct.TIM_ClockDivision     = TIM_CKD_Div1;
  26.     TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
  27.     TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStruct);

  28.     TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

  29.     NVIC_InitStruct.NVIC_IRQChannel = TIM6_IRQn;
  30.     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  31.     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  32.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  33.     NVIC_Init(&NVIC_InitStruct);

  34.     TIM_Cmd(TIM6, ENABLE);
  35. }

  36. void PLATFORM_DelayMs(uint32_t Tick)
  37. {
  38.     PLATFORM_DelayTick = Tick;

  39.     while (PLATFORM_DelayTick)
  40.     {
  41.     }
  42. }

  43. void PLATFORM_InitConsole(void)
  44. {
  45.     SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
  46. }

  47. int fputc(int ch, FILE *f)
  48. {
  49.     SEGGER_RTT_PutCharSkip(0, (char)ch);

  50.     return (ch);
  51. }

  52. void PLATFORM_PrintClocks(void)
  53. {
  54.     printf("\r\nBOARD : Mini-F5333");
  55.     printf("\r\nMCU   : MM32F5333D7P");
  56.     printf("\r\n");

  57.     switch (RCC->CFGR & RCC_CFGR_SWS_Msk)
  58.     {
  59.         case 0x00:
  60.             printf("\r\nHSI used as system clock source");
  61.             break;

  62.         case 0x04:
  63.             printf("\r\nHSE used as system clock source");
  64.             break;

  65.         case 0x08:
  66.             if (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC_Msk)
  67.             {
  68.                 printf("\r\nPLL1 (clocked by HSE) used as system clock source");
  69.             }
  70.             else
  71.             {
  72.                 printf("\r\nPLL1 (clocked by HSI) used as system clock source");
  73.             }

  74.             break;

  75.         case 0x0C:
  76.             printf("\r\nLSI used as system clock source");
  77.             break;

  78.         default:
  79.             break;
  80.     }

  81.     RCC_ClocksTypeDef  RCC_Clocks;
  82.     RCC_GetClocksFreq(&RCC_Clocks);

  83.     printf("\r\n");
  84.     printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)RCC_Clocks.SYSCLK_Frequency / (double)1000000.0);
  85.     printf("\r\nHCLK   Frequency : %7.3f MHz", (double)RCC_Clocks.HCLK_Frequency   / (double)1000000.0);
  86.     printf("\r\nPCLK1  Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK1_Frequency  / (double)1000000.0);
  87.     printf("\r\nPCLK2  Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK2_Frequency  / (double)1000000.0);
  88.     printf("\r\n");
  89. }

  90. void PLATFORM_Init(void)
  91. {
  92.     PLATFORM_InitSysTick();

  93.     PLATFORM_ConfigDelay();

  94.     PLATFORM_InitConsole();

  95.     PLATFORM_PrintClocks();
  96. }

  97. void TIM6_IRQHandler(void)
  98. {
  99.     if (RESET != TIM_GetITStatus(TIM6, TIM_IT_Update))
  100.     {
  101.         if (PLATFORM_DelayTick)
  102.         {
  103.             PLATFORM_DelayTick--;
  104.         }

  105.         TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
  106.     }
  107. }


6.2.LED驱动
  1. #include "bsp_led.h"

  2. void bsp_LedInit(void)
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStruct;

  5.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  6.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

  7.     GPIO_StructInit(&GPIO_InitStruct);
  8.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_11 | GPIO_Pin_10 ;
  9.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  10.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
  11.     GPIO_Init(GPIOB, &GPIO_InitStruct);

  12.     GPIO_StructInit(&GPIO_InitStruct);
  13.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_7 | GPIO_Pin_6;
  14.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  15.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
  16.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  17.     GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET);
  18.     GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_SET);
  19.     GPIO_WriteBit(GPIOC, GPIO_Pin_7,  Bit_SET);
  20.     GPIO_WriteBit(GPIOC, GPIO_Pin_6,  Bit_SET);
  21. }

  22. void bsp_LedToggle(uint8_t Index)
  23. {
  24.     switch (Index)
  25.     {
  26.         case 1:
  27.             if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_11) == Bit_RESET)
  28.             {
  29.                 GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET);
  30.             }
  31.             else
  32.             {
  33.                 GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_RESET);
  34.             }
  35.             break;

  36.         case 2:
  37.             if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_10) == Bit_RESET)
  38.             {
  39.                 GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_SET);
  40.             }
  41.             else
  42.             {
  43.                 GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_RESET);
  44.             }
  45.             break;

  46.         case 3:
  47.             if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7) == Bit_RESET)
  48.             {
  49.                 GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);
  50.             }
  51.             else
  52.             {
  53.                 GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);
  54.             }
  55.             break;

  56.         case 4:
  57.             if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6) == Bit_RESET)
  58.             {
  59.                 GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
  60.             }
  61.             else
  62.             {
  63.                 GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
  64.             }
  65.             break;

  66.         default:
  67.             break;
  68.     }
  69. }



6.3.KEY驱动
  1. #include "bsp_key.h"

  2. void bsp_KeyInit(void)
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStruct;

  5.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  6.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

  7.     GPIO_StructInit(&GPIO_InitStruct);
  8.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_4;
  9.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
  10.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  11.     GPIO_StructInit(&GPIO_InitStruct);
  12.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_5;
  13.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  14.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  15.     GPIO_StructInit(&GPIO_InitStruct);
  16.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_1 | GPIO_Pin_2;
  17.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  18.     GPIO_Init(GPIOB, &GPIO_InitStruct);
  19. }

  20. uint8_t bsp_KeyReadPinLevel(uint8_t Index)
  21. {
  22.     uint8_t PinLevel = 0;

  23.     switch (Index)
  24.     {
  25.         case 1:
  26.             PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4);
  27.             break;

  28.         case 2:
  29.             PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5);
  30.             break;

  31.         case 3:
  32.             PinLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);
  33.             break;

  34.         case 4:
  35.             PinLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);
  36.             break;

  37.         default:
  38.             break;
  39.     }

  40.     return (PinLevel);
  41. }



6.4.按键应用
  1. #include "key.h"
  2. #include "bsp_key.h"
  3. #include "multi_button.h"

  4. struct Button K1;
  5. struct Button K2;
  6. struct Button K3;
  7. struct Button K4;

  8. volatile uint8_t KeyRegisterFlag = 0;
  9. volatile uint8_t KeyHttpPostFlag = 0;

  10. void KEY_PressUpHandler(void *btn)
  11. {
  12.     struct Button *handle = (struct Button *)btn;

  13.     switch (handle->button_id)
  14.     {
  15.         case 1:
  16.             printf("\r\nK1");
  17.             break;

  18.         case 2:
  19.             printf("\r\nK2");
  20.             break;

  21.         case 3:
  22.             printf("\r\nK3");
  23.             break;

  24.         case 4:
  25.             printf("\r\nK4");   KeyHttpPostFlag = 1;
  26.             break;

  27.         default:
  28.             break;
  29.     }
  30. }

  31. void KEY_Init(void)
  32. {
  33.     button_init(&K1, bsp_KeyReadPinLevel, Bit_SET,   1);
  34.     button_init(&K2, bsp_KeyReadPinLevel, Bit_RESET, 2);
  35.     button_init(&K3, bsp_KeyReadPinLevel, Bit_RESET, 3);
  36.     button_init(&K4, bsp_KeyReadPinLevel, Bit_RESET, 4);

  37.     button_attach(&K1, PRESS_UP, KEY_PressUpHandler);
  38.     button_attach(&K2, PRESS_UP, KEY_PressUpHandler);
  39.     button_attach(&K3, PRESS_UP, KEY_PressUpHandler);
  40.     button_attach(&K4, PRESS_UP, KEY_PressUpHandler);

  41.     button_start(&K1);
  42.     button_start(&K2);
  43.     button_start(&K3);
  44.     button_start(&K4);

  45.     KeyRegisterFlag = 1;
  46. }

  47. void SysTick_Handler(void)
  48. {
  49.     if (KeyRegisterFlag)
  50.     {
  51.         button_ticks();
  52.     }
  53. }


6.5.Air724驱动
  1. #include "bsp_air724.h"
  2. #include "platform.h"

  3. uint8_t  Air724_RxBuffer[2048];
  4. uint16_t Air724_RxLength = 0;
  5. char     deepseek_Buffer[2048];

  6. void bsp_Air724InitUART(void)
  7. {
  8.     GPIO_InitTypeDef GPIO_InitStruct;
  9.     NVIC_InitTypeDef NVIC_InitStruct;
  10.     UART_InitTypeDef UART_InitStruct;

  11.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);

  12.     UART_StructInit(&UART_InitStruct);
  13.     UART_InitStruct.BaudRate      = 115200;
  14.     UART_InitStruct.WordLength    = UART_WordLength_8b;
  15.     UART_InitStruct.StopBits      = UART_StopBits_1;
  16.     UART_InitStruct.Parity        = UART_Parity_No;
  17.     UART_InitStruct.HWFlowControl = UART_HWFlowControl_None;
  18.     UART_InitStruct.Mode          = UART_Mode_Rx | UART_Mode_Tx;
  19.     UART_Init(UART4, &UART_InitStruct);

  20.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

  21.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_8);
  22.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_8);

  23.     GPIO_StructInit(&GPIO_InitStruct);
  24.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
  25.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  26.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
  27.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  28.     GPIO_StructInit(&GPIO_InitStruct);
  29.     GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_1;
  30.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  31.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  32.     UART_ITConfig(UART4, UART_IT_RX, ENABLE);

  33.     NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
  34.     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  35.     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  36.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  37.     NVIC_Init(&NVIC_InitStruct);

  38.     UART_Cmd(UART4, ENABLE);
  39. }

  40. void bsp_Air724RxIrqHandler(uint8_t Data)
  41. {
  42.     printf("%c", Data);

  43.     Air724_RxBuffer[Air724_RxLength] = Data;

  44.     Air724_RxLength += 1;
  45.     Air724_RxLength %= 2048;
  46. }

  47. void bsp_Air724InitGPIO(void)
  48. {
  49.     GPIO_InitTypeDef GPIO_InitStruct;

  50.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOI, ENABLE);

  51.     GPIO_StructInit(&GPIO_InitStruct);
  52.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
  53.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  54.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
  55.     GPIO_Init(GPIOI, &GPIO_InitStruct);

  56.     GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_SET);
  57. }

  58. void bsp_Air724Reset(void)
  59. {
  60.     GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_SET);
  61.     PLATFORM_DelayMs(100);

  62.     GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_RESET);
  63.     PLATFORM_DelayMs(100);
  64. }

  65. void bsp_Air724ClearRxBuffer(void)
  66. {
  67.     Air724_RxLength = 0;

  68.     for (uint16_t i = 0; i < 2048; i++)
  69.     {
  70.         Air724_RxBuffer[i] = 0;
  71.     }
  72. }

  73. void bsp_Air724Init(void)
  74. {
  75.     bsp_Air724InitUART();

  76.     bsp_Air724InitGPIO();

  77.     bsp_Air724ClearRxBuffer();
  78. }

  79. void bsp_Air724SendData(uint8_t Data)
  80. {
  81.     UART_SendData(UART4, Data);

  82.     while (RESET == UART_GetFlagStatus(UART4, UART_FLAG_TXC))
  83.     {
  84.     }
  85. }

  86. uint32_t bsp_Air724SendCommandBlocking(char *Command, char *Response, uint32_t Timeout)
  87. {
  88.     if (Command != NULL)
  89.     {
  90.         while (*Command != '\0')
  91.         {
  92.             bsp_Air724SendData(*Command++);
  93.         }

  94.         bsp_Air724SendData(0x0D);
  95.         bsp_Air724SendData(0x0A);
  96.     }

  97.     if (Timeout != 0)
  98.     {
  99.         bsp_Air724ClearRxBuffer();

  100.         while (Timeout--)
  101.         {
  102.             if (strstr((char *)Air724_RxBuffer, Response) != NULL)
  103.             {
  104.                 return (Timeout);
  105.             }

  106.             PLATFORM_DelayMs(1);
  107.         }
  108.     }

  109.     return (0);
  110. }

  111. void bsp_Air724InputDataNonBlocking(char *Data)
  112. {
  113.     if (Data != NULL)
  114.     {
  115.         while (*Data != '\0')
  116.         {
  117.             bsp_Air724SendData(*Data++);
  118.         }

  119.         bsp_Air724SendData(0x1A);
  120.     }
  121. }


6.6.HTTP初始化
  1. void HTTP_Init(void)
  2. {
  3.     bsp_Air724Reset();

  4.     bsp_Air724SendCommandBlocking(NULL, "RDY",   10000);
  5.     bsp_Air724SendCommandBlocking(NULL, "+NITZ", 10000);

  6.     PLATFORM_DelayMs(500);

  7.     bsp_Air724SendCommandBlocking("AT", "OK", 10000);

  8.     bsp_Air724SendCommandBlocking("AT+CPIN?",  "OK", 10000);

  9.     bsp_Air724SendCommandBlocking("AT+CGATT?", "OK", 10000);

  10.     bsp_Air724SendCommandBlocking("AT+SAPBR=3,1,"CONTYPE","GPRS"", "OK", 10000);

  11.     bsp_Air724SendCommandBlocking("AT+SAPBR=3,1,"APN",""", "OK", 10000);

  12.     bsp_Air724SendCommandBlocking("AT+SAPBR=1,1", "OK", 10000);

  13.     bsp_Air724SendCommandBlocking("AT+SAPBR=2,1", "OK", 10000);

  14.     bsp_Air724SendCommandBlocking("AT+CGNSPWR=1", "OK", 10000);

  15.     bsp_Air724SendCommandBlocking("AT+CSQ", "OK", 10000);

  16.     bsp_Air724SendCommandBlocking("AT+CGNSAID=31,1,1,1", "OK", 10000);
  17. }


6.7.HTTP与DeepSeek交互
  1. char POST_DATA[] =
  2. "{\
  3.     "model": "deepseek-chat",\
  4.     "messages": [{"role": "user", "content": "who are you?"}],\
  5.     "stream": false\
  6. }";

  7. void HTTP_Post(void)
  8. {
  9.     char Command[200];

  10.     bsp_Air724SendCommandBlocking("AT+HTTPINIT", "OK", 10000);

  11.     bsp_Air724SendCommandBlocking("AT+HTTPSSL=1", "OK", 10000);

  12.     bsp_Air724SendCommandBlocking("AT+HTTPPARA="CID",1", "OK", 10000);

  13.     bsp_Air724SendCommandBlocking("AT+HTTPPARA="URL","https://api.deepseek.com/chat/completions"", "OK", 10000);

  14.     bsp_Air724SendCommandBlocking("AT+HTTPPARA="CONTENT","application/json"", "OK", 10000);

  15.     bsp_Air724SendCommandBlocking("AT+HTTPPARA="USERDATA","Authorization:Bearer API key"", "OK", 10000);

  16.     memset(Command, 0, sizeof(Command));
  17.     sprintf(Command, "AT+HTTPDATA=%d,10000", strlen(POST_DATA));

  18.     bsp_Air724SendCommandBlocking(Command, "DOWNLOAD", 30000);

  19.     printf("\r\n%s", POST_DATA);

  20.     bsp_Air724InputDataNonBlocking(POST_DATA);

  21.     bsp_Air724SendCommandBlocking("AT+HTTPACTION=1", "OK", 30000);

  22.     bsp_Air724SendCommandBlocking(NULL, "+HTTPACTION: 1,200,", 30000);

  23.     bsp_Air724SendCommandBlocking("AT+HTTPREAD", "OK", 30000);

  24.     bsp_Air724RxHandler();

  25.     bsp_Air724SendCommandBlocking("AT+HTTPTERM", "OK", 10000);
  26. }


6.8.DeepSeek数据处理
  1. #include "cJSON.h"

  2. void bsp_Air724RxHandler(void)
  3. {
  4.     uint16_t Count = 0;
  5.     uint16_t Group = 0;

  6.     memset(deepseek_Buffer, 0, sizeof(deepseek_Buffer));

  7.     for (uint16_t i = 0; i < Air724_RxLength; i++)
  8.     {
  9.         if (Air724_RxBuffer[i] == '{')
  10.         {
  11.             Group++;
  12.         }

  13.         if (Group)
  14.         {
  15.             deepseek_Buffer[Count++] =  Air724_RxBuffer[i];
  16.         }

  17.         if (Air724_RxBuffer[i] == '}')
  18.         {
  19.             if(Group) Group--;
  20.         }
  21.     }

  22.     printf("\r\n--------------------------------------------------------------------------------");

  23.     cJSON *cjson = cJSON_Parse(deepseek_Buffer);

  24.     char *json_data = cJSON_Print(cjson);

  25.     if (cjson == NULL)
  26.     {
  27.         printf("\r\ncjson error!!!");
  28.     }
  29.     else
  30.     {
  31.         printf("\r\n%s", json_data);
  32.     }

  33.     printf("\r\n--------------------------------------------------------------------------------");

  34.     printf("\r\n");
  35. }




7.运行结果
MCU向DeepSeek发送了"who are you?"的提问,如下图,DeepSeek进行了回答“I’m an AI language model created by OpenAI……”
7.png


8.附件
软件工程代码: Mini-F5333_Air724_21ic.zip (502.76 KB, 下载次数: 39)

点评

紧跟热点,使用MM32和Air724模块通过HTTP协议与DeepSeek的API开放平台完成对接,实现与DeepSeek交互,设备较为简单,但实现效果较佳!  发表于 2025-2-10 17:33
发表于 2025-2-6 18:03 来自手机 | 显示全部楼层
deepseek可以本地离线部署应用
 楼主| 发表于 2025-2-6 21:33 | 显示全部楼层
chenjun89 发表于 2025-2-6 18:03
deepseek可以本地离线部署应用

是的,是可以直接在电脑上本地部署使用的;但如何让MCU与本地部署的deepseek实现交互,还需要研究一下,不知是否可行;对于有算力的嵌入式平台则可以直接部署deepseek,对于MCU这种资源和算力不够的,通过上述的方式是不错的应用方案了……
发表于 2025-2-7 13:52 | 显示全部楼层
万恶的资本家 要开始收费了?

点评

愤青  发表于 2025-2-8 16:04
愤青  发表于 2025-2-8 16:04
发表于 2025-2-7 13:57 | 显示全部楼层
不错,本地部署也可以尝试一下
发表于 2025-2-7 13:58 | 显示全部楼层
希望能发掘更多应用场景,更加实用的
 楼主| 发表于 2025-2-7 14:00 | 显示全部楼层
keer_zu 发表于 2025-2-7 13:58
希望能发掘更多应用场景,更加实用的

 楼主| 发表于 2025-2-7 14:02 | 显示全部楼层
keer_zu 发表于 2025-2-7 13:57
不错,本地部署也可以尝试一下

后面会专门分享一下如何实施本地部署的
发表于 2025-2-8 16:05 | 显示全部楼层
xionghaoyun 发表于 2025-2-7 13:52
万恶的资本家 要开始收费了?

愤青
发表于 2025-2-15 15:33 | 显示全部楼层
xionghaoyun 发表于 2025-2-7 13:52
万恶的资本家 要开始收费了?

做生意不收钱?
发表于 2025-2-17 09:49 | 显示全部楼层
本地部署好像对资源要求挺高的哦

点评

是的,1.5是要求最低的  发表于 2025-2-17 17:56
发表于 2025-2-17 18:52 来自手机 | 显示全部楼层
感觉deepseek之所以会火,在于开源免费,当然免费也是当前,后面形成粘性了估计就要开始收费了,毕竟企业要生存。
 楼主| 发表于 2025-2-17 21:29 | 显示全部楼层
weifeng90 发表于 2025-2-17 18:52
感觉deepseek之所以会火,在于开源免费,当然免费也是当前,后面形成粘性了估计就要开始收费了,毕竟企业要 ...

App、网页版、离线部署的环境,这3个当前都是免费的;但通过调用API keys的方式是收费的,价格按照“百万Tokens”为单位进行计费的,先充值,后使用。但是当前官网上出了公告:“当前服务器资源紧张,为避免对您造成业务影响,我们已暂停 API 服务充值。存量充值金额可继续调用,敬请谅解!”,等后面可以充值了,才能再使用API keys的方式了……
发表于 2025-3-25 14:26 | 显示全部楼层
这种方式使得更多的人可以体验到 DeepSeek 的强大功能,同时也能够为企业和开发者提供灵活的接口调用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:King.Xu

77

主题

3023

帖子

38

粉丝
快速回复 返回顶部 返回列表