国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT

這篇具有很好參考價(jià)值的文章主要介紹了第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲取: https://item.taobao.com/item.htm?id=728461040949

配套資料獲?。篽ttps://renesas-docs.100ask.net

瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總: https://blog.csdn.net/qq_35181236/article/details/132779862


第18章 GPT

本章目標(biāo)

  • 了解RA6M5處理器的GPT外設(shè);
  • 學(xué)會(huì)使用RASC配置GPT實(shí)現(xiàn)基本定時(shí)和PWM輸出;

18.1 GPT簡(jiǎn)介

通用PWM定時(shí)器(GPT,Genera- PWM Timer)是RA MCU的一種32/16位的定時(shí)器外設(shè)。在GPT當(dāng)中,可分為GPT32和GPT16,它們最主要的區(qū)別是計(jì)數(shù)器的位數(shù)不同。GPT32是32位的定時(shí)器,能計(jì)數(shù)的范圍為:0~0xFFFF_FFFF; 而GPT16是16位的定時(shí)器,能計(jì)數(shù)的范圍為:0~0xFFFF。

GPT模塊可用于計(jì)數(shù)事件、測(cè)量外部輸入信號(hào)、作為通用計(jì)時(shí)器并產(chǎn)生周期性中斷、以及輸出周期性PWM信號(hào)到GTIO引腳。GPT也可用于輸出單個(gè)脈沖,但是注意這是通過(guò)軟件來(lái)實(shí)現(xiàn)的,GPT硬件本身不支持輸出單個(gè)脈沖(One-Shot)功能。當(dāng)使用單個(gè)脈沖(One-Shot)模式時(shí),必須要開(kāi)啟中斷,在脈沖周期結(jié)束后在ISR中斷服務(wù)函數(shù)中停止計(jì)時(shí)器。

RA MCU的GPT包括但不限于如下這些特征:

  • 32位GPT有4個(gè)輸入/輸出通道;16位GPT有6個(gè)輸入輸出通道;
  • 每個(gè)GPT的計(jì)數(shù)器支持向上計(jì)數(shù)、向下計(jì)數(shù)或者向上向下同時(shí)計(jì)數(shù);
  • 每個(gè)通道的時(shí)鐘源都可以單獨(dú)配置選擇;
  • 每個(gè)通道有2個(gè)引腳可用來(lái)輸入輸出;
  • 每個(gè)通道有2個(gè)輸出比較寄存器或者輸入捕獲寄存器;
  • 每個(gè)通道的輸出比較寄存器或輸入捕獲寄存器都有4個(gè)緩存寄存器;
  • 在PWM模式下支持設(shè)置死區(qū)時(shí)間;
  • 計(jì)數(shù)器的開(kāi)始、停止、清除等動(dòng)作可以由最多8個(gè)ELC事件響應(yīng),也可以由最多4個(gè)外部觸發(fā)器相應(yīng);
  • 支持生成控制無(wú)刷直流電機(jī)的PWM波;

RA MCU的GPT支持下表的這些功能:·

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

RA MCU的GPT引腳及其功能用途如下表:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

最后來(lái)看下GPT的系統(tǒng)框圖:

![](
http://photos.100ask.net/renesas-docs/DShanMCU_RA6M5/object_oriented_module_programming_method_in_ARM_embedded_system/chapter-18/image4.png" alt="image4)

  1. 計(jì)數(shù)器

GTCNT是GPT定時(shí)器模塊內(nèi)部的計(jì)數(shù)器,實(shí)際上,計(jì)數(shù)器是實(shí)現(xiàn)定時(shí)器外設(shè)的各種功能的基礎(chǔ)。 因此,了解計(jì)數(shù)器的規(guī)格和功能非常重要。

對(duì)于RA6M5,共有10個(gè)GPT定時(shí)器(GPT09),而GPT又分為GPT32和GPT16。GPT32有4個(gè)(GPT03),計(jì)數(shù)器為32bit,在上圖中用GPT320GPT323來(lái)表示;而GPT16有6個(gè)(GPT49),計(jì)數(shù)器為16bit,在上圖中用GPT164~GPT169來(lái)表示。

GPT的計(jì)數(shù)器支持遞增計(jì)數(shù),遞減計(jì)數(shù)和遞增/遞減計(jì)數(shù)(即遞增與遞減計(jì)數(shù)輪流進(jìn)行)。

  1. 時(shí)鐘源

GPT定時(shí)器的時(shí)鐘輸入可以選擇內(nèi)部的PCLKD分頻后輸入,或者選擇通過(guò)GTETRGn引腳輸入外部時(shí)鐘。這兩類(lèi)中只能選擇一個(gè),若選擇外部時(shí)鐘輸入則定時(shí)器不能對(duì)內(nèi)部時(shí)鐘輸入進(jìn)行計(jì)數(shù)。

  • PCLKD / n(n = 1/2/4/8/16/32/64/256/1024)
  • GTETRGA,GTETRGB,GTETRGC,GTETRGD(通過(guò)POEG)

注:PCLKD / 1表示的是不分頻。

  1. 周期設(shè)置

GTPR周期設(shè)置寄存器,是一個(gè)可讀寫(xiě)的寄存器,用戶(hù)可通過(guò)該寄存器設(shè)置計(jì)數(shù)器GTCNT的最大計(jì)數(shù)值,計(jì)數(shù)超過(guò)該值就會(huì)溢出,因此該值決定了計(jì)數(shù)器的計(jì)數(shù)周期。GTPR的有效位與GTCNT(16位或32位)相同。如果GTPR的有效大小為16位,則用戶(hù)讀取其高16位始終為0,并且對(duì)其高16位的寫(xiě)入作會(huì)被忽略。

GTPBR 周期設(shè)置緩沖寄存器,同樣也是一個(gè)可讀寫(xiě)的寄存器,用作GTPR的緩沖寄存器,GPT計(jì)數(shù)器每計(jì)數(shù)溢出一次,就會(huì)將GTPBR的值寫(xiě)入GTPR。GTPBR的有效大小也與GTCNT(16位或32位)相同。如果GTPBR的有效大小為16位,則用戶(hù)讀取其高16位始終為0,并且對(duì)其高16位的寫(xiě)入作會(huì)被忽略。

  1. 控制寄存器

本書(shū)是面向?qū)ο蟮木幊趟枷?,不?huì)基于寄存器直面底層硬件編程,且GPT的控制寄存器很多,本書(shū)不對(duì)GPT的寄存器做一一講解。

  1. 比較輸出和輸入捕獲控制寄存器

