(转)aardio字符串模式匹配快速入门

回复

其他分享admin 回复了问题 • 1 人关注 • 8 个回复 • 92 次浏览 • 1 天前 • 来自相关话题

用cube生成的mdk工程编译很缓慢

问题困惑admin 回复了问题 • 2 人关注 • 1 个回复 • 29 次浏览 • 1 天前 • 来自相关话题

TIM1输入捕获模式测量脉冲宽度和频率

回复

软件教程admin 回复了问题 • 1 人关注 • 3 个回复 • 86 次浏览 • 2 天前 • 来自相关话题

上位机学习之aardio笔记3

回复

其他分享admin 回复了问题 • 1 人关注 • 1 个回复 • 49 次浏览 • 3 天前 • 来自相关话题

小白问题 stm32cube生成工错误

新手交流起点VS 回复了问题 • 2 人关注 • 2 个回复 • 47 次浏览 • 3 天前 • 来自相关话题

(转)通过后备数据寄存器RTC_BKP0R从用户代码调用系统bootloader来更新应用程序

经验分享admin 发表了文章 • 0 个评论 • 71 次浏览 • 5 天前 • 来自相关话题

我们知道,任何STM32芯片内都包含有一块系统存储器(SystemMemory),里边存储着内部的启动代码Bootloader。不同的STM32型号所支持的用于升级代码的通讯口不尽相同,需要参考应用笔记AN2606。但是,有一个问题避免不了,那就是如何进入System Memory去执行Bootloader?通常的办法都是将BOOT1和BOOT0进行配置:BOOT0拉高,BOOT1拉低(注意:有些型号的BOOT1由选项字节nBOOT1控制)。可是在一些产品中,由于外观的要求,往往不方便在外边开口去放置按键或跳线来改变BOOT脚的电平。而且,用户并不想自己写IAP代码,觉得麻烦。特别是一些产品,需要使用USBDFU来进行代码升级的,而在产品功能中USB又没用到,用户就会觉得自己为了一个通过USB进行代码升级的功能,去写IAP的话,需要去熟悉USB的代码,觉得麻烦,而且这些USB的代码还占用了用户的程序空间。对于这些用户来讲,他们很希望能在不管BOOT脚的情况下能够去调用STM32中System Memory的Bootloader,完成代码升级功能。1.判断其可行性首先,打开应用笔记AN2606《STM32 microcontroller system memory bootmode》,翻到3.1 Bootloader activation一节的最后,可以看到如下信息:这里的意思就是说,用户可以通过从用户代码跳转到系统存储器去执行Bootloader。但是,在跳转到Bootloader之前,有几个事情必须要做好:     1) 关闭所有外设的时钟                            2) 关闭使用的PLL3) 禁用所有中断4) 清除所有挂起的中断标志位最后,去掉Bootloader的激活条件并产生一个硬件复位去执行用户代码,也可以直接使用Go命令去执行用户代码。 那么,如何从用户代码跳转到System Memory中去呢?这个其实并不难,如果写过IAP,或者看过关于IAP的应用笔记中的参考代码的话,比如应用笔记AN3965“STM32F40x/STM32F41x in-application programming using theUSART”及其参考代码STSW-STM32067,都应该知道,IAP的启动代码通过重新设置主堆栈指针并跳转到用户代码来执行用户代码的。同样的道理,只要知道SystemMemory的地址,一样可以从用户代码通过重新设置主堆栈指针并跳转到System Memory来执行Bootloader。而System Memory地址可以从参考手册来获得。比如,查看STM32F411的参考手册RM0383,可以找到如下的表格:那很多人又会问了,我的代码很复杂,用了很多外设,开了很多中断,可是要跳转到System Memory中的Bootloader,需要关所有外设的时钟,需要关PLL,需要关闭所有中断,需要禁用所有的中断,清除所有挂起的中断。这可是一项非常庞大的的任务啊!所以,在这里,我们需要一个更简单的事情来完成这项庞大的任务。其实真的就有这么简单的一个方法——复位!通过软件复位来实现这一目的。但是,复位后,又怎么知道还记得我们要去做代码升级呢?这又要用到STM32另一个特性了,那就是后备数据寄存器Backup Data Registers在软件复位后会保留其值,这样给了我们在复位前后做一个标志的机会。这样,考证下来,客户的需求是具备可行性的。接下来需要做的是理清思路。2.软件流程这里使用32F411EDISCOVERY板来设计一个参考例程:设计一个用户程序,让LED3进行闪烁;当用户按键被按下,产生EXTI中断,在中断中选择后备数据寄存器RTC_BKP0R,写入值0x32F2,然后产生软件复位;软件复位后,在运行代码的最前面对RTC_BKP0R进行判断,如果其值不是0x32F2则直接去运行用户代码,如果其值为0x32F2则是需要跳转到Bootloader去进行代码升级,并在跳转前将RTC_BKP0R清零。这样,在进入Bootloader后,客户进行USB DFU升级后,将来不会因为不需要升级代码的复位而误入Bootloader。 来看软件流程图,先来看主程序的流程图:3.主要代码使用STM32F4Cube库来开发这个例程。先来看位于main.c中的main函数:int main(void)
{
  /* STM32F4xx HALlibrary initialization:
- Configure theFlash prefetch, Flash preread and Buffer caches
- Systick timer isconfigured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base durationshould be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled inmilliseconds basis.
 - Low LevelInitialization     */

  HAL_Init();
 
  /* Configure the Systemclock to have a frequency of 100 MHz */
  SystemClock_Config();
 
  /* Configure LED3,LED4, LED5 and LED6 */
  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  BSP_LED_Init(LED5);
  BSP_LED_Init(LED6); 
 
  /* Configure EXTI Line0(connected to PA0 pin) in interrupt mode */
  EXTILine0_Config();
 
  /* Infinite loop */
  while (1)
  {
  }
}Main函数很简单,配置系统时钟,对使用的LED进行初始化,然后配置了用户按键的EXTI中断,然后就进入主循环了。前面说到,要实现用户的功能程序为LED3闪烁,在主循环我们没看到,是因为在Cube库中,会使用SysTick,所以把LED3的闪烁放到SysTick的中断代码中了,查看stm32f4xx_it.c,如下:void SysTick_Handler(void)
{
  HAL_IncTick();
 
  // LED3 Toggle
  led_toggle_counter++;
  if (led_toggle_counter>= 500)
  {
    led_toggle_counter =0;
    BSP_LED_Toggle(LED3);
  }
}从main函数最开始的那段注释中知道,跳入main函数前,在startup_stm32f411xe.s中早已经先调用执行了位于system_stm32f4xx.c中的SystemInit函数。SystemInit函数主要执行初始化FPU、复位RCC时钟寄存器、配置向量表等功能。由于我们希望在最原始的状态下进入SystemMemory,所以我们将跳转到System Memory放在这个函数的最前头,如下:void SystemInit(void)
{
  /* Check if need to gointo bootloader before configure clock*/
  RtcHandle.Instance =RTC; 
 if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) ==0x32F2)
  {
   __HAL_RCC_PWR_CLK_ENABLE();
   HAL_PWR_EnableBkUpAccess();
   __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV2);
   __HAL_RCC_RTC_ENABLE();
   HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0,0x0);
   __HAL_RCC_RTC_DISABLE();
    HAL_PWR_DisableBkUpAccess();
   __HAL_RCC_PWR_CLK_DISABLE();
   
   __set_MSP(*(__IO uint32_t*) 0x1FFF0000);
   SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FFF0004));
   SysMemBootJump();
    while (1);
  }
 
  /* FPU settings------------------------------------------------------------*/
  #if (__FPU_PRESENT ==1) && (__FPU_USED == 1)
    SCB->CPACR |=((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clockconfiguration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |=(uint32_t)0x00000001;
 
  /* Reset CFGR register*/
  RCC->CFGR =0x00000000;
 
  /* Reset HSEON, CSSONand PLLON bits */
  RCC->CR &=(uint32_t)0xFEF6FFFF;
 
  /* Reset PLLCFGRregister */
  RCC->PLLCFGR =0x24003010;
 
  /* Reset HSEBYP bit */
  RCC->CR &=(uint32_t)0xFFFBFFFF;
 
  /* Disable allinterrupts */
  RCC->CIR =0x00000000;
 
  /* Configure the VectorTable location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR =SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR =FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}可以看到,在函数的最前面对RTC_BKP_DR0进行了判断,如果其值为0x32F2的话,则先启动备份域的写入时序,如RM0383中5.1.2 Battery backup domain所描述的:然后将RTC_BKP_DR0清零,再关闭执行这次操作所打开的时钟。主堆栈指针MSP的初始值位于向量表偏移量为0x00的位置,复位Reset的值则位于向量表偏移量为0x04的位置。对于STM32F411来说,当执行System Memeory中的Bootloader时,MSP的初始值位于0x1FFF0000,而Reset向量则位于0x1FFF0004。所以在程序中,使用__set_MSP(*(__IO uint32_t*) 0x1FFF0000);来重新设置主堆栈指针,而后再跳转到0x1FFF0004所指向的程序地址去执行Bootloader。 再来看位于stm32f4xx_it.c中的EXTI中断程序:void EXTI0_IRQHandler(void)
{
 HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
}
及其位于main.c中的Callback函数:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin ==KEY_BUTTON_PIN)
  {
   __HAL_RCC_PWR_CLK_ENABLE();
   HAL_PWR_EnableBkUpAccess();
   __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV2);
   __HAL_RCC_RTC_ENABLE();
    RtcHandle.Instance =RTC;
   HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0,0x32F2);
   if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)
    {
      // Write backupdata memory failed
      BSP_LED_On(LED5);
      while (1) ;               // Error
    }
    else
    {
      // Write backupdata memory succeeded.
      BSP_LED_On(LED6);
      HAL_NVIC_SystemReset();   // Software reset for going into bootloader
      while (1)   ;
    }
  }
}当判断到用户按键按下,需要进行用户代码升级时,先启动备份域的访问时序,将RTC_BKP_DR0的值写为0x32F2。再读回来判断是否写入成功,以方便调试。如果写入成功后,则就调用HAL_NVIC_SystemReset()进行软件复位。重新复位后,就可以进入System Memory了。原帖地址:http://mp.weixin.qq.com/s/WptYinG-5pCjLt2x7E20SA 查看全部

我们知道,任何STM32芯片内都包含有一块系统存储器(SystemMemory),里边存储着内部的启动代码Bootloader。不同的STM32型号所支持的用于升级代码的通讯口不尽相同,需要参考应用笔记AN2606。

但是,有一个问题避免不了,那就是如何进入System Memory去执行Bootloader?

通常的办法都是将BOOT1和BOOT0进行配置:BOOT0拉高,BOOT1拉低(注意:有些型号的BOOT1由选项字节nBOOT1控制)。

可是在一些产品中,由于外观的要求,往往不方便在外边开口去放置按键或跳线来改变BOOT脚的电平。

而且,用户并不想自己写IAP代码,觉得麻烦。特别是一些产品,需要使用USBDFU来进行代码升级的,而在产品功能中USB又没用到,用户就会觉得自己为了一个通过USB进行代码升级的功能,去写IAP的话,需要去熟悉USB的代码,觉得麻烦,而且这些USB的代码还占用了用户的程序空间。对于这些用户来讲,他们很希望能在不管BOOT脚的情况下能够去调用STM32中System Memory的Bootloader,完成代码升级功能。


1.判断其可行性

首先,打开应用笔记AN2606《STM32 microcontroller system memory bootmode》,翻到3.1 Bootloader activation一节的最后,可以看到如下信息:

blob.png


这里的意思就是说,用户可以通过从用户代码跳转到系统存储器去执行Bootloader。但是,在跳转到Bootloader之前,有几个事情必须要做好:

     1) 关闭所有外设的时钟                            

2) 关闭使用的PLL

3) 禁用所有中断

4) 清除所有挂起的中断标志位

最后,去掉Bootloader的激活条件并产生一个硬件复位去执行用户代码,也可以直接使用Go命令去执行用户代码。

 

那么,如何从用户代码跳转到System Memory中去呢?这个其实并不难,如果写过IAP,或者看过关于IAP的应用笔记中的参考代码的话,比如应用笔记AN3965“STM32F40x/STM32F41x in-application programming using theUSART”及其参考代码STSW-STM32067,都应该知道,IAP的启动代码通过重新设置主堆栈指针并跳转到用户代码来执行用户代码的。同样的道理,只要知道SystemMemory的地址,一样可以从用户代码通过重新设置主堆栈指针并跳转到System Memory来执行Bootloader。而System Memory地址可以从参考手册来获得。比如,查看STM32F411的参考手册RM0383,可以找到如下的表格:

blob.png

那很多人又会问了,我的代码很复杂,用了很多外设,开了很多中断,可是要跳转到System Memory中的Bootloader,需要关所有外设的时钟,需要关PLL,需要关闭所有中断,需要禁用所有的中断,清除所有挂起的中断。这可是一项非常庞大的的任务啊!所以,在这里,我们需要一个更简单的事情来完成这项庞大的任务。其实真的就有这么简单的一个方法——复位!通过软件复位来实现这一目的。但是,复位后,又怎么知道还记得我们要去做代码升级呢?这又要用到STM32另一个特性了,那就是后备数据寄存器Backup Data Registers在软件复位后会保留其值,这样给了我们在复位前后做一个标志的机会。

这样,考证下来,客户的需求是具备可行性的。接下来需要做的是理清思路。


2.软件流程

这里使用32F411EDISCOVERY板来设计一个参考例程:设计一个用户程序,让LED3进行闪烁;当用户按键被按下,产生EXTI中断,在中断中选择后备数据寄存器RTC_BKP0R,写入值0x32F2,然后产生软件复位;软件复位后,在运行代码的最前面对RTC_BKP0R进行判断,如果其值不是0x32F2则直接去运行用户代码,如果其值为0x32F2则是需要跳转到Bootloader去进行代码升级,并在跳转前将RTC_BKP0R清零。这样,在进入Bootloader后,客户进行USB DFU升级后,将来不会因为不需要升级代码的复位而误入Bootloader。

 

来看软件流程图,先来看主程序的流程图:

blob.png

blob.png

3.主要代码

使用STM32F4Cube库来开发这个例程。先来看位于main.c中的main函数:

int main(void)
{
  /* STM32F4xx HALlibrary initialization:
- Configure theFlash prefetch, Flash preread and Buffer caches
- Systick timer isconfigured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base durationshould be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled inmilliseconds basis.
 - Low LevelInitialization     */

  HAL_Init();
 
  /* Configure the Systemclock to have a frequency of 100 MHz */
  SystemClock_Config();
 
  /* Configure LED3,LED4, LED5 and LED6 */
  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  BSP_LED_Init(LED5);
  BSP_LED_Init(LED6); 
 
  /* Configure EXTI Line0(connected to PA0 pin) in interrupt mode */
  EXTILine0_Config();
 
  /* Infinite loop */
  while (1)
  {
  }
}

Main函数很简单,配置系统时钟,对使用的LED进行初始化,然后配置了用户按键的EXTI中断,然后就进入主循环了。前面说到,要实现用户的功能程序为LED3闪烁,在主循环我们没看到,是因为在Cube库中,会使用SysTick,所以把LED3的闪烁放到SysTick的中断代码中了,查看stm32f4xx_it.c,如下:

void SysTick_Handler(void)
{
  HAL_IncTick();
 
  // LED3 Toggle
  led_toggle_counter++;
  if (led_toggle_counter>= 500)
  {
    led_toggle_counter =0;
    BSP_LED_Toggle(LED3);
  }
}

从main函数最开始的那段注释中知道,跳入main函数前,在startup_stm32f411xe.s中早已经先调用执行了位于system_stm32f4xx.c中的SystemInit函数。SystemInit函数主要执行初始化FPU、复位RCC时钟寄存器、配置向量表等功能。由于我们希望在最原始的状态下进入SystemMemory,所以我们将跳转到System Memory放在这个函数的最前头,如下:

void SystemInit(void)
{
  /* Check if need to gointo bootloader before configure clock*/
  RtcHandle.Instance =RTC; 
 if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) ==0x32F2)
  {
   __HAL_RCC_PWR_CLK_ENABLE();
   HAL_PWR_EnableBkUpAccess();
   __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV2);
   __HAL_RCC_RTC_ENABLE();
   HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0,0x0);
   __HAL_RCC_RTC_DISABLE();
    HAL_PWR_DisableBkUpAccess();
   __HAL_RCC_PWR_CLK_DISABLE();
   
   __set_MSP(*(__IO uint32_t*) 0x1FFF0000);
   SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FFF0004));
   SysMemBootJump();
    while (1);
  }
 
  /* FPU settings------------------------------------------------------------*/
  #if (__FPU_PRESENT ==1) && (__FPU_USED == 1)
    SCB->CPACR |=((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clockconfiguration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |=(uint32_t)0x00000001;
 
  /* Reset CFGR register*/
  RCC->CFGR =0x00000000;
 
  /* Reset HSEON, CSSONand PLLON bits */
  RCC->CR &=(uint32_t)0xFEF6FFFF;
 
  /* Reset PLLCFGRregister */
  RCC->PLLCFGR =0x24003010;
 
  /* Reset HSEBYP bit */
  RCC->CR &=(uint32_t)0xFFFBFFFF;
 
  /* Disable allinterrupts */
  RCC->CIR =0x00000000;
 
  /* Configure the VectorTable location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR =SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR =FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

可以看到,在函数的最前面对RTC_BKP_DR0进行了判断,如果其值为0x32F2的话,则先启动备份域的写入时序,如RM0383中5.1.2 Battery backup domain所描述的:

blob.png

然后将RTC_BKP_DR0清零,再关闭执行这次操作所打开的时钟。

主堆栈指针MSP的初始值位于向量表偏移量为0x00的位置,复位Reset的值则位于向量表偏移量为0x04的位置。对于STM32F411来说,当执行System Memeory中的Bootloader时,MSP的初始值位于0x1FFF0000,而Reset向量则位于0x1FFF0004。所以在程序中,使用__set_MSP(*(__IO uint32_t*) 0x1FFF0000);来重新设置主堆栈指针,而后再跳转到0x1FFF0004所指向的程序地址去执行Bootloader。

 

再来看位于stm32f4xx_it.c中的EXTI中断程序:

void EXTI0_IRQHandler(void)
{
 HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
}
及其位于main.c中的Callback函数:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin ==KEY_BUTTON_PIN)
  {
   __HAL_RCC_PWR_CLK_ENABLE();
   HAL_PWR_EnableBkUpAccess();
   __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV2);
   __HAL_RCC_RTC_ENABLE();
    RtcHandle.Instance =RTC;
   HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0,0x32F2);
   if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)
    {
      // Write backupdata memory failed
      BSP_LED_On(LED5);
      while (1) ;               // Error
    }
    else
    {
      // Write backupdata memory succeeded.
      BSP_LED_On(LED6);
      HAL_NVIC_SystemReset();   // Software reset for going into bootloader
      while (1)   ;
    }
  }
}

当判断到用户按键按下,需要进行用户代码升级时,先启动备份域的访问时序,将RTC_BKP_DR0的值写为0x32F2。再读回来判断是否写入成功,以方便调试。如果写入成功后,则就调用HAL_NVIC_SystemReset()进行软件复位。重新复位后,就可以进入System Memory了。


原帖地址:http://mp.weixin.qq.com/s/WptYinG-5pCjLt2x7E20SA


滤波算法学习与讨论

新手交流admin 发表了文章 • 3 个评论 • 101 次浏览 • 6 天前 • 来自相关话题

最近要用到滤波算法,先前转载了个卡尔曼的c,但是不知道效果和怎么使用,听说研究算法都要用到matlab,可惜不会...就用aar+echarts来表示下波形好了.上图是我在aar里直接调用C语言的那个卡尔曼产生的波形.感觉不忍直视,算法肯定调用有错误,这个aar调用c函数看来应该不像想象中那样用....var data1string ,data2string,data3string = "{data:[","{data:[","{data:[";

//aardio调用C语言函数
var code = /****
#include <stdio.h>
#include <stdlib.h> 

long KalmanFilter(long ResrcData)
{
     /*-------------------------------------------------------------------------------------------------------------*/
     /*
             Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏
             R:测量噪声,R增大,动态响应变慢,收敛稳定性变好
     */
     /*-------------------------------------------------------------------------------------------------------------*/
     static long R = (int32_t)(128*1024);
     static long Q = (int32_t)4;
     static long Counter1 ;
     static long Counter2;
     static long x_last;
        static long p_last;   // 应赋初始估计值
     long x_mid;
     long x_now;
     long p_mid ;
     long p_now;
 
     ResrcData *= 1024;
     x_now = ResrcData - x_last;
     if(x_now < 0)
     {
         x_now *= -1; // 取绝对值
     }
     if(x_now >= 32*1024)   // 如果测量值连续比估计值大或小 相信测量值,加速迭代
     {
         Counter1++;
         Counter2 = 0;
         if(Counter1 > 10)
         {
             R = 512;;
             Q = 128;
         }
     }
     else                 // 数据比较稳定,加强滤波 
     {
         Counter1 = 0;
         Counter2++;
         if(Counter2 > 10)  
         {
             R = (int)(128*1024);
             Q = (int)4;
         }
     }
     x_mid = x_last;   // x_last=x(k-1|k-1),x_mid=x(k|k-1)
     p_mid = p_last + Q; // p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声
//    kg = p_mid/(p_mid + R); //kg为kalman filter,R为噪声
//    x_now = x_mid+kg*(ResrcData - x_mid);// 估计出的最优值
     x_now = x_mid + (p_mid*(ResrcData - x_mid))/(p_mid + R);
//    p_now = (1 - kg)*p_mid; // 最优值对应的covariance
     p_now = p_mid - p_mid*p_mid/(p_mid + R); // 最优值对应的covariance
     p_last = p_now;  // 更新covariance值
     x_last = x_now;  // 更新系统状态值
     x_now /= 1024;
     if((x_now > 4096)||( x_now < 0))
     {
         x_last = ResrcData;
         p_now = ResrcData;
         x_now = ResrcData/1024;
     }
     return (int)x_now;
}

****/
mainForm.button2.oncommand = function(id,event){
//mainForm.msgbox( mainForm.button2.text );

import console;
import tcc;  
console.open()

var vm = tcc( ); //创建TCC编译器 
vm.compile(code); //编译C源码

//调用C函数
var data1,data2 = 0,0;
for(i=1;179;1){
data1 = math.round(math.sin(math.rad(i))*500);
data2 = math.round(math.sin(math.rad(i))*500) + math.random(-5, 5);
var ret = vm.KalmanFilter(data2);
console.log( "C函数返回值2",data1,data2, ret )

data1string = data1string ++ data1 ++ ",";
data2string = data2string ++ data2 ++ ",";
data3string = data3string ++ ret ++ ",";
//console.more(50)
}




}

mainForm.button3.oncommand = function(id,event){
//mainForm.msgbox( mainForm.button3.text );


var datastr;
var datalist_start = "var option = { series:["
var datalist_end = "] }; myChart.setOption(option);";

datastr = datalist_start ++ data1string ++ "]},"++ data2string ++ "]},"++ data3string ++ "]}," ++ datalist_end;
wbKitView.doScript(datastr);
}下面还是老老实实把C转换成aar语句去.. 查看全部

最近要用到滤波算法,先前转载了个卡尔曼的c,但是不知道效果和怎么使用,

听说研究算法都要用到matlab,可惜不会...

就用aar+echarts来表示下波形好了.

blob.png

上图是我在aar里直接调用C语言的那个卡尔曼产生的波形.

感觉不忍直视,算法肯定调用有错误,这个aar调用c函数看来应该不像想象中那样用....

var data1string ,data2string,data3string = "{data:[","{data:[","{data:[";	

//aardio调用C语言函数
var code = /****
#include <stdio.h>
#include <stdlib.h> 

long KalmanFilter(long ResrcData)
{
     /*-------------------------------------------------------------------------------------------------------------*/
     /*
             Q:过程噪声,Q增大,动态响应变快,收敛稳定性变坏
             R:测量噪声,R增大,动态响应变慢,收敛稳定性变好
     */
     /*-------------------------------------------------------------------------------------------------------------*/
     static long R = (int32_t)(128*1024);
     static long Q = (int32_t)4;
     static long Counter1 ;
     static long Counter2;
     static long x_last;
        static long p_last;   // 应赋初始估计值
     long x_mid;
     long x_now;
     long p_mid ;
     long p_now;
 
     ResrcData *= 1024;
     x_now = ResrcData - x_last;
     if(x_now < 0)
     {
         x_now *= -1; // 取绝对值
     }
     if(x_now >= 32*1024)   // 如果测量值连续比估计值大或小 相信测量值,加速迭代
     {
         Counter1++;
         Counter2 = 0;
         if(Counter1 > 10)
         {
             R = 512;;
             Q = 128;
         }
     }
     else                 // 数据比较稳定,加强滤波 
     {
         Counter1 = 0;
         Counter2++;
         if(Counter2 > 10)  
         {
             R = (int)(128*1024);
             Q = (int)4;
         }
     }
     x_mid = x_last;   // x_last=x(k-1|k-1),x_mid=x(k|k-1)
     p_mid = p_last + Q; // p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声
//    kg = p_mid/(p_mid + R); //kg为kalman filter,R为噪声
//    x_now = x_mid+kg*(ResrcData - x_mid);// 估计出的最优值
     x_now = x_mid + (p_mid*(ResrcData - x_mid))/(p_mid + R);
//    p_now = (1 - kg)*p_mid; // 最优值对应的covariance
     p_now = p_mid - p_mid*p_mid/(p_mid + R); // 最优值对应的covariance
     p_last = p_now;  // 更新covariance值
     x_last = x_now;  // 更新系统状态值
     x_now /= 1024;
     if((x_now > 4096)||( x_now < 0))
     {
         x_last = ResrcData;
         p_now = ResrcData;
         x_now = ResrcData/1024;
     }
     return (int)x_now;
}

