STM32

STM32是STMicroelectronics(意法半导体)推出的一系列基于ARM Cortex-M内核的32位微控制器(MCU)产品。这些微控制器提供了广泛的产品系列,覆盖了多种不同的性能和功能需求,适用于各种应用领域,包括工业控制、汽车电子、消费类电子、医疗设备等。

STM32系列微控制器以其高性能、低功耗、丰富的外设接口和灵活的开发工具而闻名。它们通常具有丰富的存储器、多种通信接口(如UART、SPI、I2C、CAN等)、模拟数字转换器(ADC)、定时器、PWM输出等功能,以满足不同应用场景下的需求。

STM32微控制器通常使用标准的ARM Cortex-M内核,包括Cortex-M0、M0+、M3、M4和M7等,这些内核具有不同的性能和功耗特性,可根据具体应用的需求进行选择。此外,STM32系列还提供了多种封装和引脚配置,以满足不同尺寸和集成度的要求。

STMicroelectronics为STM32系列提供了丰富的开发工具和支持资源,包括基于ARM开发环境的集成开发环境(IDE)、调试器、评估板和参考设计等。这些工具和资源有助于开发人员快速开发和部署他们的应用,并提供了全面的技术支持和文档资料,帮助用户充分发挥STM32微控制器的性能和功能优势。

  • 降低完整射频电路设计工作量,加快新产品上市时间
  • 优化无线连接性能,低功耗,尺寸紧凑
  • Bluetooth ® LE、Zigbee®和OpenThread认证
  • FCC、CE、JRF、KC、SRRC[1]、GOST地区认证

2021年1月12日—— 横跨多重电子应用领域的全球领先的半导体供应商意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)推出一个新的加快物联网产品上市的解决方案,该方案可利用现成的微型STM32无线微控制器(MCU)模块加快基于Bluetooth® LE和802.15.4新物联网设备的开发周期。

这个7mm x 11.3mm的 STM32WB5MMG模块让缺少无线设计能力的产品研发团队也能开发物联网产品。为开发层数最少的低成本PCB电路板而设计,新模块集成了直到天线的整个射频子系统。用户还可以免费使用意法半导体的STM32Cube MCU开发生态系统工具、设计向导、射频协议栈和完整软件库,快速高效地完成开发项目。

意法半导体部门副总裁兼微控制器产品总经理Ricardo de Sa Earp表示:“我们的首个基于STM32的无线模块有助于简化技术难题,为智能物联网设备市场带来激动人心的发展机会。作为一个现成的单封装的完整射频子系统,STM32WB5MMG是一个开箱即用的射频性能出色的无线解决方案,并已通过BluetoothZigbeeOpenThread规范认证。”

此外,该模块还支持意法半导体的独树一帜的共存双协议模式,用户可以将任何基于IEEE 802.15.4射频技术的协议(包括Zigbee 3.0和OpenThread)直连任何低功耗蓝牙BLE设备。

得益于意法半导体的STM32WB55超低功耗无线微控制器的所有功能,该模块可用于智能家居、智能建筑和智能工厂设备的各种应用场景。用户可以利用MCU的双核架构将射频和应用处理分开,处理性能不会被任何因素影响;兼具大容量存储器存放射频应用代码和数据,及最新的网络安全功能保护设备安全。

STM32WB5MMG现已开始上市

详细技术信息

STM32WB5MMG可以应对各种层面的应用机会,包括成本敏感的高度小型化设备。优化的引脚让设计人员可以开发简单的低成本PCB电路板,并利用现有的STM32WB55 MCU固件库和工具链开发产品。此外,意法半导体还专门创建了一个应用笔记,为模块用户提供额外的设计指南。

该模块集成了与接收电路正确匹配的微型天线、内部开关电源(SMPS)电路和频率控制组件。通过支持无晶体USB全速接口,该模块使用户可以最大程度地降低物料清单成本,并简化硬件设计。

在网络保护功能中,无线下载(OTA)等安全软件更新可保护品牌和产品设备的完好性,客户密钥存储和专有代码读取保护(PCROP)可保护开发者的知识产权,公共密钥验证(PKA)支持功能支持用密码加密技术保护软件代码和数据通信。

高射频性能与低功耗兼备,新模块确保无线连接可靠稳定,并有助于延长电池续航时间。

[1] Final certification available in January 2021  最终认证于20211月获得

关于意法半导体

意法半导体拥有46,000名半导体技术、产品和方案的创新者和创造者,掌握半导体供应链和最先进的制造设备。作为一家独立的半导体设备制造商,意法半导体与十万余客户、上千合作伙伴一起研发产品和解决方案,共同构建生态系统,帮助他们更好地应对各种挑战和新机遇,满足世界对可持续发展的更高需求。意法半导体的技术让人们的出行更智能,电力和能源管理更高效,物联网和5G技术应用更广泛。详情请浏览意法半导体公司网站:www.st.com

围观 9

串口发送数据

1、串口发送数据最直接的方式就是标准调用库函数 。

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