這部分包含一個(gè)比較器和6個(gè)GTCCRx寄存器(x = A,B,C,D,E,F)。這6個(gè)GTCCRx寄存器的功能并不完全相同:

  • GTCCRA和GTCCRB是用于輸出比較和輸入捕捉的寄存器。
  • GTCCRC和GTCCRE可用作比較匹配寄存器,也可以分別作為GTCCRA和GTCCRB的緩沖寄存器(構(gòu)成GTCCRA和GTCCRB的單緩沖寄存器)。
  • GTCCRD和GTCCRF可用作比較匹配寄存器,也可以分別作為GTCCRC和GTCCRE的緩沖寄存器(構(gòu)成GTCCRA和GTCCRB的雙緩沖寄存器:即GTCCRC和GTCCRD作為GTCCRA的雙緩沖,GTCCRE和 GTCCRF作為GTCCRB的雙緩沖)。

比如,在普通的PWM輸出模式下,比較器將計(jì)數(shù)器GTCNT與GTCCRA和GTCCRB進(jìn)行比較,若匹配(比較結(jié)果相等),則根據(jù)GTIOR(Genera- PWM Timer I/O Contro- Register)寄存器的GTIOA[4:0]和GTIOB[4:0]的配置來(lái)切換GTIOCA和GTIOCB的輸出電平??梢詫TIOCA和GTIOCB切換為低電平、高電平、或者反轉(zhuǎn)電平。

  1. 中斷源

圖中顯示的是GPT0的中斷請(qǐng)求信號(hào),中斷請(qǐng)求信號(hào)用于產(chǎn)生中斷、或者通過(guò)ELC鏈接到其他模塊。

GPT提供以下中斷源:

  • GTCCR輸入捕捉/比較匹配
  • GTCNT計(jì)數(shù)器上溢(超出GTPR設(shè)置的值)/下溢
  • 周期計(jì)數(shù)功能完成

每個(gè)中斷源都有自己的狀態(tài)標(biāo)志。當(dāng)一個(gè)中斷源信號(hào)產(chǎn)生時(shí),相關(guān)的狀態(tài)標(biāo)志會(huì)被硬件自動(dòng)設(shè)置為1。狀態(tài)標(biāo)志可以通過(guò)寫(xiě)入0來(lái)清除。需要注意的是,如果標(biāo)志設(shè)置和標(biāo)志清除同時(shí)發(fā)生,標(biāo)志清除優(yōu)先于標(biāo)志設(shè)置。

  1. GPT輸入引腳

GTIOCnA和GTIOCnB是GPT的IO輸入輸出引腳,用于信號(hào)輸出和輸入捕獲。它們還配備了噪聲濾波器(Noise Filter),噪聲濾波器以采樣時(shí)鐘對(duì)輸入信號(hào)進(jìn)行采樣,并去除長(zhǎng)度小于3個(gè)采樣周期的脈沖。用戶(hù)可設(shè)置是否啟用噪聲濾波器。

  1. ELC輸入事件

GPT可以執(zhí)行以下操作以響應(yīng)最多8個(gè)來(lái)自ELC的事件信號(hào)輸入:

  • 開(kāi)始計(jì)數(shù),停止計(jì)數(shù),清除計(jì)數(shù)
  • 遞增計(jì)數(shù),遞減計(jì)數(shù)
  • 進(jìn)行一次輸入捕獲
  1. 輸出相位切換控制

