OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5349|回复: 1

关于软件模拟PWM的实现,以LED的渐明渐暗为例子

[复制链接]

20

主题

158

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
334
金钱
334
注册时间
2012-8-21
在线时间
27 小时
发表于 2013-12-30 16:33:00 | 显示全部楼层 |阅读模式
1,首先在实现渐明渐暗的时候,如果是多个LED的时候
   在MCU IO的选择的时候,最好是一个端口上的

2,在编写代码之前,首先将LED的渐明渐暗的所有情形分析,需求
定义好,PWM的等级,分多少等级
#define c_SlowShowPWMStepNum 128 //128个等级
比如,首先LED1,LED2,LED3,同时渐明渐暗,
然后,LED2,LED3,渐明渐暗
然后,LED1渐明渐暗,
然后LED,3,5,6,等等,对于这种无序的排列的时候
针对这种,那么在编写程序架构的时候,要考虑使用表格的思维
首先定义所使用的LED 在IO端口上的位
如下:
#define c_LedNum 8
#define c_AllLedOff 0
#define c_Led1 0x0001
#define c_Led2 0x0002
#define c_Led3 0x0004
#define c_Led4 0x0008
#define c_Led5 0x0010
#define c_Led6 0x0020
#define c_Led7 0x0040
#define c_Led8 0x0080
在定义好LED 的IO位之后,再根据渐明渐暗的不同需求建立表格
如下

const static unsigned int T_LedSlowShow[]=                     
{                                                              
c_Led1+c_Led2, //LED1,LED2同时渐明渐暗                                              
c_Led3+c_Led4,                                               
c_Led5+c_Led6,                                               
c_Led1+c_Led2+c_Led3,                                        
c_Led4+c_Led5+c_Led6,                                        
c_Led1+c_Led2+c_Led3+c_Led4+c_Led5+c_Led6,                   
c_Led3+c_Led4,                                               
c_Led2+c_Led3+c_Led4+c_Led5,                                 
c_Led1+c_Led6,                                               
c_Led2+c_Led5,                                               
c_Led3+c_Led4,                                           
c_Led1+c_Led2+c_Led4,                                        
c_Led3+c_Led5+c_Led6,                                        
c_Led1+c_Led3+c_Led4,                                        
c_Led2+c_Led5+c_Led6,                                        
}; 
//这样做的好处,可以同时几个LED同时渐明渐暗,而且好修改,维护

在定义好IO和建立表格之后,再建立三个函数
void LEDSlowShowInit(void)  ,//渐明渐暗使能
void LEDSlowShowUnInit(void)  ,//渐明渐暗,关闭
void LED_SlowShowProcess(void)  ,//渐明渐暗主程序

LEDSlowShowInit:
这个函数主要实现的内容是
1 使能渐明渐暗,标志
2 设置LED的方向,是从暗到明亮还是,从明亮到暗
3 初始化PWM控制变量
LEDSlowShowUnInit
关闭渐明渐暗功能


void LED_SlowShowProcess(void)                                 
{                                                              
unsigned int tempi, ledno;                                   
                                                            
if(gFlag_Sys & c_LedSlowShowFlag) //这里判断渐明渐暗,是否使能                           
{                                                            
if(gLedSlowShowPWMTmp++ >= c_SlowShowPWMStepNum) //判断是否到最大等级          
{                                                          
gLedSlowShowPWMTmp = 0; //重置计数器                                 
if(gLedSlowShowFlag & c_LedSlowShowUp)  //从暗到亮                 
{                                                       
if(gLedSlowShowStep < c_SlowShowPWMStepNum)            
gLedSlowShowStep++;                                  
else                                                   
gLedSlowShowFlag &= ~c_LedSlowShowUp;                
}                                                        
else                                                     
{                                                        
if(gLedSlowShowStep)                                   
gLedSlowShowStep--;                                  
else                                                   
{                                                      
gLedSlowShowFlag |= c_LedSlowShowUp;                 
gLedSlowShowPtr++;                                   
if(gLedSlowShowPtr >= sizeof(T_LedSlowShow))         
gLedSlowShowPtr = 0;                               
}                                           
}                                                        
}                                                          
else                                                       
{                                                          
Port_IO_Config(c_LEDPort,  0, 5, C_Port_OH); //LED OFF
if(gLedSlowShowPWMTmp <= gLedSlowShowStep)               
{                                                        
*P_IOB_Buffer &= ~T_LedSlowShow[gLedSlowShowPtr];      
}                                                        
}                                                          
}                                                            
}  

主要思想:
1 明确需求,分析PWM等级
2 对于要操作的PWM IO,进行合理分配
3 对于不同的需求,最好使用表格思维,和宏定义思维,方便程序修改和维护


























正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-12-30 22:57:10 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-14 08:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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