第一个参数是发送的串口号,第二个参数是要发送的数据,但是用过的朋友应该觉得不好用,一次只能发送单个字符,所以我们有必要根据这个函数加以扩展:

void Send_data(u8 *s)
{
 while(*s!='\0')
 { 
  while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET); 
  USART_SendData(USART1,*s);
  s++;
 }
}

以上程序的形参就是我们调用该函数时要发送的字符串,这里通过循环调用USART_SendData来一 一发送我们的字符串。

while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);

这句话有必要加,它是用于检查串口是否发送完成的标志,如果不加这句话会发生数据丢失的情况。这个函数只能用于串口1发送。有些时候根据需要,要用到多个串口发送,那么就还需要改进这个程序。如下:

void Send_data(USART_TypeDef * USARTx,u8 *s)
{
 while(*s!='\0')
 { 
  while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET); 
  USART_SendData(USARTx,*s);
  s++;
 }
}

这样就可实现任意的串口发送。但有一点,我在使用实时操作系统的时候(如UCOS,Freertos等),需考虑函数重入的问题。

当然也可以简单的实现把该函数复制一下,然后修改串口号也可以避免该问题。然而这个函数不能像printf那样传递多个参数,所以还可以再改进,最终程序如下:

void USART_printf ( USART_TypeDef * USARTx, char * Data, ... )
{
 const char *s;
 int d;   
 char buf[16];

 va_list ap;
 va_start(ap, Data);

 while ( * Data != 0 )     // 判断是否到达字符串结束符
 {                              
  if ( * Data == 0x5c )  //'\'
  {           
   switch ( *++Data )
   {
    case 'r':                 //回车符
    USART_SendData(USARTx, 0x0d);
    Data ++;
    break;

    case 'n':                 //换行符
    USART_SendData(USARTx, 0x0a); 
    Data ++;
    break;

    default:
    Data ++;
    break;
   }    
  }

  else if ( * Data == '%')
  {           //
   switch ( *++Data )
   {    
    case 's':            //字符串
    s = va_arg(ap, const char *);

    for ( ; *s; s++) 
    {
     USART_SendData(USARTx,*s);
     while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }

    Data++;

    break;

    case 'd':   
     //十进制
    d = va_arg(ap, int);

    itoa(d, buf, 10);

    for (s = buf; *s; s++) 
    {
     USART_SendData(USARTx,*s);
     while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
    }

    Data++;

    break;

    default:
    Data++;

    break;

   }   
  }

  else USART_SendData(USARTx, *Data++);

  while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );

 }
}

该函数就可以像printf使用可变参数,方便很多。通过观察函数但这个函数只支持了%d,%s的参数,想要支持更多,可以仿照printf的函数写法加以补充。

2、 直接使用printf函数。

很多朋友都知道STM32直接使用printf不行的。需要加上以下的重映射函数:


如果不想添加以上代码,也可以勾选以下的Use MicroLI选项来支持printf函数使用:


串口接收数据

串口接收最后应有一定的协议,如发送一帧数据应该有头标志或尾标志,也可两个标志都有。

这样在处理数据时既能能保证数据的正确接收,也有利于接收完后我们处理数据。串口的配置在这里就不再赘述,这里以串口2接收中断服务程序函数且接收的数据包含头尾标识为例。

#define Max_BUFF_Len 18
unsigned char Uart2_Buffer[Max_BUFF_Len];
unsigned int Uart2_Rx=0;
void USART2_IRQHandler() 
{
 if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 
 {
  USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志

  Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2);     //接收串口1数据到buff缓冲区
  Uart2_Rx++; 

  if(Uart2_Buffer[Uart2_Rx-1] == 0x0a || Uart2_Rx == Max_BUFF_Len)    //如果接收到尾标识是换行符(或者等于最大接受数就清空重新接收)
  {
   if(Uart2_Buffer[0] == '+')                      //检测到头标识是我们需要的 
   {
    printf("%s\r\n",Uart2_Buffer);        //这里我做打印数据处理
    Uart2_Rx=0;                                   
   } 
   else
   {
    Uart2_Rx=0;                                   //不是我们需要的数据或者达到最大接收数则开始重新接收
   }
  }
 }
}

数据的头标识为“\n”既换行符,尾标识为“+”。该函数将串口接收的数据存放在USART_Buffer数组中,然后先判断当前字符是不是尾标识,如果是,说明接收完毕,然后再来判断头标识是不是“+”号,如果还是,那么就是我们想要的数据,接下来就可以进行相应数据的处理了。但如果不是,那么就让Usart2_Rx=0重新接收数据。

这样做有以下好处:

  • 可以接收不定长度的数据,最大接收长度可以通过Max_BUFF_Len来更改
  • 可以接收指定的数据
  • 防止接收的数据使数组越界

这里得把接收正确数据直接打印出来,也可以通过设置标识位,然后在主函数里面轮询再操作。

