xiyue521 发表于 2021-7-21 02:33

平头哥RVB2601测评:点亮你的LED——GPIO与PWM、及PWM的疑问

本帖最后由 xiyue521 于 2021-7-21 02:38 编辑

<p style="margin-top:19px; margin-bottom:19px; text-align:justify"><span style="font-size:26px;"><strong>一、点亮你的RGB灯:</strong></span></p>

<h5><strong><span style="font-size:20px;">从原理图看出LED低电平亮:我们可以用通用IO口点亮还可以将GPIO复用为PWM来实现呼吸灯的效果。</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<h5><strong><span style="font-size:20px;">&nbsp;</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<h5><strong><span style="font-size:20px;">①GPIO方式: (以PA7为例) &nbsp;</span></strong></h5>

<pre>
<code>//设置引脚模式为通用IO口:
 csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
//引脚初始化:
 csi_gpio_pin_init(&amp;r, PA7);
//设置引脚输出方向:
csi_gpio_pin_dir(&amp;r, GPIO_DIRECTION_OUTPUT);
//设置引脚电平:
 csi_gpio_pin_write(&amp;r, GPIO_PIN_LOW);</code></pre>

<h5><strong><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;了解完主要的API后我们在主函数创建一个led任务,在任务重初始化,接着每1000ms调用led样式刷新函数(也就是一秒切换一个led颜色).</span></strong></h5>

<pre>
<code class="language-cpp">
int main(void)
{
    board_yoc_init();
    aos_task_new("demo", demo_task, NULL, 10 * 1024);
    aos_task_new("led_task", led_task, NULL, 1 * 1024);
    return 0;
}

static void led_task(void *arg)
{
    led_pinmux_init();
    while(1)
        {
          aos_msleep(1000);
          led_refresh();
        }
}
void led_refresh()
{
    g_ctr++;
    if(g_ctr  == 3)
        g_ctr = 0;
    if(g_ctr  == 0)
        {
          csi_gpio_pin_write(&amp;r, GPIO_PIN_HIGH);
          csi_gpio_pin_write(&amp;g, GPIO_PIN_HIGH);
          csi_gpio_pin_write(&amp;b, GPIO_PIN_LOW);
        }

    else if(g_ctr == 1)
        {
           csi_gpio_pin_write(&amp;r, GPIO_PIN_LOW);
           csi_gpio_pin_write(&amp;g, GPIO_PIN_HIGH);
           csi_gpio_pin_write(&amp;b, GPIO_PIN_HIGH);
        }
    else
        {
          csi_gpio_pin_write(&amp;r, GPIO_PIN_HIGH);
          csi_gpio_pin_write(&amp;g, GPIO_PIN_LOW);
          csi_gpio_pin_write(&amp;b, GPIO_PIN_HIGH);
        }
}
</code></pre>

<p>&nbsp;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p>&nbsp;</p>

<h5><strong><span style="font-size:20px;">②PWM方式:</span></strong></h5>

<pre>
<code class="language-cpp">//设置引脚功能复用为PWM模式:
csi_pin_set_mux(PA7, PA7_PWM_CH7);

//初始化PWM:
csi_pwm_init(&amp;r, 0);

//配置PWM周期、有效电平时间和有效电平极性:
    csi_pwm_out_config(&amp;r, 7 / 2, 300, 100, PWM_POLARITY_HIGH);

//使能PWM
 csi_pwm_out_start(&amp;r, 7 / 2);</code></pre>

<h5><strong><span style="font-size:20px;">用逻辑分析仪测出来占空比差不多为100/300即33.3%</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<h5><strong><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;然后我们在main函数依然创建一个led任务,led刷新函数里没5ms对g_ctr++或--,取决于dir值,dir就要用到刚刚的控制台用户自定义命令了,在控制台对dir值修改可以改变呼吸灯的变亮或变暗。</span></strong></h5>

<pre>
<code class="language-cpp">static void led_task(void *arg)
{
        led_pinmux_init();
        while(1)
    {
            aos_msleep(5);
            led_refresh();
    }
}
void led_pinmux_init()
{
        // 7

    csi_error_t ret;
        csi_pin_set_mux(PA7, PA7_PWM_CH7);
        csi_pin_set_mux(PA25, PA25_PWM_CH2);
        csi_pin_set_mux(PA4, PA4_PWM_CH4);
        ret = csi_pwm_init(&amp;r, 0);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        ret = csi_pwm_out_config(&amp;r, 7 / 2, 300, 100, PWM_POLARITY_HIGH);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        ret = csi_pwm_out_start(&amp;r, 7 / 2);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        // 25

    ret = csi_pwm_out_config(&amp;r, 2 / 2, 300, 100, PWM_POLARITY_HIGH);
        if(ret != CSI_OK)

    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        ret = csi_pwm_out_start(&amp;r, 2 / 2);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        // 4
    ret = csi_pwm_out_config(&amp;r, 4 / 2, 300, 100, PWM_POLARITY_HIGH);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
        ret = csi_pwm_out_start(&amp;r, 4 / 2);
        if(ret != CSI_OK)
    {
            printf("===%s, %d\n", __FUNCTION__, __LINE__);
            return;
    }
         csi_pwm_out_stop(&amp;r, 2 / 2);
         csi_pwm_out_stop(&amp;r, 7 / 2);
}

