查看: 2320|回复: 0

[原创] MX6ULL PWM背板光调节实验笔记

[复制链接]
  • TA的每日心情
    慵懒
    2020-1-19 10:06
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2020-3-30 09:55:17 | 显示全部楼层 |阅读模式
    分享到:
    众所周知,PWM输出在我们的工程应用中是一个十分基础的模块,具有很强大的功用。在正点原子的官方教程中,也有专门的实验来进行教学。下面,我将将把实验过程中的笔记和我的个人的一些想法分享给大家。
    一、PWM简介
            1、6ULLPWM16位计数器,
            2、有4个16位的FIFO。
            3、一个12位的分频器
            4、正点原子LCD屏幕的背光IO连接到了GPIO1_IO08上。GPIO1_IO08可以复用位PWM1_OUT信号。
            PWM计数器从0X0000开始计数,当计数器的值等于PWMPR+1的时候定时器就会重新开始下一个周期的运行,因此PWMPR寄存器控制着PWM频率。
            FIFO保存着采样值,当我们向PWMSAR寄存器写采样值的时候会写道FIFO里面,内每当读取一次PWMSAR寄存器,FIFO里面的数据都会减一,或者每产生一个PWM信号,FIFO的数据也会减一。直到FIFO为空,那么就无法再产生PWM信号。FIFO为空的时候会产生中断,我们可以在中断中向FIFO写入采样数据,也就是向PWMSAR写数据。
            PWMCR寄存器,bit0是PWM使能信号,bit2:1设置为0,每个周期使用FIFO里面的一个数据。Bit15:4PWM分频设置,可以设置0~4095,对应1~4096分频。Bit17:16设置PWM时钟源,设置为1,表示使用ipg_clk=66MHzbit19:18,设置为0。Bit2726,设置为01,表示当FIFO里面空余位置大于2的时候FIFO为空。
            PWMIR寄存器,bit0设置为1,开启FIFO空中断。
    二、实验程序编写
    #include "bsp_backlight.h"
    #include "bsp_int.h"
    struct backlight_dev_struc backlight_dev;
    /* 初始化背光 */
    void backlight_init(void)
    {
        unsigned char i = 0;
        /* 1、IO初始化 */
        IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_PWM1_OUT , 0); /*复用为PWM1_OUT */
        IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_PWM1_OUT , 0Xb090);
        /* 2、PWM初始化
         * PWM时钟源=66MHz,设置66分频,因此PWM时钟频率为1MHz
         *
         */
        PWM1->PWMCR = 0;    /* 清零 */
        PWM1->PWMCR |= (1 << 16) | (65 << 4) | (1 << 26);
        pwm1_setperiod_value(1000);  /* PWM频率为1Khz */
        /* 3、设置默认站空比 */   
        backlight_dev.pwm_duty = 50;
        for(i = 0; i < 4; i++)
        {
            pwm1_setduty(backlight_dev.pwm_duty);
        }
        /*4、使能FIFO空中断  */
        PWM1->PWMIR = 1 << 0;   /* 使能PWM1的FIFO空中断 */
        GIC_EnableIRQ(PWM1_IRQn);
        system_register_irqhandler(PWM1_IRQn, (system_irq_handler_t)pwm1_irqhandler, NULL);
        PWM1->PWMSR = 0xff;
        /* 5、打开PWM */
        PWM1->PWMCR |= 1 << 0;
    }
    /* 设置PR寄存器 */
    void pwm1_setperiod_value(unsigned int value)
    {
        unsigned int regvalue = 0;
        if(value < 2)
            regvalue = 2;
        else
            regvalue = value - 2;
        PWM1->PWMPR = (regvalue & 0XFFFF);
    }
    /* 设置站空比duty=0~100 */
    void pwm1_setduty(unsigned char duty)
    {
        unsigned short period = 0;
        unsigned short sample = 0;
        backlight_dev.pwm_duty = duty;
        period = PWM1->PWMPR + 2;
        sample = (unsigned short)(period * backlight_dev.pwm_duty / 100.0f);
        PWM1->PWMSAR = (sample & 0xffff);
    }
    /* 中断处理函数 */
    void pwm1_irqhandler(unsigned int gicciar, void *param)
    {
        if(PWM1->PWMSR & (1 << 3)) /* FIFO空中断 */
        {
            pwm1_setduty(backlight_dev.pwm_duty);
            PWM1->PWMSR |= 1 << 3;  /* 中断标志位清零 */
        }
    }
           
           
    Main.c
    #include "main.h"
    #include "bsp_clk.h"
    #include "bsp_led.h"
    #include "bsp_delay.h"
    #include "bsp_beep.h"
    #include "bsp_key.h"
    #include "bsp_int.h"
    #include "bsp_exti.h"
    #include "bsp_epit.h"
    #include "bsp_keyfilter.h"
    #include "bsp_uart.h"
    #include "bsp_lcd.h"
    #include "bsp_rtc.h"
    #include "bsp_lcdapi.h"
    #include "bsp_ap3216c.h"
    #include "bsp_icm20608.h"
    #include "bsp_ft5426.h"
    #include "bsp_backlight.h"
    #include "stdio.h"
    /*
    * @description : 使能I.MX6U的硬件NEON和FPU
    * @param       : 无
    * @return      : 无
    */
    void imx6ul_hardfpu_enable(void)
    {
        uint32_t cpacr;
        uint32_t fpexc;
        /* 使能NEON和FPU */
        cpacr = __get_CPACR();
        cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
               |  (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
        __set_CPACR(cpacr);
        fpexc = __get_FPEXC();
        fpexc |= 0x40000000UL;  
        __set_FPEXC(fpexc);
    }
    int main(void)
    {
        unsigned char duty;
        unsigned char key = 0;
        unsigned char i = 0;
        unsigned char state = OFF;
        imx6ul_hardfpu_enable(); /* 开启硬件浮点运算及ENON */
       
        int_init();         /* 初始化中断 */
        imx6u_clkinit();    /* 初始化系统时钟 */
        delay_init();       /* 延时初始化 */
        uart_init();        /* 初始化串口 */
        clk_enable();       /* 使能外设时钟 */
        led_init();         /* 初始化LED */
        beep_init();        /* 初始化奉命器 */
        key_init();         /* 初始化按键 */
        lcd_init();         /* 初始化LCD */
        backlight_init();       /* 初始化背光*/
        tftlcd_dev.forecolor = LCD_RED;
        lcd_show_string(50, 10, 400, 24, 24, (char*)"IMX6U-ZERO BACKLIGHT TEST");  
        lcd_show_string(50, 40, 200, 16, 16, (char*)"BACKLIGHT TEST");  
        lcd_show_string(50, 60, 200, 16, 16, (char*)"ATOM@ALIENTEK");  
        lcd_show_string(50, 80, 200, 16, 16, (char*)"2019/3/27");  
        duty = 10;
        pwm1_setduty(duty);
        while(1)
        {   
            key = key_getvalue();
            if(key == KEY0_VALUE) {
                duty += 10;
                if(duty > 100)
                    duty = 0;
                printf("PWM1 Duty = %d\r\n", duty);
                pwm1_setduty(duty);
            }
            delay_ms(10);
            i++;
       
            if(i == 50)
            {   
                i = 0;
                state = !state;
                led_switch(LED0,state);
            }
        }
        return 0;
    }

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-3-29 03:47 , Processed in 0.106886 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.