輸出相位切換(GPT_OPS)功能通過(guò)輸出相位切換控制寄存器(OPSCR)進(jìn)行控制,用于實(shí)現(xiàn)輕松控制無(wú)刷直流電機(jī)運(yùn)行的功能。

需要注意的是:GPT_OPS功能在RA6M5中只有一個(gè),并不是每個(gè)GPT定時(shí)器都對(duì)應(yīng)有一個(gè),也就是說(shuō)通過(guò)該功能只能輕松控制一個(gè)直流無(wú)刷電機(jī)。

18.2 GPT模塊的使用

在RASC中使用GPT模塊根據(jù)應(yīng)用場(chǎng)景分為兩類(lèi):基本定時(shí)、有輸入/輸出需求。如果僅僅用作基本定時(shí),那么只需要在RASC的“Stacks”中添加GPT模塊即可;如果有輸入輸出需求的,例如輸出PWM到某個(gè)引腳或者對(duì)某個(gè)波形進(jìn)行捕獲比較,那就需要去FSP的“Pins”中配置該引腳,然后再去“Stacks”中添加配置GPT模塊。

18.2.1 配置GPT模塊

如果需要輸出波形到某個(gè)引腳或者捕獲比較某個(gè)引腳,建議先去RASC的“Pins”配置引腳。

  1. 配置GPT引腳

在“Pins”中的“Peripherals”中找到“Timers:GPT”,根據(jù)硬件設(shè)計(jì)選擇GPT通道和引腳,比如要使用PWM實(shí)現(xiàn)一個(gè)呼吸燈,LED的原理圖如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

使用到的引腳是P400,此引腳支持的GPT復(fù)用通道在RA6M5數(shù)據(jù)手冊(cè)中查看:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

可以看到P400支持的GPT復(fù)用通道是GTIOC6A,也就是GPT通道6的A組引腳,那么就可以配置Pins了,如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

  1. 添加GPT Stack

在FSP的“Stacks”中點(diǎn)擊“New Stack”找到“Timers”,選擇其中的“Timer,General PWM(r_gpt)”添加GPT模塊,如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

接著根據(jù)使用場(chǎng)景配置GPT的Stack模塊。GPT的Stack有3個(gè)大類(lèi)需要配置:

  • Common:通用配置,適配該外設(shè)所有的stack模塊。對(duì)于GPT而言,通用配置需要設(shè)置的參數(shù)是:

    • Parameter Checking:參數(shù)校驗(yàn),在FSP庫(kù)函數(shù)中判斷參數(shù)是否合法,使用斷言方式判斷,默認(rèn)不使能。
    • Pin Output Support:GPT輸出引腳是否使能,支持兩種模式:使能和根據(jù)模塊外部特征配置使能。默認(rèn)使用“根據(jù)模塊外部特征配置使能”,目的是不同的模塊使用不同的配置實(shí)現(xiàn)定制化。
    • Write Protect Enable:寫(xiě)保護(hù),默認(rèn)不使能。
    • Clock Source:時(shí)鐘源,GPT默認(rèn)選擇PCLKD。
  • Module g_timer Timer,General PWM(r_gpt):模塊定制化配置,是本節(jié)配置的重點(diǎn)。

  • Pins:引腳選擇,如果有輸入輸出需求,會(huì)自動(dòng)連接到前文配置的引腳。如果是多通道,需要選擇配置。

  1. 配置GPT Module

GPT的通道定制化Module配置有以下5類(lèi)參數(shù)需要配置:

  • General:常規(guī)配置

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

  • OutPut:輸出配置

此項(xiàng)是配置GPT輸出功能的參數(shù),例如占空比、引腳初始狀態(tài)、空閑狀態(tài)等,參數(shù)比較多,不一一列舉,主要內(nèi)容如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

后文會(huì)配置此處的參數(shù)生成PWM來(lái)實(shí)現(xiàn)呼吸燈效果,那時(shí)會(huì)詳細(xì)介紹這些參數(shù)。

  • Input:輸入配置

此項(xiàng)是配置GPT的輸入捕獲功能,需要配置觸發(fā)捕獲向上計(jì)數(shù)的源、觸發(fā)向下計(jì)數(shù)的源、開(kāi)始捕獲觸發(fā)源、停止捕獲觸發(fā)源等,詳細(xì)內(nèi)容見(jiàn)下圖:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

這些觸發(fā)源都需要根據(jù)硬件設(shè)計(jì)選擇。

  • Interrupts:中斷配置

此項(xiàng)配置GPT的中斷回調(diào)函數(shù)和中斷優(yōu)先級(jí),比如溢出中斷優(yōu)先級(jí)、輸入捕獲優(yōu)先級(jí)等,如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

  • Extra Features:外部特征配置

GPT的外部特征配置是指配置GPT輸出引腳的使能、GPT計(jì)數(shù)的觸發(fā)源、死區(qū)時(shí)間的設(shè)置等,如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

