搜索
bottom↓
回复: 57

QP™状态机框架学习之菜鸟范例(一):闪灯(MDK,STM32F10x)

  [复制链接]

出130入129汤圆

发表于 2014-2-5 10:05:18 | 显示全部楼层 |阅读模式
本帖最后由 68336016 于 2014-2-5 11:36 编辑

      只是算我个人学习QP™状态机框架的一个笔记吧,因为我学习东西没耐心一开始就看上几百页的书,看完之后满头雾水还不知道怎么入手。
所以我一般都是大概了解下概念,然后简单例子入手,以逐步加深认识,增强信心。

      前提:使用MDK环境,STM32F10x芯片。

      QP产品里几个名词区别:

暂时用得上的只是QP/C,QM,打开上面链接下载exe版本,一路点击NEXT安装完就行。

/*****************************************************************************************************************************************************/

这是代码,运行起来再说其它的。
我用的是MDK4.70,STM32F103R8T6,LED引脚是PB15,高电平点亮。
libqp_Cortex-M3.a路径为:..\QPC\ports\arm-cm\vanilla\arm_keil\rel\libqp_Cortex-M3.a



bsp.h
  1. #ifndef bsp_h
  2. #define bsp_h

  3. void BSP_init(void);
  4. void BSP_led_Off(void);
  5. void BSP_led_On(void);
  6.                                                             /* bsp_h */
  7. #endif
复制代码

bsp.c
  1. #include "qp_port.h"
  2. #include "bsp.h"
  3. #include "hw_config.h"
  4. #include "stm32f10x_lib.h"

  5. /*..........................................................................*/
  6. void BSP_init(void) {
  7.         System_Init();                //系统初始化函数,定义在hw_config.c
  8. }

  9. /*..........................................................................*/
  10. void BSP_led_Off(void) {
  11.         GPIOB->BRR = GPIO_Pin_15;
  12. }

  13. /*..........................................................................*/
  14. void BSP_led_On(void) {
  15.         GPIOB->BSRR = GPIO_Pin_15;
  16. }
复制代码