以上的接收形式是中断一次就接收一个字符,这在UCOS等实时内核系统中频繁的中断,非常消耗CPU资源,在有些时候我们需要接收大量数据时且波特率很高的情况下,长时间中断会带来一些额外的问题。

所以以DMA形式配合串口的IDLE(空闲中断)来接收数据将会大大的提高CPU的利用率,减少系统资源的消耗。首先还是先看代码。

#define DMA_USART1_RECEIVE_LEN 18
void USART1_IRQHandler(void)                                 
{     
    u32 temp = 0;  
    uint16_t i = 0;  

    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  
    {  
        USART1->SR;  
        USART1->DR; //这里我们通过先读SR(状态寄存器)和DR(数据寄存器)来清USART_IT_IDLE标志    
        DMA_Cmd(DMA1_Channel5,DISABLE);  
        temp = DMA_USART1_RECEIVE_LEN - DMA_GetCurrDataCounter(DMA1_Channel5); //接收的字符串长度=设置的接收长度-剩余DMA缓存大小 
        for (i = 0;i < temp;i++)  
        {  
            Uart2_Buffer[i] = USART1_RECEIVE_DMABuffer[i];  

        }  
        //设置传输数据长度  
        DMA_SetCurrDataCounter(DMA1_Channel5,DMA_USART1_RECEIVE_LEN);  
        //打开DMA  
        DMA_Cmd(DMA1_Channel5,ENABLE);  
    }        
} 

之前的串口中断是一个一个字符的接收,现在改为串口空闲中断,就是一帧数据过来才中断进入一次。而且接收的数据时候是DMA来搬运到我们指定的缓冲区(也就是程序中的USART1_RECEIVE_DMABuffer数组),是不占用CPU时间资源的。

最后在讲下DMA的发送:

#define DMA_USART1_SEND_LEN 64
void DMA_SEND_EN(void)
{
 DMA_Cmd(DMA1_Channel4, DISABLE);      
 DMA_SetCurrDataCounter(DMA1_Channel4,DMA_USART1_SEND_LEN);   
 DMA_Cmd(DMA1_Channel4, ENABLE);
}

这里需要注意下DMA_Cmd(DMA1_Channel4,DISABLE)函数需要在设置传输大小之前调用一下,否则不会重新启动DMA发送。

有了以上的接收方式,对一般的串口数据处理是没有问题的了。下面再讲一下,在ucosiii中我使用信号量+消息队列+储存管理的形式来处理我们的串口数据。先来说一下这种方式对比其他方式的一些优缺点。

一般对串口的处理形式是"生产者"和"消费者"的模式,即本次接收的数据要马上处理,否则当数据大量涌进的时候,就来不及"消费"掉生产者(串口接收中断)的数据,那么就会丢失本次的数据处理。所以使用队列就能够很方便的解决这个问题。

在下面的程序中,对数据的处理是先接收,在处理,如果在处理的过程中,有串口中断接收数据,那么就把它依次放在队列中,队列的特征是先进先出,在串口中就是先处理先接收的数据,所以根据生产和消费的速度,定义不同大小的消息队列缓冲区就可以了。缺点就是太占用系统资源,一般51单片机是没可能了。

下面是从我做的项目中截取过来的程序:

OS_MSG_SIZE  Usart1_Rx_cnt;          //字节大小计数值
unsigned char Usart1_data;           //每次中断接收的数据
unsigned char* Usart1_Rx_Ptr;        //储存管理分配内存的首地址的指针
unsigned char* Usart1_Rx_Ptr1;       //储存首地址的指针

void USART1_IRQHandler() 
{
 OS_ERR err;
 OSIntEnter();

  if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET) //中断产生 
  {   
    USART_ClearFlag(USART1, USART_FLAG_RXNE);     //清除中断标志

    Usart1_data = USART_ReceiveData(USART1);     //接收串口1数据到buff缓冲区

  if(Usart1_data =='+')                     //接收到数据头标识
  {
//   OSSemPend((OS_SEM*  )&SEM_IAR_UART,  //这里请求信号量是为了保证分配的存储区,但一般来说不允许
//   (OS_TICK  )0,                   //在终端服务函数中调用信号量请求但因为
//   (OS_OPT   )OS_OPT_PEND_NON_BLOCKING,//我OPT参数设置为非阻塞,所以可以这么写
//   (CPU_TS*  )0,
//   (OS_ERR*  )&err); 
//   if(err==OS_ERR_PEND_WOULD_BLOCK)     //检测到当前信号量不可用
//   {
//     printf("error");
//   }    
   Usart1_Rx_Ptr=(unsigned char*) OSMemGet((OS_MEM*)&UART1_MemPool,&err);//分配存储区
   Usart1_Rx_Ptr1=Usart1_Rx_Ptr;          //储存存储区的首地址
  }
  if(Usart1_data == 0x0a )       //接收到尾标志
  {                    
   *Usart1_Rx_Ptr++=Usart1_data;
   Usart1_Rx_cnt++;                         //字节大小增加
   OSTaskQPost((OS_TCB    *  )&Task1_TaskTCB,
                                   (void      *  )Usart1_Rx_Ptr1,    //发送存储区首地址到消息队列
                                   (OS_MSG_SIZE  )Usart1_Rx_cnt,
                                   (OS_OPT       )OS_OPT_POST_FIFO,  //先进先出,也可设置为后进先出,再有地方很有用
                                   (OS_ERR    *  )&err);

   Usart1_Rx_Ptr=NULL;          //将指针指向为空,防止修改
   Usart1_Rx_cnt=0;      //字节大小计数清零
  }
  else
  {
   *Usart1_Rx_Ptr=Usart1_data; //储存接收到的数据
   Usart1_Rx_Ptr++;
   Usart1_Rx_cnt++;
  } 
 }    
 OSIntExit();
}

