pwm

作者: 昨天剩下的一杯冷茶 | 来源:发表于2020-08-05 14:47 被阅读0次
    //pwm.c
    #include <iocc2540.h>
    #include "pwm.h"
    
    
    
    
    //pwm pins:
    //P0_3:R  (TX)--ch1
    //P0_4:G  (CTS)--ch2
    //P0_5:B  (RTS)--ch3
    static uint16 gRed =1;
    static uint16 gGreen =1;
    static uint16 gBlue =1;
    
    
    
    void PWM_Init()
    {
        //设置pwm端口为输出
        P0DIR|= BV(3)|BV(4)|BV(5);
        //设置pwm端口为外设端口,非gpio
        P0SEL|= BV(3)|BV(4)|BV(5);
        //由于uart等会占用我们当前使用的pwm端口,因此需要将uart等重映射到别的端口去。
        PERCFG |= 0x03;             // Move USART1&2 to alternate2 location so that T1 is visible
    
        // Initialize Timer 1
        T1CTL = 0x0C;               // Div = 128, CLR, MODE = Suspended
        T1CCTL1 = 0x0C;             // IM = 0; CMP = Clear output on compare; Mode = Compare
        T1CCTL2 = 0x0C;             // IM = 0; CMP = Clear output on compare; Mode = Compare
        T1CCTL3 = 0x0C;             // IM = 0, CMP = Clear output on compare; Mode = Compare
        T1CNTL = 0;                 // Reset timer to 0;
    
        //必须设置,否则定时器不工作
        T1CCTL0 = 0x4C;            // IM = 1, CMP = Clear output on compare; Mode = Compare
    
        //设置周期的tick为375, 也就是1.5ms
    #if 1
        T1CC0H = 0x01;              // Ticks = 375 (1.5ms initial duty cycle)
        T1CC0L = 0x77;              //
        T1CC1H = 0x01;              // Ticks = 375 (1.5ms initial duty cycle)
        T1CC1L = 0x77;
        T1CC2H = 0x01;              // Ticks = 375 (1.5ms initial duty cycle)
        T1CC2L = 0x77;
        T1CC3H = 0x01;              // Ticks = 375 (1.5ms initial duty cycle)
        T1CC3L = 0x77;
    #else//以下设置会是1khz
    #define VALUE_H     0x00
    #define VALUE_L     0x10
        T1CC0H = VALUE_H;
        T1CC0L = VALUE_L;
        T1CC1H = VALUE_H;
        T1CC1L = VALUE_L;
        T1CC2H = VALUE_H;
        T1CC2L = VALUE_L;
        T1CC3H = VALUE_H;
        T1CC3L = VALUE_L;
    #endif
    
        EA=1;
        IEN1 |= 0x02;               // Enable T1 cpu interrupt
    }
    
    //red, green, blue 的值必须是 1~375, 其他值无效
    void PWM_Pulse(uint16 red, uint16 green, uint16 blue)
    {
        uint16 r,g,b;
    
        // stop,注意,不能加这句,加了周期偏差十几倍,具体原因未查明
        //T1CTL &= BV(0)|BV(1);
        r=red;
        g=green;
        b=blue;
        // Set up the timer registers
    
        T1CC1L = (uint8)r;
        T1CC1H = (uint8)(r >> 8);
        //避免比较值为0时,输出一直为高
        if(r!=0)
        {
            T1CCTL1 = 0x0C;
        } else
        {
            T1CCTL1 = 0x00;
        }
        T1CC2L = (uint8)g;
        T1CC2H = (uint8)(g >> 8);
        if(g!=0)
        {
            T1CCTL2 = 0x0C;
        } else
        {
            T1CCTL2 = 0x00;
        }
        T1CC3L = (uint8)b;
        T1CC3H = (uint8)(b >> 8);
        if(b!=0)
        {
            T1CCTL3 = 0x0C;
        } else
        {
            T1CCTL3 = 0x00;
        }
    
        // Reset timer
        T1CNTL = 0;
        // Start timer in modulo mode.
        T1CTL |= 0x02;
    }
    
    //red, green, blue 的值必须是 1~375, 其他值无效
    void PWM_RGB(uint16 red, uint16 green, uint16 blue)
    {
        gRed=red;
        gGreen=green;
        gBlue=blue;
    }
    
    //#pragma register_bank=2
    #pragma vector = T1_VECTOR
    __interrupt void pwmISR (void)
    {
        uint8 flags = T1STAT;
        // T1 ch 0
        if (flags & 0x01)
        {
            // Stop Timer 1
            //T1CTL |= 0x02;
            //red, green, blue 的值必须是 1~375, 其他值无效
            PWM_Pulse(gRed,gGreen,gBlue);
        }
        T1STAT = ~ flags;
    }
    
    //pwm.h
    #ifndef __PWM_H__
    #define __PWM_H__
    
    #include <iocc2540.h>
    
    
    #define uint8 unsigned char
    #define uint16 unsigned short
    #define BV(n)      (1 << (n))
    
    
    
    void PWM_Init();
    void PWM_Pulse(uint16 red, uint16 green, uint16 blue);
    void PWM_RGB(uint16 red, uint16 green, uint16 blue);
    
    
    
    #endif
    
    
    
    
    //main.c
    #include "pwm.h"
    
    //(375/2)--------305.8-3.2-48.8
    //(375)----------305.8-3.2-97.8
    //(375*100/10)---
    #define R_CYCLE (375/2)
    #define G_CYCLE (375/2)
    #define B_CYCLE (375/2)
    void init_clock(void)
    {
        CLKCONCMD &= ~0x40;              //设置系统时钟源为 32MHZ晶振
        while(CLKCONSTA & 0x40);         //等待晶振稳定
        CLKCONCMD &= ~0x47;              //设置系统主时钟频率为 32MHZ
    }
    void main(void)
    {
    
        IEN0 = IEN1 = IEN2 = 0x00;
    
        init_clock();
        PWM_Init();
        PWM_RGB(R_CYCLE,G_CYCLE,B_CYCLE);
        PWM_Pulse(R_CYCLE,G_CYCLE,B_CYCLE);
        
        while(1)
        {
    
        }
    }
    
    
    
    
    
    

    教程的测试结果是周期是1.5MS,但是本人测试周期是3MS。不知道本人哪里弄错。

    测试结果:


    image.png

    相关文章

      网友评论

          本文标题:pwm

          本文链接:https://www.haomeiwen.com/subject/pttorktx.html