blinky.c
  1. /* @(/1/1/0) ...............................................................*/
  2. #include "qp_port.h"
  3. #include "bsp.h"
  4. #include "stm32f10x_lib.h"

  5. #define BSP_TICKS_PER_SEC 100

  6. void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) {
  7. }
  8. void QF_onStartup(void) {
  9.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);/* Select AHB clock(HCLK) as SysTick clock source */
  10.         NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 0, 0);/* Set SysTick Priority to 3 */
  11.         SysTick_SetReload(480000);/* SysTick interrupt each 10ms with HCLK equal to 48MHz */
  12.         SysTick_ITConfig(ENABLE);/* Enable the SysTick Interrupt */
  13.         SysTick_CounterCmd(SysTick_Counter_Enable); //运行起来
  14. }
  15. void QF_onIdle(void) {
  16. #ifdef NDEBUG
  17.         /* put the CPU and peripherals to the low-power mode, see NOTE02 */
  18.         __WFI();
  19. #endif
  20.         QF_INT_ENABLE();                            /* always enable interrupts */
  21. }
  22. void QF_onCleanup(void) {}
  23. void QF_onClockTick(void) {
  24.         QF_TICK((void *)0);
  25. }
  26. /*..........................................................................*/

  27. void SysTickHandler(void) {//把原先在stm32f10x_it.c中的代码注释掉,挪到这里
  28.         //QF_onClockTick();    //SysTick_Configuration周期定义为10ms
  29.         QF_TICK_X(0U, (void *)0);              /* process all armed time events */
  30. }

  31. enum BlinkySignals {
  32.         TIMEOUT_SIG = Q_USER_SIG,
  33.         MAX_SIG
  34. };

  35. /* @(/1/0) .................................................................*/
  36. typedef struct BlinkyTag {
  37.         /* protected: */
  38.         QActive super;

  39.         /* private: */
  40.         QTimeEvt timeEvt;
  41. } Blinky;

  42. /* protected: */
  43. static QState Blinky_initial(Blinky * const me, QEvt const * const e);
  44. static QState Blinky_led_Off(Blinky * const me, QEvt const * const e);
  45. static QState Blinky_led_On(Blinky * const me, QEvt const * const e);

  46. /* @(/1/0) .................................................................*/
  47. /* @(/1/0/1) ...............................................................*/
  48. /* @(/1/0/1/0) */
  49. static QState Blinky_initial(Blinky * const me, QEvt const * const e) {
  50.         QTimeEvt_postEvery(&me->timeEvt, (QActive *)me, BSP_TICKS_PER_SEC/2);
  51.         return Q_TRAN(&Blinky_led_Off);
  52. }
  53. /* @(/1/0/1/1) .............................................................*/
  54. static QState Blinky_led_Off(Blinky * const me, QEvt const * const e) {
  55.         QState status_;
  56.         switch (e->sig) {
  57.                 /* @(/1/0/1/1) */
  58.                 case Q_ENTRY_SIG: {
  59.                         BSP_led_Off();
  60.                         status_ = Q_HANDLED();
  61.                         break;
  62.                                                   }
  63.                                                   /* @(/1/0/1/1/0) */
  64.                 case TIMEOUT_SIG: {
  65.                         status_ = Q_TRAN(&Blinky_led_On);
  66.                         break;
  67.                                                   }
  68.                 default: {
  69.                         status_ = Q_SUPER(&QHsm_top);
  70.                         break;
  71.                                  }
  72.         }
  73.         return status_;
  74. }
  75. /* @(/1/0/1/2) .............................................................*/
  76. static QState Blinky_led_On(Blinky * const me, QEvt const * const e) {
  77.         QState status_;
  78.         switch (e->sig) {
  79.                 /* @(/1/0/1/2) */
  80.                 case Q_ENTRY_SIG: {
  81.                         BSP_led_On();
  82.                         status_ = Q_HANDLED();
  83.                         break;
  84.                                                   }
  85.                                                   /* @(/1/0/1/2/0) */
  86.                 case TIMEOUT_SIG: {
  87.                         status_ = Q_TRAN(&Blinky_led_Off);
  88.                         break;
  89.                                                   }
  90.                 default: {
  91.                         status_ = Q_SUPER(&QHsm_top);
  92.                         break;
  93.                                  }
  94.         }
  95.         return status_;
  96. }


  97. static Blinky l_blinky;
  98. QActive *AO_Blinky = &l_blinky.super;

  99. static void Blinky_ctor(void) {
  100.         Blinky *me = (Blinky *)AO_Blinky;
  101.         QActive_ctor(&me->super, (QStateHandler)&Blinky_initial);
  102.         QTimeEvt_ctor(&me->timeEvt, TIMEOUT_SIG);
  103. }
  104. int main() {
  105.         static QEvt const *blinky_queueSto[10];        /* 这行挪到这里 */
  106.         BSP_init();                                           /* 自己添加这行,定义在bsp.c */
  107.         Blinky_ctor();
  108.         QF_init();

  109.         QActive_start(AO_Blinky, 1,
  110.                 blinky_queueSto, Q_DIM(blinky_queueSto),
  111.                 (void *)0, 1024, (QEvt *)0);
  112.         return QF_run();
  113. }
复制代码

hw_config.h
  1. /* Define to prevent recursive inclusion -------------------------------------*/
  2. #ifndef __HW_CONFIG_H
  3. #define __HW_CONFIG_H

  4. /* Includes ------------------------------------------------------------------*/
  5. #include "stm32f10x_lib.h"
  6. /* Exported types ------------------------------------------------------------*/
  7. /* Exported constants --------------------------------------------------------*/
  8. /* Exported macro ------------------------------------------------------------*/
  9. /* Exported define -----------------------------------------------------------*/
  10. /* Exported functions ------------------------------------------------------- */
  11. void System_Init(void);
  12. /* External variables --------------------------------------------------------*/

  13. #endif  /*__HW_CONFIG_H*/

  14. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码