上面被注释掉的代码为了防止当分区中没有空闲的存储块时加入信号量,打印出报警信息。当然我们也可以将存储块直接设置大一点,但是还是无法避免当没有可用存储块时会程序会崩溃现象的发生。希望懂的朋友能告知下~。

下面是串口数据处理任务,这里删去了其他代码,只把他打印出来了而已。

void task1_task(void *p_arg)
{
 OS_ERR err;
 OS_MSG_SIZE Usart1_Data_size;
 u8 *p;

 while(1)
 {
  p=(u8*)OSTaskQPend((OS_TICK  )0, //请求消息队列,获得储存区首地址
   (OS_OPT    )OS_OPT_PEND_BLOCKING,
   (OS_MSG_SIZE* )&Usart1_Data_size,
   (CPU_TS*   )0,
   (OS_ERR*   )&err);

  printf("%s\r\n",p);        //打印数据

  delay_ms(100);
  OSMemPut((OS_MEM* )&UART1_MemPool,    //释放储存区
  (void*   )p,
  (OS_ERR*  )&err);

  OSSemPost((OS_SEM* )&SEM_IAR_UART,    //释放信号量
  (OS_OPT  )OS_OPT_POST_NO_SCHED,
  (OS_ERR* )&err);

  OSTimeDlyHMSM(0,0,1,500,OS_OPT_TIME_PERIODIC,&err);     
 }
}

作者:可以吃的鱼
原文:
https://blog.csdn.net/qq_35281599/article/details/80299770
声明:本文系网络转载,版权归原作者所有。

围观 30

1. 什么是Bootloader

Bootloader是硬件启动的引导程序,是运行操作系统的前提。在操作系统内核或用户应用程序运行之前运行的一段小代码。对硬件进行相应的初始化和设定,最终为操作系统准备好环境。

2. Bootloader的特点

Bootloader不属于操作系统,一般采用汇编语言和C语言开发。需要针对特定的硬件平台编写。在移植过程时,首先为开发板移植Bootloader。Bootloader不但依赖于CPU的体系架构,而且依赖于嵌入式系统板级设备的配置。

3. STM32中bootloader的内存分配

stm32默认的是从0x08000000开始启动程序,所以bootloader也存在于这个地址,大小可以设置。如下图举例分配 48K的大小空间给Bootloader


还有一种分配方式:镜像的备份 Firmware ---> Application Bak ---> SysRest ----> Bootloader -----> Check if new Firmware -----> Move App Bak to App area

这种方式需要更大的存储空间,如果MCU内置FLASH 不够备份Firmware则需要外置Flash,将Firmware备份在外置FLASH。


根据实际MCU的Flash的大小和固件的大小来分配空间。一般可以把固件信息(app固件的StartAddr, EndAddr, FirmwareSize, CRC等)存放在Free Spae.

bootloader的作用一般是用作更新APP,和初始化后设定跳转到对应的APP。如果APP不加更新功能的话也可以直接将APP写入到0x08000000这个地址里。更新程序就是数据包的接收、校验、写入,全部写入完成后检查APP的启动向量为合格就可以跳转到APP里。


4. Bootloader的跳转简单实现

4.1 Bootloader

我基于STM32Cube配置的外设,IDE用的STM32SW4,STM32F103RCT6。

在实现IAP功能前,先实现跳转。这里先不涉及固件更新。

/*FLASH : 0x8000000 --- 0x8040000 Total Size: 256K
*RAM : 0x20000000 --- 0x2000C000 Total Size: 48K
*Bootloader: 0x8000000 --- 0x8008000 Total Size: 32K

*/

