<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[fr8008怎么实现 SysTick ?]]></title><description><![CDATA[<p>fr8008怎么实现 SysTick ?</p>
]]></description><link>http://www.freqchip.net:4567/topic/1890/fr8008怎么实现-systick</link><generator>RSS for Node</generator><lastBuildDate>Thu, 27 Aug 2026 00:50:39 GMT</lastBuildDate><atom:link href="http://www.freqchip.net:4567/topic/1890.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 24 Aug 2026 09:21:22 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to fr8008怎么实现 SysTick ? on Invalid Date]]></title><description><![CDATA[<p>fr8008怎么实现 SysTick ?</p>
]]></description><link>http://www.freqchip.net:4567/post/4625</link><guid isPermaLink="true">http://www.freqchip.net:4567/post/4625</guid><dc:creator><![CDATA[黄书剑]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to fr8008怎么实现 SysTick ? on Invalid Date]]></title><description><![CDATA[<p>如下</p>
<pre><code>
/*
 * INCLUDE FILES
 ****************************************************************************************
 */
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#include &quot;gap_api.h&quot;
#include &quot;gatt_api.h&quot;
#include &quot;ble_stack.h&quot;
#include &quot;app_config.h&quot;

#include &quot;jump_table.h&quot;
#include &quot;co_log.h&quot;

#include &quot;plf.h&quot;
#include &quot;driver_system.h&quot;
#include &quot;driver_pmu.h&quot;
#include &quot;driver_uart.h&quot;

#include &quot;ble_simple_peripheral.h&quot;
#include &quot;simple_gatt_service.h&quot;

#undef LOG_LOCAL_LEVEL
#define LOG_LOCAL_LEVEL        (LOG_LEVEL_INFO)
const char *app_tag = &quot;project&quot;;

#define SYSTEM_STACK_SIZE           0x800

void patch_init(void);
void disable_ch_sel_2(void);
void conn_req_rssi_filter(int8_t rssi_value);

void systick_init(void);
void systick_delay_ms(uint32_t ms);
void systick_delay_us(uint32_t us);
uint32_t systick_get_ms(void);

/*
 * LOCAL VARIABLES
 */
static volatile uint32_t g_systick_ms = 0;

__attribute__((section(&quot;stack_section&quot;))) static uint32_t system_stack[SYSTEM_STACK_SIZE/sizeof(uint32_t)];

const struct jump_table_version_t _jump_table_version __attribute__((section(&quot;jump_table_3&quot;))) = 
{
    .stack_top_address = &amp;system_stack[SYSTEM_STACK_SIZE/sizeof(uint32_t)],
    .firmware_version = 0x00000000,
};

const struct jump_table_image_t _jump_table_image __attribute__((section(&quot;jump_table_1&quot;))) =
{
    .image_type = IMAGE_TYPE_APP,
    .image_size = 0x20000,      
};

/*********************************************************************
 * @fn      SysTick_Handler
 *
 * @brief   1ms tick. Overrides the WEAK handler in boot_vectors.
 */
void SysTick_Handler(void)
{
    g_systick_ms++;
}

/*********************************************************************
 * @fn      systick_init
 *
 * @brief   Start SysTick at 1ms. Must be called after system_set_clock().
 */
void systick_init(void)
{
    uint32_t ticks = system_get_clock() / 1000;

    if ((ticks == 0) || ((ticks - 1) &gt; SysTick_LOAD_RELOAD_Msk)) {
        return;
    }

    SysTick_Config(ticks);
}

/*********************************************************************
 * @fn      systick_get_ms
 *
 * @brief   Milliseconds since systick_init. Does not advance in sleep.
 */
uint32_t systick_get_ms(void)
{
    return g_systick_ms;
}

/*********************************************************************
 * @fn      systick_delay_ms
 *
 * @brief   Blocking delay. Do not call with interrupts disabled.
 */
void systick_delay_ms(uint32_t ms)
{
    uint32_t start = g_systick_ms;

    while ((uint32_t)(g_systick_ms - start) &lt; ms) {
    }
}

/*********************************************************************
 * @fn      systick_delay_us
 *
 * @brief   Blocking us delay. Temporarily uses SysTick as a one-shot,
 *          then restores the 1ms tick.
 */
void systick_delay_us(uint32_t us)
{
    uint32_t clk = system_get_clock();
    uint32_t ticks_per_us;
    uint32_t max_us;

    if ((us == 0) || (clk &lt; 1000000)) {
        return;
    }

    ticks_per_us = clk / 1000000;
    max_us = SysTick_LOAD_RELOAD_Msk / ticks_per_us;

    while (us) {
        uint32_t chunk = (us &gt; max_us) ? max_us : us;

        SysTick-&gt;CTRL = 0;
        SysTick-&gt;LOAD = ticks_per_us * chunk - 1;
        SysTick-&gt;VAL  = 0;
        SysTick-&gt;CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;

        while ((SysTick-&gt;CTRL &amp; SysTick_CTRL_COUNTFLAG_Msk) == 0) {
        }

        us -= chunk;
    }

    systick_init();
}

