找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3043|回复: 8
打印 上一主题 下一主题
收起左侧

咨询一个单片机同时驱动数码管和点阵有闪烁的问题

[复制链接]
跳转到指定楼层
楼主
通过数码管做的频率计,点阵来显示波形。但是波形和数码管会出现闪烁的问题,求大神解决

QQ图片20171127160843.png (77.74 KB, 下载次数: 51)

QQ图片20171127160843.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:235629 发表于 2017-11-27 16:15 | 只看该作者
#include <reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned  int       
uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};         //所需的段的位码
//uchar wei[4]={0XEf,0XDf,0XBf,0X7f};                                 //位的控制端        (开发板)
uchar wei[4]={0X80,0X40,0X20,0X10};                                 //位的控制端        (仿真)
uint z,x,c,v, date;        //定义数据类型
uint dispcount=0;
uint lck=0;
uint disp=0;
/*  数据端接口定义 */
sbit  key0=P1^0;
sbit  key1=P1^1;
sbit  key2=P1^2;
sbit  key3=P1^3;

sbit  sck = P2^0;                 //输入时钟
sbit  row_dat = P2^1;         //行数据时钟
sbit  row_buf_sck = P2^2; //行锁存
//sbit  row_mr = P2^4;          //移位寄存器清零端
//sbit  row_oe = P2^5;        //输出使能
/*  选通端接口定义 */
sbit  col_dat = P2^6;          //列数据时钟
sbit  col_buf_sck = P2^3; //列锁存
unsigned char keyval;

unsigned int code sel[16] = {0xff7f,0x7fff,0xffbf,0xbfff,0xffdf,0xdfff,0xffef,0xefff,
                                                         0xfff7,0xf7ff,0xfffb,0xfbff,0xfffd,0xfdff,0xfffe,0xfeff};

unsigned char code hanzi[4][32] =
{

{0x1C,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x1C,0x00,0x02,0x00,0x01,0x00,
0x01,0x00,0x02,0x00,0x1C,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x1C,0x00},/*"正弦",0*/

{0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF},/*"方波",1*/

{0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20,
0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20},/*"三角波",2*/

{0x1C,0xFF,0x20,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1C,0xFF,0x02,0x01,0x01,0x01,
0x01,0x01,0x02,0x01,0x1C,0xFF,0x20,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1C,0xFF},/*"正弦和方波",3*/

};


void display(unsigned char *p);
void send_data_row(unsigned int dat);  /*  发送行数据端数据函数  */
void send_data_col(unsigned int dat);  /*  发送列选通端数据函数  */
void delay(unsigned int m);
void T(void);
void delay10ms();
void delayfre(uchar t)
{
  uchar i,j;
   for(i=0;i<t;i++)
   {
            for(j=13;j>0;j--);
         { ;
         }
   }
}

void xianshi()
{
/*****************数据转换*****************************/
  z=date/1000;                         //求千位
  x=date%1000/100;                 //求百位
  c=date%100/10;                 //求十位
  v=date%10;                         //求个位

      P2=wei[0];
          P0=duan[z];
          delayfre(30);  
            P2=wei[1];
      P0=duan[x];
          delayfre(30);  
             P2=wei[2];
      P0=duan[c];
          delayfre(30);  
      P2=wei[3];
      P0=duan[v];
          delayfre(30);  
                                      

       }

/*************************************************************************
                                定时器初值1ms       
**************************************************************************/
void initTimer(void)
{
TMOD=0x0;
TH0=0xe3;
TL0=0xc;
}

/*************************************************************************
                                定时器函数       
**************************************************************************/
void timer0(void) interrupt 1
{
TH0=0xe3;
TL0=0xc;
lck++;
if(lck==1000)
       {
        disp=dispcount;
            lck=0;
                dispcount=0;
       }

}

/*************************************************************************
                                中断函数       
**************************************************************************/
void int0(void) interrupt 0
{

dispcount++; //每一次中断,计数加一

}


void T(void)
{
        P1=0xff;
        if((P1&0x0f)!=0x0f)
        {
        delay10ms();
             if(key0==0)
        keyval=0;
                if(key1==0)
        keyval=1;
                if(key2==0)
        keyval=2;
                if(key3==0)
        keyval=3;
       
        }
}

void delay10ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
;
}
void send_data_row(unsigned int dat)
{
        unsigned char i;
       
        for(i=0;i<16;i++)
        {
                sck = 0;
                row_dat = dat&0x8000;                //temp<<=1;
                dat = dat<<1;                                //ds = CY;
                sck = 1;
        }
        row_buf_sck = 0;
        _nop_();
        _nop_();
        row_buf_sck = 1;
}

