在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32G0開發筆記:FreeRTOS和FreeModbus庫使用

CHANBAEK ? 來源:電子技術攻城獅 ? 作者:MakerInChina.cn ? 2023-01-16 14:44 ? 次閱讀

使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為FreeRTOS和FreeModbus庫使用。

1 新建項目

  • 建立freertos_modbus項目

PIO的Home頁面新建項目,項目名稱freertos_modbus,選擇開發板為 MonkeyPi_STM32_G070RB,開發框架選擇libopencm3;

  • 項目建立完成后在src目錄下新建main.c主程序文件;
  • 修改下載和調試方式,這里開發板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:
1upload_protocol = cmsis-dap
2debug_tool = cmsis-dap

2 編寫程序

直接在之前的FreeRTOS工程上進行添加;

2.1 添加 freeModbus 庫

從git倉庫下載源碼: https://github.com/cwalter-at/freemodbus

將下載的源碼中的mobus文件夾放置到工程的lib目錄下,然后在modbus目錄新建library.json文件,內容如下:

1{
 2    "name": "FreeModbus",
 3    "version": "master",
 4    "repository":{
 5        "type":"git",
 6        "url":"https://github.com/cwalter-at/freemodbus"
 7    },
 8    "build": {
 9        "flags": [
10            "-Iascii",
11            "-Ifunctions",
12            "-Iinclude",
13            "-Irtu",
14            "-Itcp"
15        ],
16        "srcFilter": [
17            "+<*>"
18        ]
19    }
20}

然后從FreeModbus源碼中的 demo\\BARE\\port中復制文件到工程的src\\modbus_port文件夾下,最后的文件夾結構如下:

image-20220928231915800

2.2 移植
  • portevent:
1/* ----------------------- Modbus includes ----------------------------------*/
 2#include "mb.h"
 3#include "mbport.h"
 4#include "FreeRTOS.h"
 5#include "task.h"
 6
 7/* ----------------------- Variables ----------------------------------------*/
 8static eMBEventType eQueuedEvent;
 9static BOOL     xEventInQueue;
10static uint32_t modbus_last_active_time = 0;
11
12uint32_t get_modbus_last_active_time(void)
13{
14    return modbus_last_active_time;
15}
16
17/* ----------------------- Start implementation -----------------------------*/
18BOOL
19xMBPortEventInit( void )
20{
21    xEventInQueue = FALSE;
22    return TRUE;
23}
24
25BOOL
26xMBPortEventPost( eMBEventType eEvent )
27{
28    xEventInQueue = TRUE;
29    eQueuedEvent = eEvent;
30
31    if (eEvent == EV_EXECUTE) {
32        modbus_last_active_time = xTaskGetTickCount();
33    }
34    return TRUE;
35}
36
37BOOL
38xMBPortEventGet( eMBEventType * eEvent )
39{
40    BOOL            xEventHappened = FALSE;
41
42    if( xEventInQueue )
43    {
44        *eEvent = eQueuedEvent;
45        xEventInQueue = FALSE;
46        xEventHappened = TRUE;
47    }
48    return xEventHappened;
49}
  • portserial

這里使用RS485,因此需要對RS485使能端口進行配置,其他為串口的配置,然后在發送和接收中斷時候調用modbus相關接口進行處理:

