3778|12

252

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

请教高手 [复制链接]

本人做了个光源,遇到疑问请各位高手不吝赐教。此光源采用PWM调光,采用STC12CLE5A48S2单片机,LCD显示LED光源的亮度,定时器1作为串口波特率发生器,定时器0用来产生PWM方波。程序在不加EEPROM读写子程序,光源能正常通过按键进行调光,但是在加了EEPROM读写子程序,在有调光按键按下时,光源都会产生闪烁。听别人说,是EEPROM子程序和其他程序在占用硬件上有冲突,但是还是不懂,不知道哪边有冲突。麻烦高手指点一下,谢谢喽。如果需要程序我可以把程序附上,如果我有什么说不清楚的地方,请指出了,我可以详细再说下。再谢。
此帖出自51单片机论坛

最新回复

可有软件手段回避或者减轻?  详情 回复 发表于 2011-10-19 11:01
点赞 关注
 

回复
举报

535

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
拿程序过来看看撒!没有程序不好说啊!
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

板凳
 

回复 沙发 小小白 的帖子

C语言写的  我分几部分给您检查下  谢谢
先一些变量的定义
#define uchar unsigned char
#define uint unsigned int
#define CTRL  0x2F
#define databus  P0
#define DATA_FLASH_START_ADDRESS 0x00
#define ENABLE_ISP 0x82
sbit  CS1 = P2^3;
sbit  RES = P2^4;
sbit  A0 = P2^5;
sbit  WR = P2^6;
sbit  RD = P2^7;

sbit key1 = P1^5;
sbit key2 = P1^6;
sbit DIM = P1^3;

bit flag1 = 0;
bit flag2 = 0;

uchar power;
uint y=1;

uint count_up ; //增按键计数值
uint count_down ; //减按键计数值
uchar contrast;
uint eeprom_address;


uchar code fenhao[]=
{
0x0F,0x10,0x0F,0x00,0x07,0x18,0x00,0x00,0x00,0x84,0x38,0xC0,0x78,0x84,0x78,0x00,//%
};

uchar code digit[]=
{
0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0xF0,0x08,0x04,0x04,0x08,0xF0,0x00,//0
0x00,0x08,0x08,0x1F,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0xFC,0x04,0x04,0x00,0x00,//1
0x00,0x0E,0x10,0x10,0x10,0x11,0x0E,0x00,0x00,0x0C,0x14,0x24,0x44,0x84,0x0C,0x00,//2
0x00,0x0C,0x10,0x11,0x11,0x12,0x0C,0x00,0x00,0x18,0x04,0x04,0x04,0x88,0x70,0x00,//3
0x00,0x00,0x03,0x04,0x08,0x1F,0x00,0x00,0x00,0xE0,0x20,0x24,0x24,0xFC,0x24,0x00,//4
0x00,0x1F,0x10,0x11,0x11,0x10,0x10,0x00,0x00,0x98,0x84,0x04,0x04,0x88,0x70,0x00,//5
0x00,0x07,0x08,0x11,0x11,0x18,0x00,0x00,0x00,0xF0,0x88,0x04,0x04,0x88,0x70,0x00,//6
0x00,0x1C,0x10,0x10,0x13,0x1C,0x10,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,//7
0x00,0x0E,0x11,0x10,0x10,0x11,0x0E,0x00,0x00,0x38,0x44,0x84,0x84,0x44,0x38,0x00,//8
0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0x00,0x8C,0x44,0x44,0x88,0xF0,0x00,//9
};

uchar code bangtu[]=              //柱状图 15*30
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x01,0x03,0x03,0x07,0x07,0x0F,0x0F,0x1F,0x1F,0x3F,0x3F,0x7F,0x7F,0xFF,0xFF,0xFF,

0x01,0x01,0x03,0x03,0x07,0x07,0x0F,0x0F,0x1F,0x1F,0x3F,0x3F,0x7F,0x7F,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};

uchar code off[]=
{
0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0xF0,0x08,0x04,0x04,0x04,0x08,0xF0,0x00,//O
};

uchar code gong[]=
{
0x00,0x20,0x20,0x20,0x3F,0x20,0x28,0x28,0x08,0x09,0xFE,0x08,0x08,0x0F,0x00,0x00,
0x20,0x30,0x20,0x20,0xC0,0x42,0x44,0x88,0x30,0xC4,0x04,0x06,0x04,0xF8,0x00,0x00,//功
};

