1 【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出 - 单片机/MCU论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛 - 德赢Vwin官网
单片机/MCU论坛
直播中

jf_05441697

1年用户 24经验值
擅长:可编程逻辑 嵌入式技术 接口/总线/驱动 控制/MCU
私信 关注

【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出

PWM输出配置

第一步 -- 时钟

使用PWM输出必不可少的就是查看时钟源从而设置定时器计数值

首先,可以通过数据手册查到GPT的时钟源是由PCLKD进行分频得来的,所以配置时需要注意下PCLKD的配置

image.png

image.png

图中配置的PCLKD为64MHz(待会要用)

第二步 -- 引脚

时钟配置完成之后,就需要配置引脚,我选用的GTP0_GPTOC0A,即P213
image.png

第三步 -- 栈配置(个人感觉叫外设配置更好)

image.png

image.png

主要配置的就是:

通道、周期、占空比以及模式
image.png

不要忘记了将输出使能打开

这样输出方波的PWM就算配置完成了,由于没有示波器,所以选择结合ADC来一起演示

ADC输入配置

第一步 -- 时钟

ADC的时钟和PWM一样,都是使用的PCLKD,手册上还说其高达13个输入通道(说实话,我感觉不多),结果12bit(算中规中矩吧)

image.png

第二步 -- 引脚配置

和其他都一样,正常勾选上相应功能即可

image.png

第三步 -- 外设配置

image.png

image.png

主要配置的有:

对齐方式、扫描模式,还有通道勾选上,其他感觉没啥需要配置的,最后将中断打开即可。

代码

void adc0_intrruput_callback( adc_callback_args_t* p_args )
{
    switch ( p_args->event )
    {
        case ADC_EVENT_SCAN_COMPLETE:
            adc_event_scan_complete = true;
            break;

        default:
            break;
    }
}
/*********************************************************************************************************************
 * main() is generated by the RA Configuration editor and is used to generate
 * threads if an RTOS is used.  This function is called by main() when no RTOS
 *is used.
 **********************************************************************************************************************/
void hal_entry( void )
{
    uint16_t     voltage        = 0;
    uint16_t     freq           = 1000;
    uint8_t      show_str[ 20 ] = "0.000";
    uint32_t     second         = 0;
    uint32_t     cnt            = 0;
    timer_info_t timer_info;

    /* TODO: add your own code here */
    oled_init();
    uart9_init();
    oled_showStr( 0, 0, 6, "This is a adc test" );
    oled_showStr( 0, 2, 6, "adc voltage:" );
    oled_showStr( 0, 4, 6, "pwm frequency:" );
    oled_showStr( 0, 6, 6, "Running time:" );

    R_ADC_Open( &g_adc0_ctrl, &g_adc0_cfg );
    R_ADC_ScanCfg( &g_adc0_ctrl, &g_adc0_channel_cfg );
    R_ADC_ScanStart( &g_adc0_ctrl );

    R_GPT_Open( &g_timer0_ctrl, &g_timer0_cfg );
    R_GPT_Start( &g_timer0_ctrl );
    R_GPT_PeriodSet( &g_timer0_ctrl, 128000000 );
    
    R_BSP_SoftwareDelay( 100, BSP_DELAY_UNITS_MILLISECONDS );
    while ( 1 )
    {
        if ( adc_event_scan_complete )
        {
            adc_event_scan_complete = false;
            R_ADC_Read( &g_adc0_ctrl, ADC_CHANNEL_0, &voltage );
            sprintf( show_str, "0x%03x", voltage );
            oled_showStr( 12 * 6, 2, 6, show_str );
            R_ADC_ScanStart( &g_adc0_ctrl );
        }
        R_GPT_InfoGet( &g_timer0_ctrl, &timer_info );
        sprintf( show_str, "%d", 64000000000 / timer_info.period_counts );
        oled_showStr( 14 * 6, 4, 6, show_str );
        sprintf( show_str, "%d.%dS", second, cnt % 10 );
        oled_showStr( 13 * 6, 6, 6, show_str );
        cnt++;
        if ( cnt % 10 == 0 )
        {
            second += 1;
            cnt = 0;
        }

        R_BSP_SoftwareDelay( 100, BSP_DELAY_UNITS_MILLISECONDS );
    }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

着重需要注意的就是

R_GPT_PeriodSet( &g_timer0_ctrl, 128000000 );

传入的参数需要结合时钟,前面提到的PCLKD = 64MHz

那么,我想要0.5Hz的输出频率就需要传入128M

同理,输出频率 = 64M / cnt,想要多少就通过公式计算传入即可

我这段代码的效果就是屏幕显示

ADC的采样值

PWM的输出频率*1000(因为我调用sprintf转换float类型一直不成功,最后就放弃了)

运行时间

效果就是,每隔一秒ADC采样值变换依次(不知道为什么PWM输出一直有一点小跳变)
IMG_20241118_205526(1).jpg

video_20241118_205243

更多回帖

发帖
×
20
完善资料,
赚取积分