當(dāng)GPT的使用更加精細(xì),比如會(huì)和ADC搭配使用,需要生成復(fù)雜的PWM、三角PWM時(shí),就需要對(duì)外部特征進(jìn)行更加精細(xì)的,定制化的配置。

18.2.2 配置信息解讀

使用RASC將GPT的stack模塊配置好之后點(diǎn)擊“Generate Project Content”生成工程,會(huì)在工程的pin_data.c中生成模塊的引腳信息,在hal_data.c中生成模塊的配置信息。

  1. GPT的引腳信息

假設(shè)需要使用GPT往P400引腳輸出PWM控制LED,使用RASC配置GPT的通道且指定引腳后,生成的工程中的pin_data.c中的g_bsp_pin_cfg_data[]數(shù)組就會(huì)添加該引腳的配置信息,代碼如下:

const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
    ......(省略?xún)?nèi)容)
    {.pin = BSP_IO_PORT_04_PIN_00,
    .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN 
              | (uint32_t) IOPORT_PERIPHERAL_GPT1)
    },
};
  1. GPT的模塊配置信息

GPT模塊的配置信息在hal_data.c中以timer_cfg_t類(lèi)型的結(jié)構(gòu)體變量表示,代碼如下:

const timer_cfg_t g_timer6_cfg =
{
    .mode                = TIMER_MODE_PERIODIC,
    /* Actual period: 0.001 seconds. Actual duty: 50%. */ 
    .period_counts = (uint32_t) 0x186a0, 
    .duty_cycle_counts = 0xc350, 
    .source_div = (timer_source_div_t)0,
    .channel             = 6,
    .p_callback          = gpt_timer6_callback,
    /** If NULL then do not add & */
#if defined(NULL)
    .p_context           = NULL,
#else
    .p_context           = &NULL,
#endif
    .p_extend            = &g_timer6_extend,
    .cycle_end_ipl       = (10),
#if defined(VECTOR_NUMBER_GPT2_COUNTER_OVERFLOW)
    .cycle_end_irq       = VECTOR_NUMBER_GPT2_COUNTER_OVERFLOW,
#else
    .cycle_end_irq       = FSP_INVALID_VECTOR,
#endif
};
  • 第03行:mode表示GPT的類(lèi)型,此處是周期型;
  • 第05~06行:表示輸出PWM的周期和占空比;
  • 第08行:表示使用的GPT的通道;
  • 第09行:表示GPT的中斷回調(diào)函數(shù);

在程序中使用GPT的open函數(shù)打開(kāi)GPT設(shè)備的時(shí),就會(huì)使用這些配置信息初始化GPT。

18.2.3 中斷回調(diào)函數(shù)

使用RASC配置生成工程后,配置的中斷回調(diào)函數(shù)會(huì)在hal_data.h中聲明,代碼如下:

#ifndef gpt_timer6_callback
void gpt_timer6_callback(timer_callback_args_t * p_args);
#endif

用戶(hù)需要在自己的程序中實(shí)現(xiàn)這個(gè)中斷回調(diào)函數(shù),例如:

void gpt_timer6_callback(timer_callback_args_t *p_args)
{
    /* TODO: add your own code here */
}

用戶(hù)可以根據(jù)中斷回調(diào)函數(shù)的參數(shù)timer_callback_args_t的成員進(jìn)行定制處理,這個(gè)結(jié)構(gòu)體的原型長(zhǎng)這樣:

typedef struct st_timer_callback_args
{
    /** Placeholder for user data.  Set in @ref timer_api_t::open function in @ref timer_cfg_t. */
    void const  * p_context;
    timer_event_t event;               ///< The event can be used to identify what caused the callback.

    /** Most recent capture, only valid if event is TIMER_EVENT_CAPTURE_A or TIMER_EVENT_CAPTURE_B. */
        uint32_t capture;
} timer_callback_args_t;

最常用的就是其中的定時(shí)器事件成員timer_event_t,它支持的事件如下:

/** Events that can trigger a callback function */
typedef enum e_timer_event
{
    TIMER_EVENT_CYCLE_END, ///< Requested timer delay has expired or timer has wrapped around
    TIMER_EVENT_CREST = TIMER_EVENT_CYCLE_END, ///< Timer crest event (counter is at a maximum, triangle-wave PWM only)
    TIMER_EVENT_CAPTURE_A,                    ///< A capture has occurred on signal A
    TIMER_EVENT_CAPTURE_B,                    ///< A capture has occurred on signal B
    TIMER_EVENT_TROUGH,      ///< Timer trough event (counter is 0, triangle-wave PWM only
} timer_event_t;

比如用戶(hù)可以判斷事件是否為T(mén)IMER_EVENT_CYCLE_END,它表示計(jì)數(shù)到指定周期了才進(jìn)入的中斷:

if(p_args->event == TIMER_EVENT_CYCLE_END)
{
}

18.2.4 API接口及其用法

GPT模塊供用戶(hù)使用的API在r_timer_api.h中定義:

typedef struct st_timer_api
{
    fsp_err_t (* open)(timer_ctrl_t * const p_ctrl, 
                       timer_cfg_t const * const p_cfg);
    fsp_err_t (* start)(timer_ctrl_t * const p_ctrl);
    fsp_err_t (* stop)(timer_ctrl_t * const p_ctrl);
    fsp_err_t (* reset)(timer_ctrl_t * const p_ctrl);
    fsp_err_t (* enable)(timer_ctrl_t * const p_ctrl);
    fsp_err_t (* disable)(timer_ctrl_t * const p_ctrl);
    fsp_err_t (* periodSet)(timer_ctrl_t * const p_ctrl, 
                            uint32_t const period);
    fsp_err_t (* dutyCycleSet)(timer_ctrl_t * const p_ctrl, 
                               uint32_t const duty_cycle_counts, 
                               uint32_t const pin);
    fsp_err_t (* infoGet)(timer_ctrl_t * const p_ctrl, 
                          timer_info_t * const p_info);
    fsp_err_t (* statusGet)(timer_ctrl_t * const p_ctrl, 
                            timer_status_t * const p_status);
    fsp_err_t (* callbackSet)(timer_ctrl_t * const p_api_ctrl, 
                              void (* p_callback)(timer_callback_args_t *),
                              void const * const p_context, 
                              timer_callback_args_t * const p_callback_memory);
    fsp_err_t (* close)(timer_ctrl_t * const p_ctrl);
} timer_api_t;

接下來(lái)看下這些API的用法。

  1. 打開(kāi)GPT設(shè)備
fsp_err_t (* open)(timer_ctrl_t * const p_ctrl, 
                   timer_cfg_t const * const p_cfg);
  • p_ctrl:timer_ctrl_t結(jié)構(gòu)體指針參數(shù),本質(zhì)是一個(gè)void類(lèi)型的參數(shù),指向st_gpt_instance_ctrl類(lèi)型變量;
  • p_cfg:timer_cfg_t結(jié)構(gòu)體指針參數(shù),在程序中會(huì)指向在hal_data.c中定義的g_timer6_cfg靜態(tài)全局變量;

用戶(hù)在程序中可以參考如下代碼使用此函數(shù):

fsp_err_t err = g_timer6.p_api->open(g_timer0.p_ctrl, g_timer6.p_cfg);
if(FSP_SUCCESS != err)
    printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
  1. 開(kāi)啟/停止GPT計(jì)數(shù)
  • GPT開(kāi)始計(jì)數(shù)
fsp_err_t (* start)(timer_ctrl_t * const p_ctrl);
  • GPT停止計(jì)數(shù)
fsp_err_t (* stop)(timer_ctrl_t * const p_ctrl);

必須要在GPT打開(kāi)狀態(tài)下使用這兩個(gè)函數(shù),用戶(hù)可以參考如下代碼在自己的程序中使用這兩個(gè)函數(shù):

err = g_timer6.p_api->start(g_timer6.p_ctrl);
if(FSP_SUCCESS != err)
    printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
    
err = g_timer6.p_api->stop(g_timer6.p_ctrl);
if(FSP_SUCCESS != err)
    printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
  1. 重置GPT計(jì)數(shù)值
fsp_err_t (* reset)(timer_ctrl_t * const p_ctrl);

如果GPT是向上計(jì)數(shù),使用此函數(shù)會(huì)將計(jì)數(shù)器的值重置為0;如果是向下計(jì)數(shù),使用此函數(shù)會(huì)將計(jì)數(shù)器的值重置為設(shè)定的周期值。

  1. 使能/失能GPT的輸入捕獲
  • 使能GPT輸入捕獲
fsp_err_t (* enable)(timer_ctrl_t * const p_ctrl);
  • 失能GPT輸入捕獲
    fsp_err_t (* disable)(timer_ctrl_t * const p_ctrl);

如果用戶(hù)使用了GPT的輸入捕獲功能的話(huà),在需要對(duì)引腳的信號(hào)進(jìn)行捕獲時(shí)需要使能捕獲功能;如果想要停止捕獲則調(diào)用disable。

  1. 設(shè)置GPT的計(jì)數(shù)周期值
    fsp_err_t (* periodSet)(timer_ctrl_t * const p_ctrl, 
                        uint32_t const period);

如果要改變定時(shí)器的計(jì)數(shù)周期,可以調(diào)用此函數(shù),在下一次重新計(jì)數(shù)開(kāi)始生效。

  1. 設(shè)置GPT輸出PWM的占空比
fsp_err_t (* dutyCycleSet)(timer_ctrl_t * const p_ctrl, 
                           uint32_t const duty_cycle_counts, 
                           uint32_t const pin);

在PWM驅(qū)動(dòng)應(yīng)用中,可以使用此函數(shù)來(lái)修改占空比。用戶(hù)可以參考如下代碼來(lái)使用這個(gè)函數(shù):