hw_config.c
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "hw_config.h"
  3. /* Private typedef -----------------------------------------------------------*/
  4. /* Private define ------------------------------------------------------------*/
  5. /* Private macro -------------------------------------------------------------*/
  6. /* Private variables ---------------------------------------------------------*/
  7. /* Extern variables ----------------------------------------------------------*/
  8. /* Private function prototypes -----------------------------------------------*/
  9. void SysTick_Configuration(void);
  10. void RCC_Configuration(void);
  11. void GPIO_Configuration(void);
  12. void NVIC_Configuration(void);

  13. /* Private functions ---------------------------------------------------------*/

  14. /*******************************************************************************
  15. * Function Name  : System_Init
  16. * Description    : Configures Main system clocks & power
  17. * Input          : None.
  18. * Return         : None.
  19. *******************************************************************************/
  20. void System_Init(void)
  21. {
  22.         /* System Clocks Configuration */
  23.         RCC_Configuration();
  24.         /* Configure the GPIO ports */
  25.         GPIO_Configuration();
  26.         /* NVIC configuration */
  27.         NVIC_Configuration();
  28. }

  29. /*******************************************************************************
  30. * Function Name  : RCC_Configuration
  31. * Description    : 配置不同的系统时钟
  32. * Input          : None
  33. * Output         : None
  34. * Return         : None
  35. *******************************************************************************/
  36. void RCC_Configuration(void)
  37. {
  38.         /* RCC system reset(for debug purpose) */
  39.         RCC_DeInit();

  40.         RCC_HSICmd(ENABLE);        //打开内部高速时钟
  41.         //等待HSI准备好
  42.         while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);

  43.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);        //开启FLASH预取指功能
  44.         //FLASH时序控制
  45.         //推荐值:SYSCLK = 0~24MHz   Latency=0
  46.         //       SYSCLK = 24~48MHz  Latency=1
  47.         //       SYSCLK = 48~72MHz  Latency=2
  48.         FLASH_SetLatency(FLASH_Latency_2);
  49.         RCC_HCLKConfig(RCC_SYSCLK_Div1);        //设置HCLK(AHB时钟)=SYSCLK
  50.         RCC_PCLK2Config(RCC_HCLK_Div1);                //PCLK2(APB2) = HCLK
  51.         RCC_PCLK1Config(RCC_HCLK_Div2);                //PCLK1(APB1) = HCLK/2=24M
  52.         RCC_ADCCLKConfig(RCC_PCLK2_Div4);        //ADCCLK = PCLK2/4=12M
  53.         //PLL设置 SYSCLK/2 * 12 = 4*12 = 48MHz
  54.         RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
  55.         //启动PLL
  56.         RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,不能被DISABLE
  57.         //等待PLL稳定
  58.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){;}

  59.         //设置系统时钟SYSCLK = PLL输出
  60.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  61.         //等待PLL成功用作于系统时钟的时钟源,并等待稳定
  62.         // 0x00:HSI作为系统时钟
  63.         // 0x04:HSE作为系统时钟
  64.         // 0x08:PLL作为系统时钟
  65.         while(RCC_GetSYSCLKSource() != 0x08);

  66.         /* Enable GPIOB*/
  67.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  68. }

  69. /*******************************************************************************
  70. * Function Name  : NVIC_Configuration
  71. * Description    : 配置NVIC
  72. * Input          : None
  73. * Output         : None
  74. * Return         : None
  75. *******************************************************************************/
  76. void NVIC_Configuration(void)
  77. {
  78.         NVIC_InitTypeDef NVIC_InitStructure;

  79. #ifdef  VECT_TAB_RAM
  80.         NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);                        // Set the Vector Table base location at 0x20000000
  81. #else  /* VECT_TAB_FLASH  */
  82.         NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);                // Set the Vector Table base location at 0x08000000
  83. #endif
  84.         /* Configure the NVIC Preemption Priority Bits */
  85.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  86. }

  87. /*******************************************************************************
  88. * Function Name  : GPIO_Configuration
  89. * Description    : 配置GPIO口
  90. * Input          : None
  91. * Output         : None
  92. * Return         : None
  93. *******************************************************************************/
  94. void GPIO_Configuration(void)
  95. {
  96.         GPIO_InitTypeDef GPIO_InitStructure;

  97.         /* 配置 PB.15引脚为推挽输出 */
  98.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//指示灯
  99.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  100.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  101.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  102. }

  103. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
复制代码

至于stm32f10x_it.c中断函数文件,将以下注释掉就可以
  1. //void SysTickHandler(void)
  2. //{
  3. //        
  4. //}
复制代码


值得注意的是,导入libqp_Cortex-M3.a(在QPC安装目录下)要设置一下



将LED的IO口稍微修改下,估计在你的板上已经能闪灯了。

/*****************************************************************************************************************************************************/

现在再说blinky上的代码怎么来的,大部分是用QM生成的,小部分是得自己敲的。
QM怎么使用呢?请看官方的教程官方代码是在PC上运行的,所以跟我这有很细微的差异,自己对比下Blinky.c一看就明白。
为了方便看贴,我把官方的例子贴在这,看图就行,英文几乎不用看


