基于单片机开发版,于步进电机模块PWM控制台灯亮度


通过学习多位大佬的C语言编程控制单片机,今,我基于普中51-单核-A4开发板,利用步进电机模块来控制台灯的灯光亮度。
在这里插入图片描述


2.1 目标:

   ①开发板四个独立按键控制台灯不同亮度(可以调多个档位,可调亮亦可调暗,异步控制两种的灯芯),
   ②开发板数码管显示档位与亮度占空比

2.2 C程序结构:

 ⑴需用模块:
      ①四个独立按键模块
      ②八个数码管模块
      ③定时计数器T0
      ④步进电机模块
  ⑵布局:
      ①主函数——识别独立按键消息+调整(PWM)亮占空比+数码管显示数据信息
     ② 中断函数——依据PWM周期和高电平(亮)占比控制台灯两个灯芯的亮度,赋定时计数器T0初值达到理想的PWM工作范围。(在极高速的亮灭变化下,肉眼无法感觉灯的闪烁,而一个周期内高电平所占宽度就决定灯的亮度)。

Ⅲ C程序:
3.1-1〈main文件〉头文件+变量

    #include <REGX52.H>
   #include "Key.h"      //(普中51-单核-A4开发板)四个独立按键的读取头文件。
   #include "Nixie.h"    //八个数码管显示头文件
   #include "Timer0.h"   //定时计数器T0头文件
   sbit light1=P1^0;
   sbit light2=P1^1;
   #define cycle 20      //设置(灯亮灭)PWM的周期值,周期越大则闪烁越明显(可以通过手机照相机观察到黑条。大于1000时人眼球侧看可以感觉到灯闪烁)
   unsigned int HV[7]={0,1,4,8,12,15,20}; //设置亮宽度比值,总共可以设置7个,即:灯的亮度有七个挡位。
   unsigned char Counter,T1_h,T2_h;	//中断计数,灯1的亮宽,灯2的亮宽
   unsigned char gears,remL1,remL2;  //档位,记灯1前任,记灯2前任
   unsigned int cut;                 //切换灯void 
   LightOFF();   //灯灭的服务函数

3.1-2〈main文件〉主函数

    void main()
    {	
        Timer0_Init();  //启动定时计数器T0,初始化	
        while(1)	
        {   
 /**************** 识别‘按键’并执行 **********************/				
    	 switch(Key())		
          {			
            case 1: gears++;if(gears>=7){gears=0;}; break;  //按键1//加挡位,变亮			
            case 2: if(gears>0){gears--;}; break;           //按键2//减挡位,变暗			
            case 3: LightOFF();break;                       //按键3//零档, 灯灭			
            case 4: cut++;cut%=2;                     //按键4//切换灯(对两盏灯选择)并保持被切换之前的亮度。
                   switch(cut) { case 0: gears=remL1;break;case 1: gears=remL2;break;};break;		
           }    
/****************** 赋值相应的高电平占比 *************************/		
        if(gears<7)		
         {			
            gears%=7;		
        	if(gears==0){switch(cut){ case 0:T1_h=HV[0];break; case 1:T2_h=HV[0]; break;}}	//设置灯亮所占一个周期宽度(改变PWM占空比)			
             if(gears==1){switch(cut){ case 0:T1_h=HV[1];break; case 1:T2_h=HV[1]; break;}}			
            if(gears==2){switch(cut){ case 0:T1_h=HV[2];break; case 1:T2_h=HV[2]; break;}}			
          	if(gears==3){switch(cut){ case 0:T1_h=HV[3];break; case 1:T2_h=HV[3]; break;}}			
            if(gears==4){switch(cut){ case 0:T1_h=HV[4];break; case 1:T2_h=HV[4]; break;}}			
            if(gears==5){switch(cut){ case 0:T1_h=HV[5];break; case 1:T2_h=HV[5]; break;}}			
            if(gears==6){switch(cut){ case 0:T1_h=HV[6];break; case 1:T2_h=HV[6]; break;}}		
         }		    
/****************** 数码管显示 *************************/		
       if(cut==0)		
    	{			
            Nixie(1,cut);           //数码管一:0表灯1、1表灯2			
            Nixie(5,gears);         //数码管五:档位值			
            Nixie(8,(T1_h%100)%10);	//数码管八,七,六:亮度占比值的百,十,个位数。			
            Nixie(7,(T1_h%100)/10);			
            Nixie(6,T1_h/100);			
            remL1=gears;         //当前档位记到‘灯1前任’			
            }		
       else		
         {			
            Nixie(1,cut);			
            Nixie(5,gears);			
            Nixie(8,(T2_h%100)%10);			
            Nixie(7,(T2_h%100)/10);			
            Nixie(6,T2_h/100);			
            remL2=gears;         //当前档位记到‘灯2前任’		
          }	
    }
}