uchar code lv[]=
{
0x00,0x30,0x28,0x25,0x20,0x26,0xAC,0x75,0x26,0x24,0x28,0x25,0x28,0x20,0x20,0x00,
0x10,0x50,0x90,0x10,0x10,0x50,0xD0,0x7F,0x50,0xD0,0x30,0x10,0x90,0x50,0x10,0x00,//率
};


//******** Initial System ********


void InitialSystem();
void InitialIO();
void Initial_timer0();
void Initial_Serial();


//******** Initial System  End********

//******** Key1_scan ******************************

void Key1_scan();

//******** Key1_scan End******************************

//******** Key2_scan ******************************

void Key2_scan();

//******** Key2_scan End******************************


//*********Upkey***************************************

void Upkey();

//*********Upkey End************************************

//*********Downkey***************************************

void Downkey();

//*********Downkey End************************************

//******** PWM_P13 ******************************
uchar  duty ;

uchar PWM_P13();
//******** PWM_P13 End******************************

//******** Delay ******************************
void Delay(uint time);

//******** Delay End******************************
此帖出自51单片机论坛
 
 
 

回复

1万

帖子

139

TA的资源

版主

4
 
STC的“EEPROM”其实是程序FLASH,通过IAP实现,Flash的擦除和写入的时间比较长,如果数据量大或者程序调度的效率不够,那么自然会影响程序循环的时间,具体需要进行合理的工艺设计来改善。
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

5
 
EEPROM读写子程序部分
void IAP_Disable()
{
         IAP_CONTR = 0;
         IAP_CMD = 0;
         IAP_TRIG = 0;
         IAP_ADDRH = 0;
         IAP_ADDRL = 0;

}
uint Byte_Read(uint add)
{
         IAP_DATA = 0x00;
         IAP_CONTR = ENABLE_ISP;
         IAP_CMD = 0x01;   

         my_unTemp16.un_temp16 = add;
         IAP_ADDRH = my_unTemp16.un_temp8[0];
         IAP_ADDRL = my_unTemp16.un_temp8[1];

         EA = 0;                                         //???????????????
         IAP_TRIG = 0x5A;
         IAP_TRIG = 0xA5;
         _nop_();                                         //头文件中已包含这个函数,产生一个NOP指令
         EA = 1;                                         //??????????????

         IAP_Disable();

         return(IAP_DATA);

}
void Byte_Program(uint add, uchar ch)
{
         IAP_CONTR = ENABLE_ISP;
         IAP_CMD = 0x02;

         my_unTemp16.un_temp16 = add;
         IAP_ADDRH = my_unTemp16.un_temp8[0];
         IAP_ADDRL = my_unTemp16.un_temp8[1];

     IAP_DATA = ch;

         EA = 0;
         IAP_TRIG = 0x5A;
         IAP_TRIG = 0xA5;
         _nop_();
         EA = 1;

         IAP_Disable();

}
void Sector_Erase(uint add)
{
         IAP_CONTR = ENABLE_ISP;
         IAP_CMD = 0x03;

         my_unTemp16.un_temp16 = add;
         IAP_ADDRH = my_unTemp16.un_temp8[0];
         IAP_ADDRL = my_unTemp16.un_temp8[1];

         EA = 0;
         IAP_TRIG = 0x5A;
         IAP_TRIG = 0xA5;
         _nop_();
         EA = 1;

         IAP_Disable();

}

void EEPROM_read()
{
         eeprom_address = DATA_FLASH_START_ADDRESS;

         count_up = Byte_Read(eeprom_address);
         count_down = Byte_Read(eeprom_address+512);

}

void EEPROM_program()
{
         eeprom_address = DATA_FLASH_START_ADDRESS;

         Sector_Erase(eeprom_address);  
         Byte_Program(eeprom_address,count_up);

         Sector_Erase(eeprom_address+512);
         Byte_Program(eeprom_address+512,count_down);

}
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

6
 
初始化及一些函数
//************I/O初始化*****************************************
void InitialIO()
{
        P1M0 = 0x08;        //P1.3推挽输出 ,P1.5,P1.6紧为输入
        P1M1 = 0x60;
        DIM = 0;

}

//************ 定时器0初始化 ***************************************
void Initial_timer0(void)   
{   
    AUXR = 0x80;   //T0为1T模式
        TMOD = 0x01;   // T0为模式1  
    TH0 = (65536 - 26) / 256;;    //1KHzPWM波
    TL0 = (65536 - 26) % 256;;  
   
        EA = 1;
        ET0 = 1;
        TR0 = 1;  
}

//************ 串口初始化 ***************************************