void send_data_col(unsigned int dat)
{
        unsigned char i;       
        for(i=0;i<16;i++)
        {
                sck = 0;
                col_dat = dat&0x8000;
                dat = dat<<1;
                sck = 1;
        }
        col_buf_sck = 0;
        _nop_();
        _nop_();
        col_buf_sck = 1;
}

void delay(unsigned int m)
{
        unsigned char i;
        for(;m>0;m--)
        {
                for(i=0;i<124;i++)
                {;}
        }
}

void display(unsigned char *p)         
{
        unsigned char i;
//        unsigned int temp;
        for(i=0;i<32;i++)
        {
                if(i<16)
                {
                        send_data_row(0x0000);
                //        temp = sel[i]|0xff00;
                        send_data_col(sel[i]);
                        send_data_row(*p);
                        p++;
                                                delay(2);

                }
                else
                {
                        send_data_row(0x0000);
                //        temp = (sel[i]<<8)|0x00ff;
                        send_data_col(sel[i-16]);
                        send_data_row((*p)<<8);
                        p++;
                                                delay(2);

                }                         
        }
}
void main()
{
          IT0=1;     //INT0下降沿中断
EX0=1;     //允许INT1中断
initTimer(); //装入初值
TR0=1;
ET0=1;
EA=1;
keyval=0;
while(1)
{

          date=disp;
xianshi();
T();
switch(keyval)
{
case 0:display(hanzi[0]);
break;
case 1:display(hanzi[1]);
break;
case 2:display(hanzi[2]);
break;
case 3:display(hanzi[3]);
break;

}
}
}
回复

使用道具 举报

板凳
ID:235629 发表于 2017-11-27 17:09 | 只看该作者
#include <reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned  int       
uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};         //所需的段的位码
//uchar wei[4]={0XEf,0XDf,0XBf,0X7f};                                 //位的控制端        (开发板)
uchar wei[4]={0X80,0X40,0X20,0X10};                                 //位的控制端        (仿真)
uint z,x,c,v, date;        //定义数据类型
uint dispcount=0;
uint lck=0;
uint disp=0;
/*  数据端接口定义 */
sbit  key0=P1^0;
sbit  key1=P1^1;
sbit  key2=P1^2;
sbit  key3=P1^3;

sbit  sck = P2^0;                 //输入时钟
sbit  row_dat = P2^1;         //行数据时钟
sbit  row_buf_sck = P2^2; //行锁存
//sbit  row_mr = P2^4;          //移位寄存器清零端
//sbit  row_oe = P2^5;        //输出使能
/*  选通端接口定义 */
sbit  col_dat = P2^6;          //列数据时钟
sbit  col_buf_sck = P2^3; //列锁存
unsigned char keyval;

unsigned int code sel[16] = {0xff7f,0x7fff,0xffbf,0xbfff,0xffdf,0xdfff,0xffef,0xefff,
                                                         0xfff7,0xf7ff,0xfffb,0xfbff,0xfffd,0xfdff,0xfffe,0xfeff};

unsigned char code hanzi[4][32] =
{

{0x1C,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x1C,0x00,0x02,0x00,0x01,0x00,
0x01,0x00,0x02,0x00,0x1C,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x1C,0x00},/*"正弦",0*/

{0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x01,0x00,0x01,
0x00,0x01,0x00,0x01,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF},/*"方波",1*/

{0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20,
0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20},/*"三角波",2*/

{0x1C,0xFF,0x20,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1C,0xFF,0x02,0x01,0x01,0x01,
0x01,0x01,0x02,0x01,0x1C,0xFF,0x20,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1C,0xFF},/*"正弦和方波",3*/

};


void display(unsigned char *p);
void send_data_row(unsigned int dat);  /*  发送行数据端数据函数  */
void send_data_col(unsigned int dat);  /*  发送列选通端数据函数  */
void delay(unsigned int m);
void T(void);
void delay10ms();
void delayfre(uchar t)
{
  uchar i,j;
   for(i=0;i<t;i++)
   {
            for(j=13;j>0;j--);
         { ;
         }
   }
}

void xianshi()
{
/*****************数据转换*****************************/
  z=date/1000;                         //求千位
  x=date%1000/100;                 //求百位
  c=date%100/10;                 //求十位
  v=date%10;                         //求个位

      P2=wei[0];
          P0=duan[z];
          delayfre(30);  
            P2=wei[1];
      P0=duan[x];
          delayfre(30);  
             P2=wei[2];
      P0=duan[c];
          delayfre(30);  
      P2=wei[3];
      P0=duan[v];
          delayfre(30);  
                                      

       }