1 /* Includes ------------------------------------------------------------------*/
  2 #include "main.h"
  3 #include "stm32f1xx_hal.h"
  4 #include "usart.h"
  5 #include "gpio.h"
  6 
  7 /* USER CODE BEGIN Includes */
  8 #include "stdio.h"
  9 /* USER CODE END Includes */
 10 
 11 /* USER CODE BEGIN PFP */
 12 /* Private function prototypes -----------------------------------------------*/
 13 pFunction jump2app;
 14 void (*jump2app)();
 15 /* USER CODE END PFP */
 16 
 17 
 18 
 19 /* USER CODE BEGIN 0 */
 20 #ifdef __GNUC__
 21     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
 22 #else
 23     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
 24 #endif
 25 
 26 /*retargets the C library printf function to the USART*/
 27 PUTCHAR_PROTOTYPE
 28 {
 29     HAL_UART_Transmit(&huart1,(uint8_t*)&ch, 1, 0xFFFF);
 30     return ch;
 31 }
 32 
 33 //FLASH            : 0x8000000  --- 0x8040000       Total Size: 256K
 34 //RAM           : 0x20000000 --- 0x2000C000       Total Size: 48K
 35 //Bootloader     : 0x8000000 --- 0x8008000     Total Size: 32K 
 36   37 #define ApplicationAddress    0x8008000
 38 
 39 
 40 void iap_load_app(uint32_t appAddr)
 41 {
 42     printf("first word : 0x%x\n",(*(uint32_t*)appAddr));
 43     if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
 44     {
 45         printf("IAP load APP!!!\n");
 46 
 47         __disable_irq();
 48 
 49         jump2app = (void (*)())*(__IO uint32_t*) (appAddr + 4);
 50 
 51         __set_MSP(*(__IO uint32_t*) appAddr);
 52 
 53         jump2app();
 54     }
 55 }
 56 /* USER CODE END 0 */
 57 
 58 /**
 59   * @brief  The application entry point.
 60   *
 61   * @retval None
 62   */
 63 int main(void)
 64 {
 65   /* USER CODE BEGIN 1 */
 66 
 67   /* USER CODE END 1 */
 68 
 69   /* MCU Configuration----------------------------------------------------------*/
 70 
 71   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 72   HAL_Init();
 73 
 74   /* USER CODE BEGIN Init */
 75 
 76   /* USER CODE END Init */
 77 
 78   /* Configure the system clock */
 79   SystemClock_Config();
 80 
 81   /* USER CODE BEGIN SysInit */
 82 
 83   /* USER CODE END SysInit */
 84 
 85   /* Initialize all configured peripherals */
 86   MX_GPIO_Init();
 87   MX_USART1_UART_Init();
 88   /* USER CODE BEGIN 2 */
 89 
 90   /* USER CODE END 2 */
 91 
 92   /* Infinite loop */
 93   /* USER CODE BEGIN WHILE */
 94   while (1)
 95   {
 96       printf("I am bootloader,jump to app after 5 seconds!\n");
 97 
 98       HAL_Delay(1000);
 99 
100       printf("1\r\n");
101 
102       HAL_Delay(1000);
103 
104       printf("2\r\n");
105 
106       HAL_Delay(1000);
107 
108       printf("3\r\n");
109 
110       HAL_Delay(1000);
111 
112       printf("4\r\n");
113 
114       HAL_Delay(1000);
115 
116       printf("ready to jump!\n");
117 
118       iap_load_app(ApplicationAddress);
119   /* USER CODE END WHILE */
120 
121   /* USER CODE BEGIN 3 */
122 
123   }
124   /* USER CODE END 3 */
125 
126 }

修改ld文件 STM32F103RCTx_Flash.ld


编译烧录。首先将STM32F103RCT6的FLASH全部擦除如下图,然后用STM32SW4烧录Bootloader


调试Bootloader如下图


4.2 Application

APP主要是修改ld文件,Bootloader分配了 32Kb, 剩余224K的先全分配给App, 实现简单跳转。


int main(void)
{
    //NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000);
  /* USER CODE BEGIN 1 */
    SCB->VTOR = ((uint32_t)0x8000000) | (0x8000 & (uint32_t)0x1FFFFF80);
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  __enable_irq();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
     printf("I am new APP !\n\r");

     HAL_Delay(1000);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

再将APP烧录,Reset


来源:博客园 - M&D
转载此文目的在于传递更多信息,版权归原作者所有。
原文链接:
https://www.cnblogs.com/mickey-double/p/11718755.html

围观 1475

边缘AI助力智能楼宇实现数字化人流量监测

意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM) 与能源管理和工业自动化数字化转型的市场领导者施耐德电气 (Schneider Electric)联合推出一款物联网传感器原型。通过监测建筑物的居住率和使用率,该解决方案可以实现新型物业管理服务,提高楼宇的能源管理效率。

两家公司合作,在高性能人数统计传感器内集成人工智能(AI)技术,以克服在有多个入口的大型场所内监测人流量的挑战。在2020年11月19日IoT&5G研讨会期间,施耐德电气将以嘉宾身份参加ST Live Days活动,演示这款物联网传感器解决方案的功能。

随着楼宇及人居管理数字化的提升,施耐德致力于成为客户可持续发展和提高能源效率的数字合作伙伴,为客户提供有新意、有价值的洞见,如,协助智能楼宇管理的排队监控,同时在设计上充分尊重个人隐私。该先进的物联网传感器解决方案将意法半导体AI产品部的先进专业知识与施耐德深厚的传感器应用专长相结合,将高性能的物体检测神经网络嵌入到经济型微控制器(MCU)中。