1#include "port.h"
  2
  3#include "FreeRTOS.h"
  4#include "queue.h"
  5
  6#include 3/cm3/nvic.h>
  7#include 3/stm32/usart.h>
  8#include 3/stm32/rcc.h>
  9#include 3/stm32/gpio.h>
 10
 11/* ----------------------- Modbus includes ----------------------------------*/
 12#include "mb.h"
 13#include "mbport.h"
 14
 15/* ----------------------- static functions ---------------------------------*/
 16
 17xQueueHandle uart_queue;
 18
 19#define RS485_1_CLOCK        RCC_GPIOB
 20#define RS485_1_EN_PORT        GPIOB
 21#define RS485_1_EN_PIN        GPIO8
 22
 23static void rs485_delay(int n)
 24{
 25    while (--n) {
 26        __asm__ volatile ("nop");
 27    }
 28}
 29
 30static inline void rs485_1_rx_mode(void)
 31{
 32    gpio_clear(RS485_1_EN_PORT, RS485_1_EN_PIN);
 33}
 34
 35static inline void rs485_1_tx_mode(void)
 36{
 37    gpio_set(RS485_1_EN_PORT, RS485_1_EN_PIN);
 38}
 39
 40static inline void rs485_gpio_init(void)
 41{
 42    rcc_periph_clock_enable(RS485_1_CLOCK);
 43    gpio_mode_setup(RS485_1_EN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_1_EN_PIN);
 44
 45    rs485_1_rx_mode();
 46}
 47
 48/* ----------------------- Start implementation -----------------------------*/
 49void
 50vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
 51{
 52    /* If xRXEnable enable serial receive interrupts. If xTxENable enable
 53     * transmitter empty interrupts.
 54     */
 55    if (xRxEnable) {
 56        rs485_delay(10000);
 57        rs485_1_rx_mode();
 58        rs485_delay(10000);
 59        usart_enable_rx_interrupt(USART1);
 60    }
 61    else {
 62        usart_disable_rx_interrupt(USART1);
 63    }
 64
 65    if (xTxEnable) {
 66        rs485_delay(10000);
 67        rs485_1_tx_mode();
 68        rs485_delay(10000);
 69        usart_enable_tx_interrupt(USART1);
 70    }
 71    else {
 72        usart_disable_tx_interrupt(USART1);
 73
 74    }
 75}
 76
 77BOOL
 78xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
 79{
 80    nvic_enable_irq(NVIC_USART1_IRQ);
 81
 82    rcc_periph_clock_enable(RCC_GPIOB);
 83    gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7);
 84    gpio_set_af(GPIOB, GPIO_AF0, GPIO6 | GPIO7);
 85
 86    rcc_periph_clock_enable(RCC_USART1);
 87
 88    /* Set up USART/UART parameters using the libopencm3 helper functions */
 89    usart_set_baudrate(USART1, ulBaudRate);
 90    usart_set_databits(USART1, ucDataBits);
 91    usart_set_stopbits(USART1, USART_STOPBITS_1);
 92    usart_set_mode(USART1, USART_MODE_TX_RX);
 93
 94    switch (eParity) {
 95        case MB_PAR_ODD:
 96            usart_set_parity(USART1, USART_PARITY_ODD);
 97            break;
 98        case MB_PAR_EVEN:
 99            usart_set_parity(USART1, USART_PARITY_EVEN);
100            break;
101        default:
102            usart_set_parity(USART1, USART_PARITY_NONE);
103            break;
104    }
105
106    usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
107
108    usart_enable(USART1);
109
110    rs485_gpio_init();
111
112    return TRUE;
113}
114
115BOOL
116xMBPortSerialPutByte( CHAR ucByte )
117{
118
119    usart_send_blocking(USART1, (uint16_t) ucByte);    
120
121    return TRUE;
122}
123
124BOOL
125xMBPortSerialGetByte( CHAR * pucByte )
126{
127    *pucByte = usart_recv(USART1);
128
129    return TRUE;
130}
131
132
133uint32_t uart1_isr, uart1_icr;
134
135void usart1_isr(void)
136{
137
138    /* Check if we were called because of RXNE. */
139    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
140        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {
141
142        /* Retrieve the data from the peripheral. */
143        // usart_recv(USART1);
144
145        pxMBFrameCBByteReceived();
146
147    }
148
149
150    /* Check if we were called because of TXE. */
151    if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
152        ((USART_ISR(USART1) & USART_ISR_TXE) != 0)) {
153
154        /* Put data into the transmit register. */
155        //usart_send(USART1, data);
156
157        pxMBFrameCBTransmitterEmpty();
158
159    }
160
161}
  • porttimer
1#include "port.h"
 2
 3#include 
 4#include 
 5#include 
 6
 7/* ----------------------- Modbus includes ----------------------------------*/
 8#include "mb.h"
 9#include "mbport.h"