This tutorial describes how to use QM™ to model and implement a simple "Blinky" application, which can blink an LED on an ebmedded board or just print the state changes of the LED to the screen when executed on the desktop.
NOTE: Before you start this tutorial, make sure that the QM™ tool is unlocked to allow editing the model. The tool is unlocked when the unlock button () is depressed.
Creating New Model
To create a new model, go to File->New Model... menu or press the New Model button in the Edit toolbar. This will open the following "New Model" dialog box:

  • Select the QP™ framework type you want to base the new model on (the "Frameworks" panel). The choices are: qpc for QP/C™, qpcpp for QP/C++™, and qpn for QP-nano™. For this tutorial, you leave the default qpc framework type.
  • Choose the model template for your model ("Templates" panel). If you don't select the template and leave at "None", your model will be empty, except the selected framework. For this tutorial, you leave the default template None, so that you can start building your model from scratch.
  • Name your model ("Name:"). NOTE: the .qm extension will be added automatically. For this tutorial, you rename the model to blinky.
  • Choose the directory for your model file ("Location:"). You can either type in the path manually, or you can press the button to open the directory-search dialog box.
    For this tutorial, you choose the model location to <any-directory>\blinky.
    NOTE: the model directory provides also the reference point for the code generation. All generated directories and files are relative to the model file directory.
  • Press the OK button.










top
Adding Model Items
Now you can to start adding items to the new model. The first item you add is a Package. A package in UML is a grouping construct that allows you to combine any other items into a higher-level unit—the package. The most common use of a package is to group together classes, but a packgae can hold also free attributes, free operations, and even other packages.
In the Explorer view right-click on the blinky model item to get a popup-menu specific to that item. Once the popup menu opens, select Add Package.

In the Property Editor change the package name to AOs (Active Objects) and the stereotype to components.

Next you need to add a class to the new package, because only classes can have behavior (i.e., state machines).
In the Explorer view right-click on the AOs package and select Add Class from the popup menu.

In the Property Editor change the class name to Bliky and the superclass to qpc::QActive.

NOTE: QM™ allows only direct or indirect subclasses of QP base classes QHsm or QFsm to have a state machine (statechart). The class QActive is a subclass of QHsm, so all its subclasses, such as Blinky in this case, also inherit the statechart. The Model Explorer uses a special icon with a dot ( or ) for classes that can have a statechart.
In the Explorer view right-click on the Blinky class and select Add Attribute from the popup menu.

In the Property Editor change the attribute name to timeEvt, the type to QTimeEvt, and visibility to private.

In the Explorer view right-click on the Blinky class and select Add Statechart from the popup menu.

top
Drawing a Statechart
In the Explorer view right-click on the Statechart item and select Show Diagram from the popup menu. Alternatively you can just double-click on the Statechart item to execute its default action, which is to show the diagram.

In the Toolbox click on the state tool. Move your mouse (all mouse buttons released) to the diagram window where you want to position the upper-left corner of the state shape. Notice the new shape of the mouse cursor (shown on the right). Click the mouse and drag it (with mouse button depressed) to the location of the lower-rigth corner of the state shape. Release the mouse.Click on the picture below to watch a demo.

In the Property Editor change the state name to off and add the entry action to this state BSP_ledOff();.

In the similar way as before add second state. In the Property Editor change the state name to on and add the entry action to this state BSP_ledOn();.

In the Toolbox click on the initial transition tool. Move your mouse (all mouse buttons released) to the diagram window where you want to position the begin of the initial transition shape. Notice the new shape of the mouse cursor (shown on the right). Click the mouse and drag it (with mouse button depressed) to the edge of the state. Notice the cursor change when you reach the edge. Release the mouse. Click on the picture below to watch a demo.

In the Property Editor add action code to this initial transition QTimeEvt_postEvery(&me->timeEvt, (QActive *)me, BSP_TICKS_PER_SEC/2);.

NOTE: The action code of the initial transition arms a periodic time event me->timeEvt to trigger the blinking of the LED. You still need to add the timeEvt attribute to the Blinky class.
In the Toolbox click on the transition tool. Move your mouse (all mouse buttons released) to the state edge where you want to position the begin of the transition connector. Notice the new shape of the mouse cursor (shown on the right). Click the mouse and drag it (with mouse button depressed) to the edge of the state. Notice the cursor change when you reach the edge. Release the mouse. Click on the picture below to watch a demo.

In the Property Editor change the trigger of this transition to TIMEOUT.

In the similar way as before add second transiton and change its trigger also to TIMEOUT.