****/
mainForm.button2.oncommand = function(id,event){
//mainForm.msgbox( mainForm.button2.text );

import console;
import tcc;  
console.open()

var vm = tcc( ); //创建TCC编译器 
vm.compile(code); //编译C源码

//调用C函数
var data1,data2 = 0,0;
for(i=1;179;1){
data1 = math.round(math.sin(math.rad(i))*500);
data2 = math.round(math.sin(math.rad(i))*500) + math.random(-5, 5);
var ret = vm.KalmanFilter(data2);
console.log( "C函数返回值2",data1,data2, ret )

data1string = data1string ++ data1 ++ ",";
data2string = data2string ++ data2 ++ ",";
data3string = data3string ++ ret ++ ",";
//console.more(50)
}




}

mainForm.button3.oncommand = function(id,event){
//mainForm.msgbox( mainForm.button3.text );


var datastr;
var datalist_start = "var option = { series:["
var datalist_end = "] }; myChart.setOption(option);";

datastr = datalist_start ++ data1string ++ "]},"++ data2string ++ "]},"++ data3string ++ "]}," ++ datalist_end;
wbKitView.doScript(datastr);
}

下面还是老老实实把C转换成aar语句去..

CubeMX4.20.1生成程序并下载后无法调试

问题困惑jialian4213 回复了问题 • 2 人关注 • 15 个回复 • 103 次浏览 • 2017-06-15 18:44 • 来自相关话题

上位机学习笔记:Hid上位机软件的实现

回复

经验分享admin 回复了问题 • 2 人关注 • 20 个回复 • 1439 次浏览 • 2017-06-14 21:51 • 来自相关话题

关于stm32cube有相关的视频教程吗

新手交流admin 回复了问题 • 2 人关注 • 1 个回复 • 101 次浏览 • 2017-06-14 18:05 • 来自相关话题