fsp_err_t err = g_timer6.p_api->dutyCycleSet(g_timer6.p_ctrl, gPulse, GPT_IO_PIN_GTIOCA);
if(FSP_SUCCESS != err)
printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);

此函數(shù)最后一個(gè)參數(shù)是指GPT的輸出通道,而不是指IO引腳。

  1. 關(guān)閉GPT設(shè)備
fsp_err_t (* close)(timer_ctrl_t * const p_ctrl);

18.3 GPT的基本定時(shí)功能

本節(jié)實(shí)驗(yàn)會(huì)使用到串口打印以及滴答定時(shí)器,請(qǐng)將前文的drv_uart.c/.h和hal_systick.c/.h移植到本次實(shí)驗(yàn)中。

18.3.1 設(shè)計(jì)目的

實(shí)現(xiàn)一個(gè)基于硬件定時(shí)器的延時(shí)函數(shù),最小延時(shí)時(shí)間為1us。同時(shí)利用滴答定時(shí)器輔助驗(yàn)證,通過(guò)串口打印調(diào)試結(jié)果。

18.3.2 GPT模塊配置

本次實(shí)驗(yàn)只用到了GPT的基本定時(shí)計(jì)數(shù)功能,沒(méi)有使用到比較輸出或捕獲輸出,因而僅添加了stack模塊,沒(méi)有配置Pins。GPT Stack模塊的Module配置如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

雖然配置的時(shí)候選擇的周期和單位是1us,但是在實(shí)際使用中可以改變這個(gè)值,所以Period和Period Unit在配置時(shí)其實(shí)可以選任意值。

另外,基于本次實(shí)驗(yàn)的目的,本書(shū)將定時(shí)器設(shè)置為one-shot模式,每次延時(shí)只需要計(jì)數(shù)器完成一次周期計(jì)數(shù)溢出。

18.3.3 驅(qū)動(dòng)程序

  1. 初始化
void GPTDrvInit(void)
{
    fsp_err_t err = g_timer0.p_api->open(g_timer0.p_ctrl, g_timer0.p_cfg);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
}

初始化函數(shù)比較簡(jiǎn)單,僅僅只是調(diào)用GPT的open函數(shù)打開(kāi)設(shè)備。

  1. 中斷回調(diào)函數(shù)和溢出等待函數(shù)
static void GPTDrvWaitOverflow(void);
static volatile bool gGPTOverflow = false;
/* Callback function */
void gpt_timer0_callback(timer_callback_args_t *p_args)
{
    /* TODO: add your own code here */
    if(p_args->event == TIMER_EVENT_CYCLE_END)
        gGPTOverflow = true;
}

static void GPTDrvWaitOverflow(void)
{
    while(!gGPTOverflow);
    gGPTOverflow = false;
}
  • 第02行:定義一個(gè)bool類(lèi)型的標(biāo)志位來(lái)表示定時(shí)器計(jì)數(shù)是否溢出,在中斷回調(diào)函數(shù)中它被賦值為true,在等待函數(shù)中它被賦值為false;
  • 第07行:判斷的定時(shí)器中斷事件是周期結(jié)束事件,表示一次周期性的計(jì)數(shù)完成觸發(fā)的中斷;
  1. 微秒延時(shí)函數(shù)
void GPTDrvUDelay(unsigned int time)
{
    fsp_err_t err = g_timer0.p_api->periodSet(g_timer0.p_ctrl, time*100);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);

    err = g_timer0.p_api->reset(g_timer0.p_ctrl);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);

    err = g_timer0.p_api->start(g_timer0.p_ctrl);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);

    GPTDrvWaitOverflow();
}
  • 第03行:根據(jù)參數(shù)和定時(shí)器的時(shí)鐘頻率計(jì)算周期值,定時(shí)器的時(shí)鐘頻率是100MHz,要計(jì)數(shù)達(dá)到1us的時(shí)間就需要以100MHz的頻率計(jì)數(shù)100下。因而要實(shí)現(xiàn)以n微秒,就需要給定時(shí)器設(shè)置n*100個(gè)計(jì)數(shù)周期值。
  • 第07行:復(fù)位計(jì)數(shù)器的計(jì)數(shù)值,本次選擇的是向上計(jì)數(shù),復(fù)位后計(jì)數(shù)器的計(jì)數(shù)值會(huì)歸零;
  • 第11行:開(kāi)啟定時(shí)器計(jì)數(shù),因?yàn)楸敬问褂玫氖莖ne-shot模式,當(dāng)定時(shí)器計(jì)數(shù)time*100次后會(huì)自動(dòng)停止;

18.3.4 測(cè)試程序