void Initial_Serial()
{
            AUXR|=0x40;    //Time1 1T
                SCON=0x50;          //串口模式设置
                TMOD=0x21;         //设置定时器1为8位自动重装计数器
       
                TH1=0xFD;        //波特率:115200                       
                TL1=0xFD;
       
                TR1=1;         //开定时器1
                ES=1;
                EA=1;


}


//************ PWM输出 ***************************************
uchar PWM_P13(duty)
{
   
        CMOD = 0x04;   //T0溢出作为PCA时钟输入源
    CL = 0x00;   
    CH = 0x00;   
          CCAP0H = duty;
        CCAP0L = duty;
        CCAPM0 = 0x42;   //8位PWM
    CR = 1;   
                 
}
//************ 定时0中断 ***************************************
void timer0_int (void) interrupt 1 using 1   
{   
    TH0 = (65536 - 26) / 256;   
    TL0 = (65536 - 26) % 256;
            
      
}

//************ 串口接收中断 ***************************************
void Serial_isr() interrupt 4
{
          
                  uint temp;
            if(RI)
            {               
                       
                         RI=0;  
             temp  = SBUF;
                          SBUF = key1;
                     while(!TI);
                     TI = 0;
                         
                         RI = 0;
                         temp = SBUF;
                     SBUF = count_up;
                     while(!TI);
                     TI = 0;

                         RI = 0;
                         temp = SBUF;
                         SBUF = count_down;
                     while(!TI);
                     TI = 0;
                             
                       
                       
                       
            }
            else
            {
                RI=0;
            }
}

//************ 上按键判断 ***************************************

void Key1_scan()
{
          
           if(key1 == 0)
           {
                     
                  Delay(6);          //20ms
                  
                  if(key1 == 0)
                  {
                           flag1 = 1;
                //         count_up ++;
               
                         Delay(300);
                         PCA_PWM0=0x00;
                           
                  }
                 
                  
           }
           else
           {
                    flag1 = 0;
               
          
           }


}

//************ 下按键判断 ***************************************

void Key2_scan()
{
           if(key2 == 0)
           {
                     Delay(6); //20ms
                  if(key2 == 0)
                  {
                           flag2 = 1;
                        // count_down ++;
                         
                         Delay(300);
                         
                  
                  }
                 
          
           }
           else
           {
                    flag2 = 0;
       
          
           }


}


//************ 上按键处理 ***************************************

void Upkey()
{

                if(flag1 == 1)       
                {       
                    
                    if(y!=0)
                           {
                        count_up ++;
                        y=256-(count_up-count_down)*256/100;         
                        //y= (int)(t+5/10);
                        PWM_P13(y);
                        }
                    EEPROM_program() ;
                }


}


//************ 下按键处理 ***************************************

void Downkey()
{
               
                if(flag2 == 1)
                {
                        count_down ++;
                        y=256-(count_up-count_down)*256/100;
                        //y= (int)(t+5/10);
                        if(y==256)
                        {
                        PCA_PWM0=0x03;
                        }
                       
                        if(y>256)
                        {
                            //if(y>257)
                                //{
                            count_down --;
                            //}
                                PCA_PWM0=0x03;
                        }
                       
                        PWM_P13(y);
                    EEPROM_program();
                }


}

//************ 延时  ***************************************
void Delay(uint time)                                                    
{
    uchar i;

        while(time--)
        {
                for(i = 0; i < 80; i ++)
                {;}
        }
}
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

7
 
LCD显示屏初始化及其所要用的一些函数
uchar reverse(figure)   //反转P0口
{
        uchar a=0;
        uchar j,b;
        for(j=0;j<8;j++)
          {
                  a=a>>1;
                  b=figure&0x80;                 
                  if(b!=0)
                    {
                            a=a|0x80;
                    }
                  figure=figure<<1;  
          }
   return a;
}


void CmdWrite(uchar cam_data)                  //写地址
{
  uchar CAMDATA;
  CAMDATA=reverse(cam_data);
  CS1=1;
  A0=0;
  CS1=0;
  RD=1;
  WR=0;
  databus=CAMDATA;  
  WR=1;
  CS1=1;
}

void DataWrite(uchar data_data)                  //写数据
{
  CS1=1;
  A0=1;
  CS1=0;
  RD=1;
  WR=0;
  databus=data_data;
  WR=1;
  CS1=1;
}