施耐德电气通过使用STM32Cube.AI工具链提高了设计效率,该工具链具有成熟的功能,可为各种STM32 MCU开发AI应用。STM32Cube软件开发生态系统的工程资源、先进技术和易用性为施耐德电气提供了宝贵的硬件设计灵活性和效率。

该人数统计原型传感器整合了施耐德电气独有的超低功耗LYNRED ThermEyeTM系列热成像传感器,意法半导体最近推出的高性能STM32H723 MCU,以及基于Yolo的神经网络模型。

施耐德电气物联网传感器项目经理Maxime Loidreau表示:“这项前景广阔的技术解锁一项新的楼宇居住率监测和人流量统计方案,适用于监测排队、建筑使用率、社交距离等多种应用场景。我们与ST合作开发的创新的演示原型不仅适用于酒店、办公室、百货零售等场所,也适用任何需要掌握人流量及空间使用率等情况的任何场景。这将重新定义未来建筑!”

意法半导体的AI解决方案业务线经理Miguel Castro补充说:“该项目证明深度学习能够提升嵌入式数据处理性能,展示了如何在基于经济型微控制器的系统平台上运行高价值的应用软件。我们的STM32Cube.AI生态系统使用户能够在很短的时间内开发出灵活的解决方案,利用我们技术团队的支持服务克服工程挑战,客户可以享受更高的设计效率。”

技术详情

STM32 AI生态系统提供了在STM32 MCU上运行神经网络所需的基本模块,可以实现经济、节能的解决方案,原生支持各种深度学习框架,例如:Keras、TensorFlow™Lite和ONNX交换格式。

在这个开发生态系统中,X-CUBE-AI软件扩展包扩大了STM32CubeMX初始化工具的功能,可以自动转换预先训练的神经网络,为目标MCU生成优化的软件库,并集成到用户的项目中。此外,还有很多其他的自动化功能,把开发者从繁重的开发任务中解放出来,例如,可以验证神经网络模型并测量STM32 MCU的性能,而无需人工开发C代码。

意法半导体的软件开发生态系统支持的普通DNN方案已经映射到STM32丰富的产品组合内,使用户可以有效地复制开发成果,为多个市场创建产品。在ST Live Days上运行演示应用的STM32H723 MCU完全胜任运行AI应用,因为这款产品的内核性能优异,闪存容量高达1Mbyte,提供高速片外存储器接口,以及各种传感器接口。

了解STM32Cube.AI更多信息,请访问 www.st.com/STM32CubeAI

了解STM32H7 MCU详情,请访问:https://www.st.com/en/microcontrollers-microprocessors/stm32h7-series.html

了解如何在STM32微控制器和应用处理器上运行边缘AI应用,请联系我们:edge.ai@st.com

关于意法半导体

意法半导体拥有46,000名半导体技术、产品和方案的创新者和创造者,掌握半导体供应链和最先进的制造设备。作为一家独立的半导体设备制造商,意法半导体与十万余客户、上千合作伙伴一起研发产品和解决方案,共同构建生态系统,帮助他们更好地应对各种挑战和新机遇,满足世界对可持续发展的更高需求。意法半导体的技术让人们的出行更智能,电力和能源管理更高效,物联网和5G技术应用更广泛。详情请浏览意法半导体公司网站:www.st.com

围观 31

2020年10月20日——意法半导体新推出的STM32 * Nucleo Shield显示板卡开创物联网产品人机界面之先河。新SPI Shield显示板卡X-NUCLEO- GFX01M1利用STM32G0微控制器(MCU)的经济性,支持引入低成本非内存映射SPI闪存IC支持等新功能的最新版TouchGFX软件(4.15.0版)。

如果采用STM32G0和TouchGFX开发项目,开发人员可用仅5美元的物料清单成本,给任何项目添加一个小图形界面屏幕,这样,定时器、控制器、家用电器等简单设备也能为用户带来类似智能手机的使用体验。

新的X-Nucleo-GFX01M1 Shield显示板卡支持新的X-cube-display软件包,该软件包提供了简单的“ hello world”界面例程。这款Shield板卡集成一块2.2英寸QVGA(320x240)SPI显示屏、64 Mbit SPI NOR闪存和一个控制手柄,可以与NUCLEO-G071RB等各种STM32 MCU开发板配套使用,STM32G071RB是一款主流的Arm®Cortex®-M0+ MCU,集成高达128KB闪存、36KB SRAM、各种通信接口、模拟外设、快速I/O端口、硬件安全ID和一个USB Type-C™Power Delivery控制器。

最新版TouchGFX软件基于TouchGFX引擎的部分帧缓存方法,可以将GUI 占用的RAM空间降低多达90%,并允许在只有16-20KB的MCU RAM内存中实现简单的用户界面。新版软件采用一种新的渲染算法增强GUI性能,通过一个优化的顺序先更新部分屏幕,然后再完成额外的帧更新,从而避免了分散注意力的撕裂视觉效果。另外一个新增功能是支持非内存映射SPI 闪存,使更复杂的GUI可以把图像、字体等占用大量内存空间的图形资源存放在低成本的外部存储器中。