3.1-3〈main文件〉灯灭函数

/**————————2—— 关闭两盏灯,且清除记忆,以便重新点亮灯 ——————————**/
void LightOFF(void)  
{
   T1_h=HV[0];
   T2_h=HV[0];
   gears=0;
   remL1=0;
   remL2=0;
}

3.1-4〈main文件〉中断服务函数

void Timer0_Routine() interrupt 1
{
   TL0 = 0xD0;	   //赋定计器初值  执行中断服务:4uS/次
   TH0 = 0xFF; 	 //赋定计器初值   
   Counter++;
   if(Counter>=cycle) //一个周期值为:cycle
   Counter=0;
   if(Counter<T1_h)  //灯1亮占比值: T1_h
   {
      light1=1;
   }
   else			        //灯1灭占比值: cycle减T1_h
   {
      light1=0;
   }
   if(Counter<T2_h)  //灯2亮占比值: T2_h
   {
      light2=1;
   }
   else			        //灯2灭占比值: cycle减T2_h
   {
   	  light2=0;
   }	
}

3.2-1〈KEY.h〉四个独立按键调用头

#ifndef __KEY_H__
#define __KEY_H__

unsigned char Key();

#endif

3.2-2〈KEY.c〉四独立按键C程序

/*********************************************/
/**对四个独立按键的识别,用到寄存器P3的四个位(P3^0、P3^1、P3^2、P3^3)**/
#include <REGX52.H>

void Delay(unsigned int xms);
/**  * @brief  获取独立按键键码  * @param  无  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0  */
unsigned char Key()
{	
    unsigned char KeyNumber=0;	
    if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}	
    if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
  	if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}	
  	if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}	
  	return KeyNumber;
}

void Delay(unsigned int xms)
{
  unsigned char i, j;
  while(xms--)
  {
	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

}

3.3-1〈NIXIE.h〉数码管显示头

#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char Location,Number);

#endif

3.3-2〈NIXIE.c〉数码管显示C程序,(延时函数略)

/****************************************/
/**八个数码管扫描动态显示,用到寄存器P0和寄存器P2的三个位(P^2、P2^3、P2^4)。
**/
#include <REGX52.H>
#include "Delay.h"
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
/**
 * @brief  数码管显示
 *  * @param  Location 要显示的位置,范围:1~8
 *  * @param  Number 要显示的数字,范围:段码表索引范围
 *  * @retval 无
 *  */
  void Nixie(unsigned char Location,Number)
  {
     switch(Location)		//位码输出
     {
        case 1:P2_4=1;P2_3=1;P2_2=1;break;
        case 2:P2_4=1;P2_3=1;P2_2=0;break;
        case 3:P2_4=1;P2_3=0;P2_2=1;break;
	    case 4:P2_4=1;P2_3=0;P2_2=0;break;
	    case 5:P2_4=0;P2_3=1;P2_2=1;break;
	    case 6:P2_4=0;P2_3=1;P2_2=0;break;
	    case 7:P2_4=0;P2_3=0;P2_2=1;break;
	    case 8:P2_4=0;P2_3=0;P2_2=0;break;
	 }
	 P0=NixieTable[Number];	//段码输出
	 Delay(1);				//显示一段时间
	 P0=0x00;				//段码清0,消影
  }

3.4-1〈Timer0.h〉定时计数器T0头

#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init(void);
#endif

3.4-2〈Timer0.c〉定时计数器T0C程序

#include <REGX52.H>
/**
  * @brief  定时器0初始化,4us@12.000MHz
  * * @param  无
  *  * @retval 无
  *  */
  void Timer0_Init(void)
  {
     TMOD &= 0xF0;		//设置定时器模式
     TMOD |= 0x01;		//设置定时器模式
     TL0 = 0xD0;		//设置定时初值   每4uS溢出一次
     TH0 = 0xFF;		//设置定时初值
     TF0 = 0;		//清除TF0标志
     TR0 = 1;		//定时器0开始计时
     ET0=1;
     EA=1;
     PT0=1;
  }

做该文章,出于个人欲了解CSDN,及与大家分享此程序思路。文章表达不清莫怪。希望同大家探讨该处涉及到的主要问题:于单片机开发板而言,在可按键控制灯的多档亮度的情况下,该如何编程,能完美的消除闪烁出现的黑条?

亮占比约4/20
亮占比约4/20
亮占比约15/20
亮占比约15/20
亮占比100%
100%亮

百度网盘分享:源程序
链接:https://pan.baidu.com/s/15jOoL9YviYcFp6SzLBJPSA?pwd=1317
提取码:1317

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值