void NT75451_INIT(void)          //128*64液晶屏初始化
{      
    Delay(100);
        CmdWrite(0xE2);  //STANDBY MODE OFF
        Delay(40);
        //CmdWrite(0x34);
        CmdWrite(0xA2);  //bias set 1/9,1/65 DUTY  ,亮度设置
        CmdWrite(0xA0);  //ADC select SEG0 to SEG127 normal
        CmdWrite(0xC8);  //COM Reverse
        CmdWrite(0x40);  //Display Start Line Set =0
        Delay(20);
       
        CmdWrite(0x25);  //V0 Voltage Regulator Internal Resistor Ratio Set
        CmdWrite(0x2f);  //power control(VC,VR,VF=1,1,1)(028--02FH)--2f
        Delay(20);
        CmdWrite(0x81);  //Regulator resistor select 100(020H--027H)
        CmdWrite(CTRL);  //contrast
        Delay(20);
        //CmdWrite(0x00); //Initial Display Line/Number of Start Line Set-63-3F
        CmdWrite(0xA6);

        CmdWrite(0x89);  //Select DC-DC converter circuit
        CmdWrite(0x01);  //4 times boosting circuit
        CmdWrite(0xE5);  //Oscillation Frequency Select-31.4KHZ                                 
        CmdWrite(0xA4);  //Entire Display ON
        CmdWrite(0xAf);  //turns the display ON               
        Delay(100);
       
        contrast = CTRL;
}



void LCD_Reset(void)
{
//  RES=1;
//  DelayXms(2);
  RES=0;
  Delay(200);
  RES=1;
  Delay(200);//more than 150ms
}



void clear(void)                           //清屏
{
        uint i,j;
        for(i=0;i<8;i++)
        {
          
            CmdWrite(i+0xb0);       //行地址
            CmdWrite(0x10);         //列地址
            CmdWrite(0x00);        //此指令是为了列地址能够自动递加
            for(j=0;j<128;j++)
            {
                    DataWrite(0x00);
      }
   }                               
}






void display_WORD(uchar row,uchar line,uchar *character)  //写汉字
{
        uchar j;
        CmdWrite(0xb0+row);     //行
        CmdWrite(0x10+line);    //列

        CmdWrite(0x00);
        for(j=0;j<16;j++)
          {
                  DataWrite(character[j]);
          }

        CmdWrite(0xb1+row);     //行       
        CmdWrite(0x10+line);    //列

        CmdWrite(0x00);
        for(j=16;j<32;j++)
          {
                  DataWrite(character[j]);
          }                    
}


void display_digit(uchar value)  //写数字
{
        uchar j,l,m,n;
        if(value>=100)
          {
            value=100;
          }
        l=value/100;
        m=value%100/10;
        n=value%100%10;                    
        if(l==0)
         {
                 if(m==0)
                   {
                           CmdWrite(0xb3);
              CmdWrite(0x13);
              CmdWrite(0x00);
                          
                           for(j=0;j<8;j++) {DataWrite(0x00);}
                           for(j=0;j<8;j++) {DataWrite(0x00);}
                           for(j=0;j<8;j++) {DataWrite(digit[n*16+j]);}
                        for(j=0;j<8;j++) {DataWrite(fenhao[j]);}
                        for(j=0;j<8;j++) {DataWrite(0x00);}
                           CmdWrite(0xb4);
              CmdWrite(0x13);
              CmdWrite(0x00);
                          
                           for(j=8;j<16;j++) {DataWrite(0x00);}
                           for(j=8;j<16;j++) {DataWrite(0x00);}
                           for(j=8;j<16;j++) {DataWrite(digit[n*16+j]);}
                        for(j=8;j<16;j++) {DataWrite(fenhao[j]);}
                        for(j=8;j<16;j++) {DataWrite(0x00);}                                                     
                   }
                 else
                   {
                           CmdWrite(0xb3);
              CmdWrite(0x13);
              CmdWrite(0x00);
                           for(j=0;j<8;j++) {DataWrite(0x00);}
                           for(j=0;j<8;j++) {DataWrite(digit[m*16+j]);}
                           for(j=0;j<8;j++) {DataWrite(digit[n*16+j]);}
                           for(j=0;j<8;j++) {DataWrite(fenhao[j]);}
                           for(j=0;j<8;j++) {DataWrite(0x00);}
                           CmdWrite(0xb4);
              CmdWrite(0x13);
              CmdWrite(0x00);
                           for(j=8;j<16;j++) {DataWrite(0x00);}
                           for(j=8;j<16;j++) {DataWrite(digit[m*16+j]);}
                           for(j=8;j<16;j++) {DataWrite(digit[n*16+j]);}
                           for(j=8;j<16;j++) {DataWrite(fenhao[j]);}
                        for(j=8;j<16;j++) {DataWrite(0x00);}                          
                   }  
         }
         else
          {
                  CmdWrite(0xb3);
            CmdWrite(0x13);
            CmdWrite(0x00);
                   for(j=0;j<8;j++) {DataWrite(digit[16+j]);}
                   for(j=0;j<8;j++) {DataWrite(digit[m*16+j]);}
                   for(j=0;j<8;j++) {DataWrite(digit[n*16+j]);}
                   for(j=0;j<8;j++) {DataWrite(fenhao[j]);}
                  for(j=0;j<8;j++) {DataWrite(0x00);}       
                   
                  CmdWrite(0xb4);
            CmdWrite(0x13);
            CmdWrite(0x00);
                   for(j=8;j<16;j++) {DataWrite(digit[16+j]);}
                   for(j=8;j<16;j++) {DataWrite(digit[m*16+j]);}
                   for(j=8;j<16;j++) {DataWrite(digit[n*16+j]);}       
                   for(j=8;j<16;j++) {DataWrite(fenhao[j]);}
                  for(j=8;j<16;j++) {DataWrite(0x00);}                               
          }
}