/*********************************************************************
 * @fn      user_entry_before_sleep_imp
 *
 * @brief   Before system goes to sleep mode, user_entry_before_sleep_imp()
 *          will be called, MCU peripherals can be configured properly before 
 *          system goes to sleep, for example, some MCU peripherals need to be
 *          used during the system is in sleep mode. 
 *
 * @param   None. 
 *       
 *
 * @return  None.
 */
__attribute__((section(&quot;ram_code&quot;))) void user_entry_before_sleep_imp(void)
{
    /* SysTick uses CPU clock and would wake the core every 1ms */
    SysTick-&gt;CTRL = 0;

    pmu_calibration_stop();

    uart_putc_noint_no_wait(UART0, 's');
    co_delay_100us(1);

	pmu_set_pin_to_PMU(GPIO_PORT_A, (1&lt;&lt;GPIO_BIT_1));
	pmu_set_pin_to_PMU(GPIO_PORT_A, (1&lt;&lt;GPIO_BIT_0)|(1&lt;&lt;GPIO_BIT_4));
	pmu_set_pin_dir(GPIO_PORT_A, (1&lt;&lt;GPIO_BIT_0)|(1&lt;&lt;GPIO_BIT_4),GPIO_DIR_IN);
	pmu_set_pin_pull(GPIO_PORT_A, (1&lt;&lt;GPIO_BIT_0)|(1&lt;&lt;GPIO_BIT_4),GPIO_PULL_NONE);
    pmu_oscap_set(0);
}

/*********************************************************************
 * @fn      user_entry_after_sleep_imp
 *
 * @brief   After system wakes up from sleep mode, user_entry_after_sleep_imp()
 *          will be called, MCU peripherals need to be initialized again, 
 *          this can be done in user_entry_after_sleep_imp(). MCU peripherals
 *          status will not be kept during the sleep. 
 *
 * @param   None. 
 *       
 *
 * @return  None.
 */
__attribute__((section(&quot;ram_code&quot;))) void user_entry_after_sleep_imp(void)
{
    
    pmu_set_pin_to_CPU(GPIO_PORT_A, (1&lt;&lt;GPIO_BIT_0));
    
    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_0, PORTA0_FUNC_UART0_RXD);
    system_set_port_mux(GPIO_PORT_A, GPIO_BIT_1, PORTA1_FUNC_UART0_TXD);
    uart_init(UART0, 1152);
    fr_uart_enableIrq(UART0, Uart_irq_erbfi);

    /* RC calibration start. Ensure the accuracy of sleep wake time */
    pmu_calibration_start(PMU_CALI_SEL_RCLFOSC, LP_RC_CALIB_CNT);

    uart_putc_noint_no_wait(UART0, 'w');
    co_delay_100us(1);

    NVIC_EnableIRQ(PMU_IRQn);

    systick_init();
}

__attribute__((section(&quot;ram_code&quot;))) void main_loop(void)
{
    while(1)
    {
        if(ble_stack_schedule_allow())
        {
            /*user code should be add here*/
            
            /* schedule internal stack event */
            ble_stack_schedule();
        }
        
        GLOBAL_INT_DISABLE();
        switch(ble_stack_sleep_check())
        {
            case 2:
            {
                ble_stack_enter_sleep();
            }
            break;
            default:
                break;
        }
        GLOBAL_INT_RESTORE();
        
        ble_stack_schedule_backward();
    }
}

/*********************************************************************
 * @fn      proj_init
 *
 * @brief   Main entrancy of user application. This function is called after BLE stack
 *          is initialized, and all the application code will be executed from here.
 *          In that case, application layer initializtion can be startd here. 
 *
 * @param   None. 
 *       
 *
 * @return  None.
 */
void proj_init(void)
{
    LOG_INFO(app_tag, &quot;BLE Peripheral\r\n&quot;);
	co_printf(&quot;%s\r\n&quot;,__func__);
    systick_delay_ms(500);
	co_printf(&quot;%s\r\n&quot;,__TIME__);
	
    // Application layer initialization, can included bond manager init, 
    // advertising parameters init, scanning parameter init, GATT service adding, etc.    
    simple_peripheral_init();
}





</code></pre>
]]></description><link>http://www.freqchip.net:4567/post/4631</link><guid isPermaLink="true">http://www.freqchip.net:4567/post/4631</guid><dc:creator><![CDATA[Mars]]></dc:creator><pubDate>Invalid Date</pubDate></item></channel></rss>