为了简化用户界面原型设计,TouchGFX Designer还提供了为STM32G071 Nucleo开发板和显示开发套件优化的应用模板。必要时还可以把一个RTOS系统导入设置中,然后用TouchGFX Generator工具更换硬件。

所有软件组件现在都可以下载使用,包括X-cube-display软件包和TouchGFX 4.15.0,以及在G071RB开发板上运行的代码示例。X-NUCLEO- GFX01M1和STM32G0产品已批量生产,可通过正常的意法半导体代理渠道购买。

此外,还有一个新的图形小工具,可以简化使用线、柱状图、面积图、直方图或组合图显示顺序数据。这个小程序可以在任何一个STM32 MCU上运行顺畅运行。开发人员可以使用TouchGFX Designer自定义颜色、布局等参数。

对STM32H725的全面的即用支持也是TouchGFX 4.15.0的新特性,使开发人员可以在

意法半导体的Cortex-M7 MCU上运行微处理器级的图形。STM32H725是STM32系列最新的图形应用旗舰产品,搭载550MHz处理器内核,采用意法半导体的Chrom-ART Accelerator™图形加速技术,可以提供更快的图形处理性能;8针SPI接口用于高速连接外部闪存和RAM,以及XGA TFT-LCD显示控制器。TouchGFX Designer包含例程源代码,点击此处可以下载演示视频。

了解更多信息,免费下载软件,请访问http://www.st.com/x-cube-touchgfx

或访问 https://blog.st.com/x-nucleo-gfx01m1/ 阅读相关博文。

关于意法半导体

意法半导体拥有46,000名半导体技术、产品和方案的创新者和创造者,掌握半导体供应链和最先进的制造设备。作为一家独立的半导体设备制造商,意法半导体与十万余客户、上千合作伙伴一起研发产品和解决方案,共同构建生态系统,帮助他们更好地应对各种挑战和新机遇,满足世界对可持续发展的更高需求。意法半导体的技术让人们的出行更智能,电力和能源管理更高效,物联网和5G技术应用更广泛。详情请浏览意法半导体公司网站:www.st.com

围观 63

自2018年第一颗无线MCU系列STM32WB问世,STM32便迈入无线进击路。ST不断推出一系列具备强大无线连接能力的STM32产品,全面支持各种短距离(Zigbee、WiFi、蓝牙、Z-wave)、广域网通信标准(LoRa、SigFox、EC-GSM、LTE-M、NB-IoT 等),从产品、模组、封装、安全、认证到软硬件生态系统,ST为物联网应用提供了360度无缝解决方案,助用户顺利在物联网世界里乘风破浪、开疆拓土。

▲ ST为物联网连接提供360度无缝解决方案

STM32无线MCU现有两条产品线:

  • STM32WL是全球首颗内置LoRa收发器的SoC,能够加快LoRa® IoT智能设备开发,满足广域物联网通信需求;
  • STM32WB是首个支持蓝牙和802.15.4协议的ST解决方案,满足短距离物联网连接需求。

未来,ST还会将无线通信支持拓展到UWB、NB-IoT、LTE-M等主流通信标准,以全面满足物联网联网需求。

STM32WB:多协议+安全SoC的开路先锋

ST在2019年重磅推出双核多协议无线STM32WB微控制器。STM32WB是新一代无线双核微控制器,全球首个将多协议+安全(双核,FUS, RSS…)结合在一起的SoC,支持主流2.4GHz的多种协议栈,如BLE,ZigBee,Thread等;还支持静态和动态并发的模式,可同时运行多个协议栈。STM32WB具有高集成度、高性能、低功耗等特点,非常适用于工业网关、电信设备、家庭自动化、家电产品、智能消费电子、AI以及各种802.15. 4的无线场景;其优异的安全功能,诸如密码算法加速器和安全密钥存储等,可确保物联网硬件数据安全,是物联网硬件开发人员的最佳选择。

▲ STM32WB的八大产品特性

STM32WB的双核架构可实现固件隔离和安全分区,从而提供了物联网应用最迫切需要的安全性能。除了内置的巴伦, STM32WB还有专用于STM32WB的集成滤波器可配合使用,最大化了多协议射频性能,且占用PCB面积是分离方案的1/7。

在网关场景中,STM32WB提供BLE+Thread并发操作,可同时连接BLE和Thread网络。用户可以通过智能手机享受BLE连接的好处,同时还可以接入Thread网络;STM32WB还提供BLE+Zigbee并发操作,可以同时接入BLE和Zigbee网络。接入网络一直是Zigbee网络的一个缺陷,但是有了STM32WB,完美化解这个缺陷。ST还计划提供BLE+802.15.4并发操作,将在2020年第四季度发布。通过这种方法,客户可以创建自己的私有网状网络,同时还可以方便地连接智能手机。目前有一些工业客户正在寻找这种类型的解决方案。