void GPTAppTest(void)
{
    SystickInit();
    UARTDrvInit();
    GPTDrvInit();
    
    {
        uint32_t lastTick = HAL_GetTick();
        GPTDrvUDelay(1000000);    // delay 1ms
        uint32_t curTick = HAL_GetTick();
        printf("Last    Tick: %d\r\n", (int)lastTick);
        printf("Current Tick: %d\r\n", (int)curTick);
        printf("Passed  Tick: %d\r\n", (int)(curTick - lastTick));
    }
}
  • 第08行:獲取us延時(shí)函數(shù)調(diào)用前的滴答定時(shí)器時(shí)刻;
  • 第09行:延時(shí)1000,000us也就是1s,因?yàn)槭褂玫氖堑未鸲〞r(shí)器輔助驗(yàn)證,延時(shí)函數(shù)需要大于1ms;
  • 第10行:獲取us延時(shí)函數(shù)調(diào)用后的滴答定時(shí)器時(shí)刻;
  • 第13行:打印出兩次時(shí)刻的差值計(jì)算us延時(shí)函數(shù)的實(shí)際耗時(shí);

18.3.5 測(cè)試結(jié)果

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

可以看到滴答定時(shí)器走過(guò)的tick數(shù)為1000,也就是耗時(shí)1s,和實(shí)驗(yàn)預(yù)期一致。

18.4 PWM實(shí)現(xiàn)呼吸燈

本節(jié)實(shí)驗(yàn)會(huì)使用到串口打印以及滴答定時(shí)器,請(qǐng)將前文的drv_uart.c/.h和hal_systick.c/.h移植到本次實(shí)驗(yàn)中。

18.4.1 設(shè)計(jì)目的

使用GPT輸出PWM,通過(guò)調(diào)節(jié)PWM的占空比來(lái)改變LED的亮度,通過(guò)設(shè)計(jì)合理的周期值來(lái)達(dá)到適宜的呼吸燈效果。

18.4.2 硬件連接

LED的原理圖如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

在前文已經(jīng)分析過(guò)P400可以復(fù)用做GPT通道6的輸出IO。

18.4.3 GPT模塊配置

在FSP中對(duì)GPT6模塊的配置如下圖所示:

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT,瑞薩MCU基礎(chǔ)入門(mén)教程,單片機(jī),嵌入式硬件,瑞薩,瑞薩MCU,嵌入式

  1. 通道:6
  2. 模式:周期型,周期值:1kHz
  3. 初始占空比:50%
  4. 中斷回調(diào)函數(shù):gpt_timer6_callback

18.4.4 驅(qū)動(dòng)程序

  1. 初始化

本次實(shí)驗(yàn)的初始化程序如下:

void GptPWMDrvInit(void)
{
    fsp_err_t err = g_timer6.p_api->open(g_timer6.p_ctrl, g_timer6.p_cfg);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);

    err = g_timer6.p_api->infoGet(g_timer6.p_ctrl, &gTimerInfo);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
    gPeriod = gTimerInfo.period_counts;
    gStep = gPeriod/1500;
    
    err = g_timer6.p_api->start(g_timer6.p_ctrl);
    if(FSP_SUCCESS != err)
        printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
}
  • 第03行:使用open函數(shù)初始化GPT6的配置;
  • 第07行:獲取GPT6的初始配置,最重要的是獲取到周期數(shù)值;
  • 第11行:根據(jù)周期數(shù)值和預(yù)期的呼吸燈效果,設(shè)計(jì)為逐漸加強(qiáng)和逐漸減弱的時(shí)間都為1.5s;
  • 第13行:開(kāi)啟定時(shí)器計(jì)數(shù);
  1. 中斷回調(diào)函數(shù)

    本次實(shí)驗(yàn)以1kHz頻率觸發(fā)溢出中斷,每次中斷都要修改PWM的占空比來(lái)達(dá)到LED亮度的增強(qiáng)和減弱,代碼如下:

void gpt_timer6_callback(timer_callback_args_t *p_args)
{
    /* TODO: add your own code here */
    if(p_args->event == TIMER_EVENT_CYCLE_END)
    {
        if(gDir)
            gPulse -= gStep;
        else
            gPulse += gStep;
        if(gPulse <= 0)
            gDir = false;
        else if(gPulse >= gPeriod)
            gDir = true;
        fsp_err_t err = g_timer6.p_api->dutyCycleSet(g_timer6.p_ctrl, gPulse, GPT_IO_PIN_GTIOCA);
        if(FSP_SUCCESS != err)
            printf("Function:%s\tLine:%d\r\n", __FUNCTION__, __LINE__);
    }
}
  • 第04行:判斷觸發(fā)中斷的是否是周期性計(jì)數(shù)溢出觸發(fā)的;
  • 第06~13行:根據(jù)占空比的數(shù)值決定本次是處于亮度增強(qiáng)期還是減弱期,如果是增強(qiáng)期則增加占空比,否則減小占空比;
  • 第14行:調(diào)用函數(shù)修改PWM的占空比;

18.4.5 測(cè)試結(jié)果

本次實(shí)驗(yàn)需要在實(shí)際硬件上驗(yàn)證。在本書(shū)配套的開(kāi)發(fā)板上運(yùn)行此程序可以發(fā)現(xiàn)LED以大約1.5s的時(shí)間從暗狀態(tài)逐漸增強(qiáng)到最亮,然后又花1.5s的時(shí)間逐漸減弱到暗狀態(tài)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-705509.html