/*************************************************************************
                                定时器初值1ms       
**************************************************************************/
void initTimer(void)
{
TMOD=0x0;
TH0=0xe3;
TL0=0xc;
}

/*************************************************************************
                                定时器函数       
**************************************************************************/
void timer0(void) interrupt 1
{
TH0=0xe3;
TL0=0xc;
lck++;
if(lck==1000)
       {
        disp=dispcount;
            lck=0;
                dispcount=0;
       }

}

/*************************************************************************
                                中断函数       
**************************************************************************/
void int0(void) interrupt 0
{

dispcount++; //每一次中断,计数加一

}


void T(void)
{
        P1=0xff;
        if((P1&0x0f)!=0x0f)
        {
        delay10ms();
             if(key0==0)
        keyval=0;
                if(key1==0)
        keyval=1;
                if(key2==0)
        keyval=2;
                if(key3==0)
        keyval=3;
       
        }
}

void delay10ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
;
}
void send_data_row(unsigned int dat)
{
        unsigned char i;
       
        for(i=0;i<16;i++)
        {
                sck = 0;
                row_dat = dat&0x8000;                //temp<<=1;
                dat = dat<<1;                                //ds = CY;
                sck = 1;
        }
        row_buf_sck = 0;
        _nop_();
        _nop_();
        row_buf_sck = 1;
}

void send_data_col(unsigned int dat)
{
        unsigned char i;       
        for(i=0;i<16;i++)
        {
                sck = 0;
                col_dat = dat&0x8000;
                dat = dat<<1;
                sck = 1;
        }
        col_buf_sck = 0;
        _nop_();
        _nop_();
        col_buf_sck = 1;
}

void delay(unsigned int m)
{
        unsigned char i;
        for(;m>0;m--)
        {
                for(i=0;i<124;i++)
                {;}
        }
}

void display(unsigned char *p)         
{
        unsigned char i;
//        unsigned int temp;
        for(i=0;i<32;i++)
        {
                if(i<16)
                {
                        send_data_row(0x0000);
                //        temp = sel[i]|0xff00;
                        send_data_col(sel[i]);
                        send_data_row(*p);
                        p++;
                                                delay(2);

                }
                else
                {
                        send_data_row(0x0000);
                //        temp = (sel[i]<<8)|0x00ff;
                        send_data_col(sel[i-16]);
                        send_data_row((*p)<<8);
                        p++;
                                                delay(2);

                }                         
        }
}
void main()
{
          IT0=1;     //INT0下降沿中断
EX0=1;     //允许INT1中断
initTimer(); //装入初值
TR0=1;
ET0=1;
EA=1;
keyval=0;
while(1)
{
           T();
          date=disp;
xianshi();
switch(keyval)
{
case 0:display(hanzi[0]);
break;
case 1:display(hanzi[1]);
break;
case 2:display(hanzi[2]);
break;
case 3:display(hanzi[3]);
break;
}
}


}

回复

使用道具 举报

地板
ID:254304 发表于 2017-11-27 18:55 | 只看该作者
如果显示结果是正常的,只是显示闪烁,那可能是单片机刷新的速度不够,可以把你耗时间的运算用耗时间少的操作代替掉,比如:*用左移替换掉,把delay10ms用别的操作替换掉,10MS太大了,比如用显示操作替换掉DELAY的时间,还不行的话,就用4片595支持数码管的显示,其与时间用来刷新点阵模块。
回复

使用道具 举报

5#
ID:235629 发表于 2017-11-27 20:11 | 只看该作者
fancean 发表于 2017-11-27 18:55
如果显示结果是正常的,只是显示闪烁,那可能是单片机刷新的速度不够,可以把你耗时间的运算用耗时间少的操 ...

好的,我试一下。新手,有太多不懂的了
回复

使用道具 举报

6#
ID:142559 发表于 2017-11-27 20:16 | 只看该作者
应该是你的程序所用时间太长,出现“延时”的情况了
回复

使用道具 举报

7#
ID:254398 发表于 2017-11-27 21:41 | 只看该作者
程序准备时间太长,再次进入之前耗时太长
回复

使用道具 举报

8#
ID:253967 发表于 2017-11-27 23:03 | 只看该作者
好帖,赞一个
回复

使用道具 举报

9#
ID:254453 发表于 2017-11-27 23:37 来自手机 | 只看该作者
好帖,赞
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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