top
Generating Code
Compared to most other graphical tools based on state machines, QM™ turns the code generation upside down. QM™ lets you determine the generated code structure, directory names, file names, and elements that go into every file. You can mix your own code with the generated code and use QM to generate as much or as little of the overall code as you see fit.
In a real-life project you would typically split the code into some header (.h) files, place each active object in its own source (.c) file, and use separate .c files for the Board Support Package (BSP) and main(). But for the sake of simplicity, this tutorial will put the whole implementation in just one file: blinky.c, which you create as follows.
In the Explorer view right-click on the blinky model item and select Add Directory in the popup menu. The name of the directory can be edited right in the Explorer window (as well as in the Property Editor). Type . (dot) for the name of the directory. The dot means the same directory as the model.
In the Explorer view right-click on the . directory item and select Add File in the popup menu. After the file is created, you can edit its name right in the Explorer (as well as in the Property Editor). Type blinky.c and press Enter. Note that the file icon changes to .

In the Explorer view double-click on the blinky.c file to open the file in a widnow. Next copy the following code into the file window (notice the highlighted code-generating directives $declare() and $define().
  1. #include "qp_port.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. #define BSP_TICKS_PER_SEC 100

  5. void BSP_ledOff(void) {
  6.     printf("LED OFF\n");
  7. }
  8. void BSP_ledOn(void) {
  9.     printf("LED ON\n");
  10. }
  11. void Q_onAssert(char const Q_ROM * const Q_ROM_VAR file, int line) {
  12.     fprintf(stderr, "Assertion failed in %s, line %d", file, line);
  13.     exit(0);
  14. }
  15. void QF_onStartup(void) {}
  16. void QF_onCleanup(void) {}
  17. void QF_onClockTick(void) {
  18.     QF_TICK((void *)0);
  19. }

  20. enum BlinkySignals {
  21.     TIMEOUT_SIG = Q_USER_SIG,
  22.     MAX_SIG
  23. };

  24. $declare(AOs::Blinky)
  25. $define(AOs::Blinky)

  26. static Blinky l_blinky;
  27. QActive *AO_Blinky = &l_blinky.super;

  28. static void Blinky_ctor(void) {
  29.     Blinky *me = (Blinky *)AO_Blinky;
  30.     QActive_ctor(&me->super, (QStateHandler)&Blinky_initial);
  31.     QTimeEvt_ctor(&me->timeEvt, TIMEOUT_SIG);
  32. }
  33. int main() {
  34.     Blinky_ctor();
  35.     QF_init();

  36.     static QEvt const *blinky_queueSto[10];
  37.     QActive_start(AO_Blinky, 1,
  38.                   blinky_queueSto, Q_DIM(blinky_queueSto),
  39.                   (void *)0, 1024, (QEvt *)0);
  40.     return QF_run();
复制代码

In QM™ you provide the body of every file and then you instruct QM™ to synthesize code for selected model items by means of code-generation directives. The listing above shows two most important such directives: $declare() for generating the declaration of the selected item, and $define() for generating the definition of the selected item. Please refer to the section Code Engineering for more information about code generation in QM™
Generate code by pressing the Generate Code button in the Tools toolbar.

At this point QM™ has generated the blinky.c file in the same directory as the blinky.qm model file. You can instpect the generated blinky.c file on the disk with your favorite code editor.
top
Building the Project
You build the generated code just as any other hand-crafted code. This simplistic tutorial generated the whole project in just one soruce file blinky.c.
Building Blinky on Windows/LinuxThe Board Support Package (BSP) functions coded at the beginning if the blinky.c file are designed to run on the desktop OS, such as Windows or Linux, because of the printf() instructions. Here is how to build the blinky.exe executable on Windows using the MinGW compiler:
gcc blinky.c -oblinky.exe -I%QPC%\include -I%QPC%\ports\win32\mingw -L%QPC%\ports\win32\mingw\dbg -lqp
And here is how to build the blinky executable on Linux using the standard GNU compiler:
gcc blinky.c -oblinky -I$QPC/include -I$QPC/ports/posix/gnu -L$QPC/ports/posix/gnu/dbg -lqp -lpthread
NOTE: this command assumes that you have installed QP/C on your machine and that you have defined the environment variable QPC to pont to the installation directory of QP/C.
After you execute the build command, you can run the blinky.exe from the console, as shown in the following screen shot. You exit the application by pressing Ctrl+C.


Building Blinky for an Embedded Board
To build the Blinky project for an embedded board, you need to modify the BSP (Board Support Package), to turn the LED on and off. You also need to use the specific cross-compiler. Please refer to the specific QP Development Kits (QDKs) for more information about building QP projects for specific embedded boards.

/*****************************************************************************************************************************************************/

这个例子很简单,事件也是QP自带的TIMEOUT事件,看到这里,可能有人也奇怪,要是我自己定义的事件呢?
比如按键按下,怎么产生一个事件?
建立个blinky.h头文件,方便其它文件调用。
  1. #ifndef blinky_h
  2. #define blinky_h
  3. #include "qp_port.h"                                    /* bsp_h *

  4. typedef struct KeyEvtTag { //定义一个按键事件结构,照葫芦画瓢就
  5.         QEvt super;                                    /* derives from QEvt *
  6.         uint8_t key_code;                               /* code of the key *
  7. } KeyEvt;

  8. /*...............................................................................................................*
  9. enum BlinkySignals
  10.         TIMEOUT_SIG = Q_USER_SIG
  11.         KEY_SIG,          //将原先blinky.c里面的枚举定义放到头文件中,增加了按键事件KEY_SIG
  12.         MAX_SI
  13. }
  14. #endif
复制代码

那么按键动作怎么对应一个事件呢?在你要产生事件的地方,加入以下代码,在blinky.c里面的switch里加入对KEY_SIG事件处理。
  1.                 if (Key_Read() == XXXXX) //按键读取函数根据电路实际情况编写
  2.                 {
  3.                         KeyEvt e; //KeyEvt定义看上面,e是一个按键事件
  4.                         ((QEvt*)&e)->sig = KEY_SIG; //这就将按键动作跟KEY_SIG事件对应起来了
  5.                         QMSM_DISPATCH(the_blinky, (QEvt *)&e); //将事件发送出去
  6.                 }
复制代码

the_blink在blinky.c定义
  1. QHsm * const the_blinky = (QHsm*)&l_blinky;
复制代码
照葫芦画瓢,先运行起来,再慢慢看代码。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)

出0入0汤圆

发表于 2014-2-5 11:02:11 来自手机 | 显示全部楼层
看见就顶…

出0入0汤圆

发表于 2014-2-5 16:11:02 | 显示全部楼层

出0入0汤圆

发表于 2014-2-5 16:47:02 | 显示全部楼层
LZ辛苦,新年第一顶!

出0入0汤圆

发表于 2014-2-6 14:56:44 来自手机 | 显示全部楼层
跟着学                                

出0入0汤圆

发表于 2014-2-6 21:13:27 | 显示全部楼层
跟着LZ学习。

出0入0汤圆

发表于 2014-3-13 15:21:20 | 显示全部楼层
本帖最后由 leavic 于 2014-3-13 15:23 编辑

楼主用的lib很老了吧,system init这块在新的库里面已经在startup汇编的最后自动调用了.
我就把官方自带的GNU编译器的TI CM4的例子改了一下BSP就可以跑了.

QP这玩意本身其实代码量不大,可是文件多的要死,硬是被做成了一个几十K的lib,这对SE/SI用户来说,不方便查看函数原型了(其实习惯了应该也不需要,可是刚开始就觉得有点不习惯).

出130入129汤圆

 楼主| 发表于 2014-3-13 19:43:39 | 显示全部楼层
leavic 发表于 2014-3-13 15:21
楼主用的lib很老了吧,system init这块在新的库里面已经在startup汇编的最后自动调用了.
我就把官方自带的GN ...

习惯了用ST 2.03的库,不喜欢3.5那种风格,感觉没那么透明了

出0入0汤圆

发表于 2014-3-13 19:59:57 | 显示全部楼层
本帖最后由 rmdyj 于 2014-3-13 20:01 编辑

QP,其实就是编程的一种方法论,不知对不对?

出130入129汤圆

 楼主| 发表于 2014-3-13 20:03:40 | 显示全部楼层
rmdyj 发表于 2014-3-13 19:59
QP,其实就是编程的一种方法论,不知对不对?

可以这么理解吧

现在中文版也出来了,网上可以下载了,再不用看英文版那么辛苦

出0入0汤圆

发表于 2014-3-21 10:38:50 | 显示全部楼层
不错 顶贴学习

出0入0汤圆

发表于 2014-3-25 15:17:44 | 显示全部楼层
dashen``````mark
zhi ````

出0入0汤圆

发表于 2014-3-25 16:19:16 | 显示全部楼层
68336016 发表于 2014-3-13 20:03
可以这么理解吧

现在中文版也出来了,网上可以下载了,再不用看英文版那么辛苦 ...

记得以前 农民讲习所 发的一篇 通用处理程序,很相似。

出0入0汤圆

发表于 2014-4-29 14:56:00 | 显示全部楼层
看着有点晕,但是还是不知道是干啥用的

出0入0汤圆

发表于 2014-6-13 00:22:08 | 显示全部楼层
顶啊  顶啊, 终于有教程啦; 让我等菜鸟跟着学

出130入129汤圆

 楼主| 发表于 2014-6-13 00:25:51 | 显示全部楼层
Free_Bird 发表于 2014-6-13 00:22
顶啊  顶啊, 终于有教程啦; 让我等菜鸟跟着学

现在有中文版的PDF,你可以论坛上搜索一下,我淘宝找人打印了一本30来块钱。
书大概翻了一遍,稍微了解了QP,不过没地方使用。

出0入0汤圆

发表于 2014-6-13 09:02:01 | 显示全部楼层
68336016 发表于 2014-6-13 00:25
现在有中文版的PDF,你可以论坛上搜索一下,我淘宝找人打印了一本30来块钱。
书大概翻了一遍,稍微了解了 ...

中文版是全本翻译的 还是只有部分章节
英文实在是看不懂

出130入129汤圆

 楼主| 发表于 2014-6-13 09:04:01 | 显示全部楼层
gamep 发表于 2014-6-13 09:02
中文版是全本翻译的 还是只有部分章节
英文实在是看不懂

全本的,翻译得还可以,不过一些插图的图号没有,但是不影响阅读。

出0入0汤圆

发表于 2014-6-13 10:28:55 | 显示全部楼层
68336016 发表于 2014-6-13 00:25
现在有中文版的PDF,你可以论坛上搜索一下,我淘宝找人打印了一本30来块钱。
书大概翻了一遍,稍微了解了 ...

恩,那本中文的我已经下了,自己打印了前7章,正在看; 不过水平太菜,看的很吃力;
正在研究第3章;还有就是没有地方用,总感觉学的不扎实似的;云里雾里的;

出0入0汤圆

发表于 2014-6-13 10:51:26 | 显示全部楼层
来学习一下哈。。。

出0入0汤圆

发表于 2014-6-14 08:53:54 | 显示全部楼层
Free_Bird 发表于 2014-6-13 10:28
恩,那本中文的我已经下了,自己打印了前7章,正在看; 不过水平太菜,看的很吃力;
正在研究第3章;还 ...

传上来共享一下吧

出0入0汤圆

发表于 2014-6-14 10:25:41 | 显示全部楼层
正想学习一下呢

出0入0汤圆

发表于 2014-6-14 19:57:00 | 显示全部楼层
gamep 发表于 2014-6-14 08:53
传上来共享一下吧


有坛友上传过的;
我再传一次,感觉书很好,就是看不懂啊。。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-6-25 00:20:12 | 显示全部楼层
问一下楼主,QPC是哪个软件啊?我在官网上找了半天也没有,就一个最新的QM3.1.3

QPC能传上来共享下么? 谢谢

出130入129汤圆

 楼主| 发表于 2014-6-25 00:28:04 | 显示全部楼层
Free_Bird 发表于 2014-6-25 00:20
问一下楼主,QPC是哪个软件啊?我在官网上找了半天也没有,就一个最新的QM3.1.3

QPC能传上来共享下么? 谢 ...

http://sourceforge.net/projects/qpc/files/

出0入0汤圆

发表于 2014-6-30 22:36:18 | 显示全部楼层
68336016 发表于 2014-6-25 00:28
http://sourceforge.net/projects/qpc/files/

不是说自动生成代码么?怎么还是COPY进去的呀?这点我想不明白

出0入0汤圆

发表于 2014-7-6 22:19:41 | 显示全部楼层
请教,关于官方文档 Getting Started with QP_nano 中的环境变量设置问题;
文档中的图表如下:
Environment variable                Example setting (adjust to your system)
QPN                                       C:\qp\qpn
QTOOLS                                 C:\tools\qtools
PATH                                     …;%QTOOLS%\bin (append to the PATH)

我想问的是,假如我的QTOOLS安装在  D:\tools 下; 那么我的PATH应该如何设置?

D:\tools\qtools\bin      ??

出0入0汤圆

发表于 2014-7-27 21:55:32 | 显示全部楼层
avr32_new 发表于 2014-6-30 22:36
不是说自动生成代码么?怎么还是COPY进去的呀?这点我想不明白

有一部分是自己写的;状态图里涉及到的状态转移和相应的功能函数调用是生成代码后实现的; 你用的是生成后的文件;

关键就是需要自己写的这些都是什么,按什么流程写,官方文档里有说明么?我应该看哪个官方文档?

希望过来人给指点下

出0入0汤圆

发表于 2014-8-14 16:36:25 | 显示全部楼层
mark,感谢分享,最近在使用stm32f103c8t6

出0入0汤圆

发表于 2014-8-27 21:37:44 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2014-8-30 11:11:51 | 显示全部楼层
这个工具没有32位的么,都是64位的啊。

出0入0汤圆

发表于 2014-10-24 19:24:37 | 显示全部楼层
                                                                                                                                                                                      .

出0入0汤圆

发表于 2014-10-28 18:26:49 | 显示全部楼层
好东西,多谢楼主分享,不过为什么好多图片显示不出来呢。

出0入0汤圆

发表于 2014-10-29 09:20:57 | 显示全部楼层
好东西,收藏了,慢慢学习

出0入0汤圆

发表于 2014-10-29 09:45:24 | 显示全部楼层
好东西,有机会研究看看

出0入0汤圆

发表于 2014-10-29 16:42:47 | 显示全部楼层
状态机趋势 C++趋势

出0入0汤圆

发表于 2014-10-29 19:33:16 | 显示全部楼层
MARK                          

出0入0汤圆

发表于 2014-11-11 17:04:55 | 显示全部楼层

出0入0汤圆

发表于 2014-12-14 22:42:58 | 显示全部楼层
标记一下学习状态机有又一好方式,就是文件有些散乱,看的有点晕

出0入0汤圆

发表于 2014-12-14 22:45:52 来自手机 | 显示全部楼层
qp有时间了解一下了

出0入0汤圆

发表于 2015-1-28 10:27:40 | 显示全部楼层
QM软件官网无法下载

出0入0汤圆

发表于 2015-1-31 18:12:16 | 显示全部楼层
看得就很喜欢 消化还要一定时间

出0入0汤圆

发表于 2015-2-5 16:02:35 | 显示全部楼层
觉得不错,以后学习,谢谢分享

出0入0汤圆

发表于 2015-3-4 18:15:00 | 显示全部楼层
mcu_mouse 发表于 2014-8-30 11:11
这个工具没有32位的么,都是64位的啊。

找老点的版本就有32位的,比如QM3.1.3

出0入0汤圆

发表于 2015-3-22 20:09:03 | 显示全部楼层
那本书一直没看的太懂,LZ强大  果断的顶起

出0入0汤圆

发表于 2015-5-11 16:24:23 | 显示全部楼层
落后楼主一年呐,楼主,我下载了官网的QM,按照教程画了一个简单的例子,但不能生成,提示需要license,好多工具栏也变灰的。是需要购买license吗?

出0入0汤圆

发表于 2015-5-16 10:41:50 | 显示全部楼层
觉得不错,以后学习,谢谢分享

出0入0汤圆

发表于 2015-10-13 14:48:50 | 显示全部楼层
正在学习

出0入0汤圆

发表于 2015-10-21 16:36:28 | 显示全部楼层
请问下楼主QPC,按键程序该怎么写,有以下几种方法:
1: 程序在需要按键时直接读IO口;
2:创建一个状态,每隔20ms,扫描IO,有按键,把所有按键当作消息发给其他注册的状态;(消息让自己判断)
3:创建一个状态,每隔20ms,扫描IO,有按键,让其他程序订阅这个按键消息,这个按键消息只发送给这个订阅者;(判断好后,发送给订阅者)

出0入0汤圆

发表于 2016-6-10 21:44:46 | 显示全部楼层
开始学习QP。

出0入0汤圆

发表于 2016-7-2 15:18:50 | 显示全部楼层
感谢大神分享  相当给力

出0入4汤圆

发表于 2016-7-6 17:23:53 | 显示全部楼层
找了好久了,这样的好教程,感谢楼主分享!!!

出0入0汤圆

发表于 2016-7-13 16:42:06 | 显示全部楼层
多谢楼主分享,下载看了~!

出0入0汤圆

发表于 2016-8-16 15:35:18 | 显示全部楼层

后面我搞了个群,欢迎大家加一下:129063491

出140入8汤圆

发表于 2016-10-18 07:08:08 | 显示全部楼层
好东西啊,学习一下

出0入0汤圆

发表于 2018-9-6 11:37:33 | 显示全部楼层
小荷才露尖尖角,早有蜻蜓立上头~为你点赞,我开始学习

出0入0汤圆

发表于 2020-5-26 21:22:18 | 显示全部楼层
正在学这个东西,中文资料翻译的不好,硬啃英文资料,看了看楼主的帖子,又有收获。玩这个的太少了,很难找到学习资料。

出0入0汤圆

发表于 2020-5-26 21:52:00 | 显示全部楼层
好东西,很难找到学习资料。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-16 14:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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