10
11/* ----------------------- static functions ---------------------------------*/
12static void prvvTIMERExpiredISR( void );
13
14/* ----------------------- Start implementation -----------------------------*/
15BOOL
16xMBPortTimersInit( USHORT usTim1Timerout50us )
17{
18    rcc_periph_clock_enable(RCC_TIM2);
19    nvic_enable_irq(NVIC_TIM2_IRQ);
20    rcc_periph_reset_pulse(RST_TIM2);
21
22    timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
23
24    timer_set_prescaler(TIM2, (rcc_apb1_frequency/ 20000));
25
26    timer_disable_preload(TIM2);
27    timer_continuous_mode(TIM2);
28
29    timer_set_period(TIM2, usTim1Timerout50us);
30    timer_enable_counter(TIM2);
31
32    timer_enable_irq(TIM2, TIM_DIER_UIE);
33
34    return TRUE;
35}
36
37
38inline void
39vMBPortTimersEnable(  )
40{
41    timer_set_counter(TIM2, 0);
42    timer_enable_counter(TIM2);
43}
44
45inline void
46vMBPortTimersDisable(  )
47{
48    timer_disable_counter(TIM2);
49}
50
51/* Create an ISR which is called whenever the timer has expired. This function
52 * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
53 * the timer has expired.
54 */
55static void prvvTIMERExpiredISR( void )
56{
57    ( void )pxMBPortCBTimerExpired(  );
58}
59
60void
61vMBPortTimersDelay( USHORT usTimeOutMS )
62{
63    vTaskDelay(pdMS_TO_TICKS(usTimeOutMS));
64}
65
66void tim2_isr(void)
67{
68    if (timer_get_flag(TIM2, TIM_SR_UIF)) {
69
70        /* Clear compare interrupt flag. */
71        timer_clear_flag(TIM2, TIM_SR_UIF);
72
73        prvvTIMERExpiredISR();
74
75    }
76}

開啟定時器和中斷,用于modbus時序控制;

2.3 使用

在src目錄新建 modbus_cb.h 和 modbus_cb.c 兩個文件,實現寄存器、線圈的讀寫回調:

1/// CMD4
 2eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs );
 3
 4/// CMD6、3、16
 5eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode );
 6
 7/// CMD1、5、15
 8eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode );
 9
10/// CMD4
11eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete );

基本的實現示例如下:

1#include "modbus_cb.h"
  2#include "stdbool.h"
  3
  4extern log(const char* fmt, ...);
  5
  6// 輸入寄存器
  7#define REG_INPUT_SIZE  32
  8uint16_t REG_INPUT_BUF[REG_INPUT_SIZE];
  9
 10// 保持寄存器
 11#define REG_HOLD_SIZE   32
 12uint16_t REG_HOLD_BUF[REG_HOLD_SIZE];
 13
 14// 線圈寄存器
 15#define REG_COILS_SIZE 16
 16uint8_t REG_COILS_BUF[REG_COILS_SIZE];
 17
 18// 離散量
 19#define REG_DISC_SIZE  8
 20uint8_t REG_DISC_BUF[REG_DISC_SIZE];
 21
 22/// CMD4
 23eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
 24{
 25    USHORT usRegIndex = usAddress - 1; 
 26
 27    // 非法檢測
 28    if((usRegIndex + usNRegs) > REG_INPUT_SIZE)
 29    {
 30        return MB_ENOREG;
 31    }
 32
 33    log(" CMD4, 寄存器輸入.");
 34
 35    // 填充數據
 36    REG_INPUT_BUF[0] = 0x01;
 37    REG_INPUT_BUF[1] = 0x02;
 38
 39    // 循環讀取
 40    while ( usNRegs > 0 ) {
 41        *pucRegBuffer++ = ( unsigned char )( REG_INPUT_BUF[usRegIndex] >> 8 );
 42        *pucRegBuffer++ = ( unsigned char )( REG_INPUT_BUF[usRegIndex] & 0xFF );
 43        usRegIndex++;
 44        usNRegs--;
 45    }
 46
 47    return MB_ENOERR;
 48}
 49
 50/// CMD6、3、16
 51eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
 52{
 53    USHORT usRegIndex = usAddress - 1;  
 54
 55    // 非法檢測
 56    if((usRegIndex + usNRegs) > REG_HOLD_SIZE) {
 57        return MB_ENOREG;
 58    }
 59
 60    log(" CMD3,6,16, 保持寄存器讀寫.");
 61
 62    // 寫寄存器
 63    if (eMode == MB_REG_WRITE) {
 64        while ( usNRegs > 0 ) {
 65            uint16_t value;
 66
 67            value = (pucRegBuffer[0] << 8) | pucRegBuffer[1];
 68
 69            log("  寫寄存器值:%d", value);
 70
 71            pucRegBuffer += 2;
 72            usRegIndex++;
 73            usNRegs--;
 74
 75        }
 76
 77    }
 78    // 讀寄存器
 79    else {
 80
 81        log("  讀寄存器.");
 82
 83        REG_HOLD_BUF[0] = 0x32;
 84        REG_HOLD_BUF[1] = 0x33;
 85
 86        while ( usNRegs > 0 ) {
 87            *pucRegBuffer++ = ( unsigned char )( REG_HOLD_BUF[usRegIndex] >> 8 );
 88            *pucRegBuffer++ = ( unsigned char )( REG_HOLD_BUF[usRegIndex] & 0xFF );
 89            usRegIndex++;
 90            usNRegs--;
 91        }
 92    }
 93
 94    return MB_ENOERR;
 95}
 96
 97/// CMD1、5、15
 98eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
 99{
100
101    USHORT usRegIndex   = usAddress - 1;
102    USHORT usCoilGroups = ((usNCoils - 1) / 8 + 1);
103    UCHAR  ucStatus     = 0;
104    UCHAR  ucBits       = 0;
105    UCHAR  ucDisp       = 0;
106
107    // 非法檢測
108    if ((usRegIndex + usNCoils) > REG_COILS_SIZE) {
109        return MB_ENOREG;
110    }
111
112    log("  CMD1,5,15, 線圈讀寫.");
113
114    // 寫線圈
115    if (eMode == MB_REG_WRITE) {
116
117        while (usCoilGroups--) {
118
119            ucStatus = *pucRegBuffer++;
120            ucBits   = 8;
121
122            while((usNCoils) != 0 && (ucBits) != 0) {
123                bool flag = ucStatus & 0x01;
124
125                switch (usRegIndex) {
126
127                    case 0:
128                        log(" 線圈0 : %d", flag);//
129                    break;
130
131                    case 1:
132                        log(" 線圈1 : %d", flag);
133                    break;
134
135                    default:
136
137                    break;
138
139                }
140
141                usRegIndex++;
142                ucStatus >>= 1;
143                usNCoils--;
144                ucBits--;
145            }
146
147        }
148    }
149    // 讀線圈
150    else {
151
152        REG_COILS_BUF[0]  = 1;
153        REG_COILS_BUF[1]  = 0;
154
155        while (usCoilGroups--) {
156            ucDisp = 0;
157            ucBits = 8;
158            ucStatus = 0;
159
160            while((usNCoils) != 0 && (ucBits) != 0) {
161                ucStatus |= (REG_COILS_BUF[usRegIndex++] << (ucDisp++));
162                usNCoils--;
163                ucBits--;
164            }
165
166            *pucRegBuffer++ = ucStatus;
167        }
168    }
169
170    return MB_ENOERR;
171}
172
173/// CMD4
174eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
175{
176    USHORT usRegIndex   = usAddress - 1;
177    USHORT usCoilGroups = ((usNDiscrete - 1) / 8 + 1);
178    UCHAR  ucStatus     = 0;
179    UCHAR  ucBits       = 0;
180    UCHAR  ucDisp       = 0;
181
182    // 非法檢測
183    if ((usRegIndex + usNDiscrete) > REG_DISC_SIZE) {
184        return MB_ENOREG;
185    }
186
187    log("  CMD4, 離散寄存器寫入.");
188
189    // 讀離散輸入
190    while (usCoilGroups--) {
191        ucDisp = 0;
192        ucBits = 8;
193        ucStatus = 0;
194
195        while((usNDiscrete != 0) && (ucBits != 0))
196        {
197            switch (usRegIndex) {
198            case 0:
199                ucStatus = 0x10;
200                break;
201            }
202
203            usRegIndex++;
204            ucDisp++;
205            usNDiscrete--;
206            ucBits--;
207        }
208        *pucRegBuffer++ = ucStatus;
209    }
210
211        return MB_ENOERR;
212}

在main中創建modbus任務:

1static void task_modbus_handle(void *param)
 2{
 3
 4    eMBErrorCode    eStatus;
 5
 6    log("  task modbus start.");
 7
 8    eStatus = eMBInit( MB_RTU, 0x01, 0, 9600, MB_PAR_NONE );
 9
10    /* Enable the Modbus Protocol Stack. */
11    eStatus = eMBEnable();
12
13    (void)eStatus;
14
15    for( ;; ) {
16        ( void )eMBPoll();
17        vTaskDelay(pdMS_TO_TICKS(10));
18    }
19
20}

3 燒寫測試

將開發板連接到USB轉485模塊,然后使用modbus poll程序進行測試:

image-20220928232358657

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • MODBUS
    +關注

    關注

    28

    文章

    1805

    瀏覽量

    76986
  • STM32
    +關注

    關注

    2270

    文章

    10900

    瀏覽量

    355926
  • 開發板
    +關注

    關注

    25

    文章

    5047

    瀏覽量

    97440
  • FreeRTOS
    +關注

    關注

    12

    文章

    484

    瀏覽量

    62166
  • FreeModbus
    +關注

    關注

    0

    文章

    16

    瀏覽量

    4467