▲ STM32WB可实现灵活的BLE+Thread应用方案

STM32WB55/50:最先问世的高配置版

STM32WB55微控制器最先问世,为高性能高配置版,在无线连接和安全性能各方面达到最佳。其双核是主频为64 MHz的® Cortex®‐M4核心(应用处理器)和主频为32 MHz的Arm® Cortex®‐M0+核心(网络处理器),支持Bluetooth™ 5和IEEE 802.15.4无线标准,产品可以使用不同的软件实现不同架构BLE、ZigBee自由切换, 一颗芯片可以通过时分复用做成BLE + ZigBee形式。两个完全独立的核心使该创新型架构能最优化地支持实时执行(与无线电相关的软件处理)、灵活的资源使用和电源管理,从而实现更低的BOM成本和更好的用户体验。STM32WB55系列还包含嵌入式安全硬件功能,如256位AES硬件加密、PCROP读写保护、JTAG熔丝位、采用椭圆曲线加密引擎的公钥加密等。

▲ STM32WB55框图

STM32WB50是超值高性价比版本,与STM32WB55系统芯片引脚兼容,同样沿袭双核架构并支持多种无线协议。可用于需要支持Bluetooth® 5.0、ZigBee® 3.0或OpenThread标准的成本敏感型物联网设备。该系列产品提供从蓝牙5.0模式的100dB到802.15.4模式的104dB的良好链路预算。STM32WB50 将强大的安全性和超值系列的经济性集于一身。片上集成AES-256加密模块以及其它的基本安全功能,为应用提供强大的安全保障。STM32WB50 沿用STM32WB55的省电模式,是节能省电应用的理想选择。作为STM32WB55的一个完整的衍生产品,STM32WB50 同样支持经过市场检验的STM32Cube生态系统。

STM32WB35/30:将性价比推向极致

金秋10月,STM32WB无线MCU产品线再添新丁,STM32WB55的低成本版本STM32WB35/30将性价比推向极致。

▲ STM32WB各产品系列比较

成本 与STM32WB55/50相比,STM32WB35的成本更低。STM32WB30则是成本最低的ST蓝牙+ 802.15.4解决方案。
外设 同STM32WB55相比,STM32WB35没有LCD;
射频 STM32WB55支持动态多协议, STM32WB35/50/30 只支持某一种协议;
封装 STM32WB55封装类型最多,STM32WB35/50/30只有QFN48, 且和STM32WB55 QFN48 pin 2 pin兼容。

▲ STM32WB35框图

STM32WB35主要特性包括:

  • CM4 DSP/FPU 高达64MHz
  • 高达512KB Flash 和 96KB SRAM
  • 射频
  • 射频集成平衡不平衡器(Balun)
  • 低功耗蓝牙5.0 和802.15.4
  • 输出功率: +6.0 dBm (支持外部PA)
  • BLE 接收灵敏度: -96 dBm @ 1Mbps (102dB链路预算)
  • 802.15.4 接收灵敏度: -100 dBm @ 250kbps (106dB链路预算)
  • 接收(RX): 4.5mA 和发送(TX): 5.2mA (0dBm)
  • 外设
    - 2xI2C, 1xUSART, 1xLP-UART, 2xSPI (+ I2S), Q-SPI, 1xUSB 2.0 FS device
    - 6x 定时器: 包括2x LP-16-bit
    - 2x 超低功耗比较器
  • 工作电压1.71V 至3.6V (DC/DC, LDO)
  • 工作温度-40°C 至+105°C
  • 功耗
    - 运行模式< 53µA/MHz (3V - RF ON)
    - 待机模式0.6 µA (射频待机+ 32KB SRAM2a)
    - 关闭模式< 30nA

▲ STM32WB各产品系列定位

在消费类、智能家居、智能工业及医疗健康等不同应用领域里,STM32WB35/30将与它的兄弟STM32WB55/50携手,让物联网用户都能找到最适合自己的解决方案,迸发出更多创造力!

强大的STM32WB生态系统

ST为STM32WB产品提供了从硬件、软件开发工具等完整的生态系统,从配置、开发、下载、到监控的一站式开发平台,构建无缝的开发流程。

  • STM32CubeMX:配置硬件引脚,使HW开发更容易;配置BLE 广播、配对、Service服务, 使SW 开发更容易
  • STM32CubeIDE:代码编辑/代码编译链接/代码调试/代码烧写
  • STM32CubeWB:固件例程
  • STM32CubeProgrammer:烧写、读取片上存储区/烧写、读取片外存储区/烧写、读取选项字节/
  • STM32Cube Monitor/ STM32CubeMonRF:功耗测试,无线蓝牙调试,USB PD调试

▲ 强大的STM32WB生态系统

来源: STM32单片机
https://mp.weixin.qq.com/s/sjpJ4ZFVBoE-dL5Iv1N66A

围观 29

页面

订阅 RSS - STM32