/***************************/
void led_refresh()
{
        switch(dir)
    {
    case 0:
            g_ctr++;
            if(g_ctr == 300)
        {
              g_ctr = 0;
        }
        csi_pwm_out_config(&amp;r, 1, 300, g_ctr, PWM_POLARITY_HIGH);
        break;
    case 1:
        g_ctr--;

        if(g_ctr == 0)
          {
                    g_ctr = 300;
          }
        csi_pwm_out_config(&amp;r, 1, 300, g_ctr, PWM_POLARITY_HIGH);
         break;
    default:
        g_ctr++;
        if(g_ctr == 300)

          {
                    g_ctr = 0;
          }

        csi_pwm_out_config(&amp;r, 1, 300, g_ctr, PWM_POLARITY_HIGH);
         break;
    }
}

/*****************/
void mycmd_func(char *wbuf, int wbuf_len, int argc, char **argv)
{
        extern uint dir;
         dir = atoi(argv);
}</code></pre>

<p class="imagemiddle" style="text-align: center;"></p>

<p>&nbsp;</p>

<h5><strong><span style="font-size:20px;">可以看到输入test 0时亮度逐渐变暗,test 1反之。</span></strong></h5>

<p><span style="font-size:26px;"><strong>二、舵机:</strong></span></p>

<p><strong><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;就是利用PWM设置周期为20ms=20000us,根据占空比的大小舵机改变角度。</span></strong></p>

<pre>
<code class="language-cpp">void mycmd_func(char *wbuf, int wbuf_len, int argc, char **argv)
{
   csi_pwm_out_config(&amp;r, 4 / 2, 20000, atoi(argv), PWM_POLARITY_HIGH);
       
}</code></pre>

<p></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;在命令行改变高电平的时间,在500us-2500us之间对应0-180&deg;,1500us是90&deg;的位置。</span></strong></p>

<p><span style="font-size:26px;"><strong>三、</strong><strong>关于PWM几点疑惑:</strong></span></p>

<h5><strong><span style="font-size:20px;">在设置PWM的配置时用的是:</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<h5><strong><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;其中4/2的4是通道4,但是不知道为什么要/2,这么说的话,4/2和5/2效果应该是一样的(结果都是整形2),也就是说通道5如果配置为PWM输出的话,那这两个引脚就是一模一样的了,查看手册发现有4个引脚为CH4,5:我们全部配置为PWM 模式:</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<h5><strong><span style="font-size:20px;">&nbsp;</span></strong></h5>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<h5><strong><span style="font-size:20px;">接上逻辑分析仪:</span></strong></h5>

<p>&nbsp;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p><strong><span style="font-size:20px;">&nbsp;</span></strong></p>

<h5><strong><span style="font-size:20px;">结果真的一模一样,周期占空比都是一样的,哎就很奇怪,不知道哪的问题。。。或是SDK的问题。</span></strong></h5>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

w494143467 发表于 2021-7-21 11:15

<p>看到逻辑分析仪的界面,我就知道你用的是哪个厂家的了~</p>

xiyue521 发表于 2021-7-21 12:27

w494143467 发表于 2021-7-21 11:15
看到逻辑分析仪的界面,我就知道你用的是哪个厂家的了~

<p>哈哈最便宜的哪款<img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan21.gif" width="63" /></p>

freebsder 发表于 2021-7-21 17:55

<p>有点意思,谢谢分享!</p>

xiyue521 发表于 2021-7-21 20:35

<p>但就是想不懂为什么通道一模一样</p>

littleshrimp 发表于 2021-9-2 20:55

<p>PWM的例程是在哪找到的?</p>

littleshrimp 发表于 2021-9-2 20:57

<p>这是csi_pwm_out_config函数的官方介绍</p>

<p> &nbsp;</p>

<p>https://occ.t-head.cn/document?temp=PWM&amp;slug=csi</p>
页: [1]
查看完整版本: 平头哥RVB2601测评:点亮你的LED——GPIO与PWM、及PWM的疑问