搜索
bottom↓
回复: 14

Software PWM

[复制链接]

出0入0汤圆

发表于 2009-11-23 00:29:56 | 显示全部楼层 |阅读模式
many people working with multi-color LEDs utilize PWM to control LED light intensity, and color combinations when multi-color LEDs are utilized.

here is an example of utilizing PIC and firmware to create PWM on 3 channels.

The chip used is a 12F675 (8pdip), it is written to drive 3 channels of independent PWM output, 256 stepping. Each channel is programmed for its own duty cycle that varies with time / channel. The intensity (duty cycle) for example channel goes up or down by the stepping. the duty cycle goes up and then down, to create smooth lighting / color transitions.

it can be easily adapted to drive more channels, with different stepping, or on different mcus.

enjoy.

======code, in picc===============
#include <htc.h>

#define PWM_PORT        GPIO                        //LED on GPIO
#define Max_Tick        0x7f                        //max number of steps
#define Max_Ch                3                                //number of pwm channels
#define PWM_SET(x)        PWM_PORT |= (x)        //turn on xth bit
#define PWM_CLR(x)        PWM_PORT &=~(x)        //turn off xth bit
#define PWM_FLP(x)        PWM_PORT ^= (x)        //flip xth bit

__CONFIG(MCLRDIS & WDTDIS & BORDIS & INTIO);

typedef struct {
        unsigned char ch;                                //PWM pin/ch
        unsigned char on;                                //on tick
        char stepping;                                        //increment to on;
} PWM_type;

PWM_type PWM_Info[Max_Ch]={
        {1<<0, 0x2d, 10},
        {1<<2, 0x10, 20},
        {1<<1, 0x11, -3}};

unsigned char PWM_Ch_mask=0;
       
void mcu_init(void) {
        unsigned char i;
        ANSEL=0x00;                                                //turn off analog input
        CMCON=0x07;                                                //turn off comparators
        for (i=0; i<Max_Ch; i++)
                PWM_Ch_mask |= PWM_Info.ch;
        TRISIO &= ~PWM_Ch_mask;
}
       
void PWM_Update_Stepping(void) {
        unsigned char ch;
        signed char tmp;
       
        for (ch=0; ch<Max_Ch; ch++) {
                tmp=PWM_Info[ch].on + PWM_Info[ch].stepping;
                if (PWM_Info[ch].stepping > 0)                 //stepping > 0
                        if (tmp > Max_Tick) PWM_Info[ch].stepping = - PWM_Info[ch].stepping;        //reverse stepping direction;
                else                                                                 //stepping < 0
                        if (tmp < 0) PWM_Info[ch].stepping = - PWM_Info[ch].stepping;        //reverse stepping direction;
                PWM_Info[ch].on += PWM_Info[ch].stepping;
        }
}
                       
void
main(void)
{
        unsigned char ch, tick, mask;

        mcu_init();
        TRIS5=0; GPIO5=0;                                //GPIO5 set up as cycle indicator
        while (1){
                //TODO Auto-generated main function
                PWM_PORT=PWM_Ch_mask;
                for (tick=0; tick<Max_Tick; tick++) {
                        for (mask=0x00, ch=0; ch<Max_Ch; ch++)                                        //reset mask, and check for bits to be turned off
                                mask |= (tick==PWM_Info[ch].on)? PWM_Info[ch].ch:0;                //identify the bit to be turned off
                        //mask = (tick==PWM_Info[0].on)? PWM_Info[0].ch:0 + (tick==PWM_Info[1].on)? PWM_Info[1].ch:0 + (tick==PWM_Info[2].on)? PWM_Info[2].ch:0;
                        PWM_PORT ^= mask;
                }
                PWM_Update_Stepping();
                GPIO5 ^= 1;                                        //flip gpio5

        }
}


(原文件名:12F675 LEDs PWM v2.PNG)

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-12-9 01:31:20 | 显示全部楼层
Very good example!
Thank you for your sharing^_^

出0入0汤圆

发表于 2009-12-9 21:19:49 | 显示全部楼层
millwood0, which C compiler you are dealing with the PIC12F675?  Does it have large enough RAM and stack size to support programming in C language?

And, why PIC?  Isn't the ATTiny more cost effective or C optimized?

出0入0汤圆

 楼主| 发表于 2009-12-10 07:52:46 | 显示全部楼层
I use picc for it. this particular code takes ~5 of total code space on a 12F675, and runs flwlessly.

why pic? i picked up a book to read about mcu and it happened to be about pic.

出0入0汤圆

发表于 2009-12-10 12:50:11 | 显示全部楼层
I though PIC12 series only supports programming in native assemblem language. Thanks for your info.

出0入0汤圆

发表于 2009-12-10 17:50:53 | 显示全部楼层
好难看懂

出0入296汤圆

发表于 2009-12-13 12:04:37 | 显示全部楼层
Hi millwood0

I notice that your coding style is quite nature. Here is my suggestion:
a. DO NOT ignore any "{}" for if / for / while statement
b. Try to add some indents to each line.

出0入0汤圆

发表于 2010-9-15 22:21:29 | 显示全部楼层
Why don't use the timer in your program? I see many software PWM code,like the 80C51 family MCU(with no PWM function ),they used at least one timer? how to control the frequence and time accurately?

出0入0汤圆

发表于 2010-11-1 17:38:28 | 显示全部楼层
----------------------------------------------
█〓██▄▄▄▄▄▄ ●●●  
▄▅██████▅▄▃▂  
██████████████  
◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤

出0入0汤圆

发表于 2010-11-6 19:01:55 | 显示全部楼层
看来学电子的,英语不止我一个人烂。。。。。。。。

出0入0汤圆

发表于 2011-4-20 00:38:37 | 显示全部楼层
millwood0
是老外吗
呵呵Gorgon Meducer 版主都英文打招呼了,我等只能用中文了
我发现一个高手millwood0
发的贴子怎么全是英文
呵呵

出0入0汤圆

发表于 2014-10-7 12:49:41 | 显示全部楼层
PWM_type PWM_Info[Max_Ch]={
        {1<<0, 0x2d, 10},
        {1<<2, 0x10, 20},
        {1<<1, 0x11, -3}};

笔误?

出0入0汤圆

发表于 2014-10-25 00:33:31 | 显示全部楼层
█〓██▄▄▄▄▄▄ ●●●  
▄▅██████▅▄▃▂  
██████████████  
◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 17:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表