收藏 人收藏

    評論

    相關推薦

    AN5096_介紹STM32G0系列硬件開發

    AN5096_介紹STM32G0系列硬件開發
    發表于 11-21 08:11 ?4次下載
    AN5096_介紹<b class='flag-5'>STM32G0</b>系列硬件<b class='flag-5'>開發</b>

    STM32G0開發筆記FreeRTOS和CLI組件使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為FreeRTOS和CLI組件使用。
    的頭像 發表于 01-16 14:47 ?3595次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:<b class='flag-5'>FreeRTOS</b>和CLI組件使用

    STM32G0開發筆記:使用FreeRTOS系統的隊列Queue

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為使用FreeRTOS系統的隊列Queue。
    的頭像 發表于 01-16 14:50 ?1385次閱讀

    STM32G0開發筆記:使用FreeRTOS系統

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為使用FreeRTOS系統。
    的頭像 發表于 01-16 15:07 ?2418次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用<b class='flag-5'>FreeRTOS</b>系統

    STM32G0開發筆記:使用ADC進行NTC溫度采集

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下使用ADC進行NTC溫度采集。
    的頭像 發表于 01-16 15:12 ?9600次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用ADC進行NTC溫度采集

    STM32G0開發筆記:用PWM來實現LED呼吸燈效果

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面使用PWM來實現LED呼吸燈效果。
    的頭像 發表于 01-16 15:15 ?2293次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:用PWM來實現LED呼吸燈效果

    STM32G0開發筆記:EEPROM M24C02的使用方法

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為EEPROM M24C02的使用方法。
    的頭像 發表于 01-16 15:19 ?2881次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:EEPROM M24C02的使用方法

    STM32G0開發筆記:SD卡模塊的使用方法

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面介紹SD卡模塊的使用方法。
    的頭像 發表于 01-19 16:27 ?2342次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:SD卡模塊的使用方法

    STM32G0開發筆記:SPI接口的基本使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面介紹SPI接口的基本使用。
    的頭像 發表于 01-17 10:38 ?3126次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:SPI接口的基本使用

    STM32G0開發筆記:多通道ADC與DMA的使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為多通道ADC與DMA的使用。
    的頭像 發表于 01-17 10:41 ?7051次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:多通道ADC與DMA的使用

    STM32G0開發筆記:定時器timer的基本使用方法

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為定時器timer的基本使用方法。
    的頭像 發表于 01-17 10:43 ?3706次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:定時器timer的基本使用方法

    STM32G0開發筆記:串口中斷的使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為串口中斷的使用。
    的頭像 發表于 01-17 10:46 ?2355次閱讀

    STM32G0開發筆記:GPIO接按鍵的使用方式

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為GPIO接按鍵的使用方式。
    的頭像 發表于 01-17 10:48 ?1781次閱讀

    STM32G0開發筆記:LED燈示例

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為LED燈示例。
    的頭像 發表于 01-17 10:52 ?1419次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:LED燈示例

    STM32G0開發筆記:使用libopencm3

    使用Platformio平臺的libopencm3開發框架來開發STM32G0開發環境為VSCode+PIO插件,這里以開發
    的頭像 發表于 01-17 10:56 ?1918次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用libopencm3<b class='flag-5'>庫</b>
    主站蜘蛛池模板: 天天操综| 69xxxxxxxxxhd日本| 亚洲免费视频一区| 色综合日韩| 91极品反差婊在线观看| 最近国语视频免费观看在线播放| 黄视频免费网站| 萌白酱香蕉白丝护士服喷浆| 爽死你个放荡粗暴小淫视频| 亚洲高清一区二区三区四区| 色www| 香蕉久久久久久狠狠色| 九九九精品| 黄色网址中文字幕| 一级特级片| 国产成人综合久久| 亚洲成a人伦理| 四虎影院在线免费| 在线天堂中文在线网| dyav午夜片| 欧美色视频网| 日本在线网站| 在线久综合色手机在线播放| 国产主播在线一区| 性欧美丰满xxxx性久久久| 深夜偷偷看视频在线观看| 小视频国产| 黄到让你下面湿的视频| 国模精品一区二区| 美国bj69video18视频| 日产乱码免费一卡二卡在线| 天天弄天天模| 一色屋成人免费精品网| 成人性视频网站| 亚洲一区二区三区精品视频| 免费人成网站| 大喷水吹潮magnet| 日本精品一卡二卡≡卡四卡| 久久香蕉综合精品国产| 五月天婷婷电影| 天天艹天天|