void guangzhu (uchar value)    //显示柱状图
{
        uchar j;
          CmdWrite(0xb2);
            CmdWrite(0x15);
            CmdWrite(0x02);
            for(j=0;j<(value/3);j++)
             {
               DataWrite(bangtu[j]);
             }
           for(j=(value/3);j<33;j++)
             {
                           DataWrite(0x00);
                 }
      CmdWrite(0xb3);
            CmdWrite(0x15);
            CmdWrite(0x02);
            for(j=33;j<33+(value/3);j++)
             {
               DataWrite(bangtu[j]);
             }
           for(j=33+(value/3);j<66;j++)
             {
                           DataWrite(0x00);
                 }
             
     CmdWrite(0xb4);
           CmdWrite(0x15);
           CmdWrite(0x02);
           for(j=66;j<66+(value/3);j++)
             {
               DataWrite(bangtu[j]);
             }
           for(j=66+(value/3);j<99;j++)
             {
                           DataWrite(0x00);
                 }
       
          

}
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

8
 
主函数部分
#include
#include
#include
#include"./INC/foreal.h"
#include"./SRC/FOREAL.c"



void InitialSystem()
{
         InitialIO();

         Initial_timer0();

         Initial_Serial();

}

void display ()
{
        display_WORD(3,1,gong);   
                  display_WORD(3,2,lv);
                power=count_up-count_down;  
                  display_digit(power);
                guangzhu (power);
}

void main()
{
         InitialSystem();
         LCD_Reset();
         NT75451_INIT();
         clear();
         Delay(600);
         EEPROM_read();
         if(count_up-count_down)
         {;}
         else
         {PCA_PWM0=0x03;}
         PWM_P13(256-(count_up-count_down)*256/100);


         while(1)
         {
          
           Key1_scan();

           Key2_scan();
           Upkey();
           Downkey();

           display ();
                          
         }

}
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

9
 
P1.3口实PWM输出口,输出PWM信号给LED驱动,通过按键P1.5和P1.6调节PWM的占空比对LED调光。LCD显示LED的亮度,显示的字符为“功率 50%  光柱”(像手机信号一样的光柱),在整个程序中,我把下按键处理子程序和上按键处理子程序中的EEPROM_program();给屏蔽掉,则LED能正常进行上下调节亮度,但是如果不屏蔽,则在每次调节时LED都会有闪烁,好像有了冲突,不知道为什么,麻烦讲解下,谢谢。
此帖出自51单片机论坛
 
 
 

回复

1万

帖子

139

TA的资源

版主

10
 
这不叫冲突而是时间占用问题,看4楼的解释。
此帖出自51单片机论坛
 
 
 

回复

535

帖子

0

TA的资源

五彩晶圆(初级)

11
 
前面的大侠说的有道理啊!哈哈!自己体会下啊
此帖出自51单片机论坛
 
 
 

回复

252

帖子

0

TA的资源

纯净的硅(初级)

12
 

回复 10楼 chunyang 的帖子

谢谢,chunyang老师,您能帮我再详细分析下吗?我不懂具体应该怎么解决。是精简程序吗,还是怎么办?谢谢。
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

13
 

回复 4楼 chunyang 的帖子

可有软件手段回避或者减轻?
此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表