本章完

到了這里,關(guān)于第18章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之GPT的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 第10章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之中斷控制單元簡(jiǎn)介

    第10章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之中斷控制單元簡(jiǎn)介

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本書(shū)使用的RA處理器R7FAM5系

    2024年02月09日
    瀏覽(30)
  • 第6章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之串行通信接口(SCI)

    第6章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之串行通信接口(SCI)

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目標(biāo) 了解串行通信協(xié)

    2024年01月24日
    瀏覽(32)
  • 第3章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之開(kāi)發(fā)環(huán)境搭建與體驗(yàn)

    第3章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之開(kāi)發(fā)環(huán)境搭建與體驗(yàn)

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目標(biāo): 搭建 Renesas 的

    2024年02月09日
    瀏覽(26)
  • 第28章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之基于面向?qū)ο蟮墓こ探Y(jié)構(gòu)

    第28章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之基于面向?qū)ο蟮墓こ探Y(jié)構(gòu)

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 在前面的章節(jié)里,講解了瑞

    2024年02月09日
    瀏覽(34)
  • 第21章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之事件鏈接控制器ELC

    第21章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之事件鏈接控制器ELC

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目標(biāo) 了解ELC基本概念

    2024年02月08日
    瀏覽(35)
  • 第1章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之單片機(jī)程序的設(shè)計(jì)模式

    第1章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之單片機(jī)程序的設(shè)計(jì)模式

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲?。篽ttps://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目標(biāo) 理解裸機(jī)程序設(shè)

    2024年02月09日
    瀏覽(20)
  • 第26章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之獨(dú)立看門(mén)狗定時(shí)器-IWDT

    第26章_瑞薩MCU零基礎(chǔ)入門(mén)系列教程之獨(dú)立看門(mén)狗定時(shí)器-IWDT

    本教程基于韋東山百問(wèn)網(wǎng)出的 DShanMCU-RA6M5開(kāi)發(fā)板 進(jìn)行編寫(xiě),需要的同學(xué)可以在這里獲?。?https://item.taobao.com/item.htm?id=728461040949 配套資料獲取:https://renesas-docs.100ask.net 瑞薩MCU零基礎(chǔ)入門(mén)系列教程匯總 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目標(biāo) 了解A6M5處理器的

    2024年02月08日
    瀏覽(50)
  • 瑞薩MCU入門(mén)教程(非常詳細(xì)的瑞薩單片機(jī)入門(mén)教程)

    瑞薩MCU入門(mén)教程(非常詳細(xì)的瑞薩單片機(jī)入門(mén)教程)

    得益于瑞薩強(qiáng)大的MCU、強(qiáng)大的軟件開(kāi)發(fā)工具(e2 studio),也得益于瑞薩和RA生態(tài)工作室提供的支持,我們團(tuán)隊(duì)編寫(xiě)了《ARM嵌入式系統(tǒng)中面向?qū)ο蟮哪K編程方法》,全書(shū)37章,將近500頁(yè): 講解面向?qū)ο缶幊淘趩纹瑱C(jī)開(kāi)發(fā)中的使用 結(jié)合FSP軟件包實(shí)例分析外設(shè)驅(qū)動(dòng) 講解如何使用RASC配

    2024年02月08日
    瀏覽(48)
  • WPF入門(mén)教程系列一——基礎(chǔ)

    WPF入門(mén)教程系列一——基礎(chǔ)

    一、?前言?? ?? ????? 最近在學(xué)習(xí)WPF,學(xué)習(xí)WPF首先上的是微軟的MSDN,然后再搜索了一下網(wǎng)絡(luò)有關(guān)WPF的學(xué)習(xí)資料。為了溫故而知新把學(xué)習(xí)過(guò)程記錄下來(lái),以備后查。這篇主要講WPF的開(kāi)發(fā)基礎(chǔ),介紹了如何使用Visual?Studio?2013創(chuàng)建一個(gè)WPF應(yīng)用程序。 首先說(shuō)一下學(xué)習(xí)WPF的基礎(chǔ)知

    2024年02月07日
    瀏覽(32)
  • 【虛幻引擎】UE4初學(xué)者系列教程基礎(chǔ)篇-全中文新手入門(mén)教程

    【虛幻引擎】UE4初學(xué)者系列教程基礎(chǔ)篇-全中文新手入門(mén)教程

    一、 創(chuàng)建工程文件 (1)虛擬項(xiàng)目瀏覽器 (2)虛擬文件夾的結(jié)構(gòu) (3)?初學(xué)者內(nèi)容包 二、虛幻引擎編輯界面介紹 (1)菜單欄 (2)關(guān)卡編輯器:工具欄 ?(3)“模式”面板 ?(4)“內(nèi)容瀏覽器”面板 (5)視口面板 (6)?世界大綱視圖 (7)細(xì)節(jié)面板 三、視口導(dǎo)航 四、

    2024年02月04日
    瀏覽(93)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包