单片机与数码管的连接
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机与数码管的连接相关的知识,希望对你有一定的参考价值。
我要将51单片机与22位的七段数码管进行连接,应如何连接,除51单片机和数码管外还需要什么芯片,具体如何连接,最好有图。
如果22位数码管共用7段来驱动,显示效果很差,太暗!而且单片机直接驱动运行起来也费力。你可以计算一下就知道了:如果想显示没有闪烁感,显示刷新周期就要超过50HZ,也就是每20mS这22位数码管都要显示一次,那么每个数码管每次只能显示20mS÷22=0.91mS,而且单片机在这么短的时间内就没有太多的时间处理其它的任务了。要解决这个问题,你必须用专用的LED显示驱动IC,而且要保证每个数码管显示的占空比要超过1/8才会有足够的亮度,如果是室外使用最好是1/4或1/3。
如果占空比选用1/6,那么你要在同一时间每次点亮22/6(4)个数码管,你可以看看TM1629A、B、C、D显示驱动IC,可以用2块驱动IC,每个IC同时点亮2个数码管,每个IC驱动11个数码管。
用这种IC比用74系列的芯片的好处是:只有在需要改变显示内容时,单片机才发送数据到驱动IC,平时不必发送数据,这样MCU就可以把时间用于处理其它任务了。
具体的电路你看IC资料就行了。 参考技术A 数码管封装很多,引脚排列
都不一样,没法告诉你接线,你只要找出段和位就可以了,七个段码和小数点可以通过74hc595直接连接到单片机口上,或者还有cd4511等的bcd解码芯片,共阴或共阳都是可以通过万用表测出来的 参考技术B 本人曾经用一个8位接口(实际上使用了7条线),外接了25个8段的LED数码显示器。
用两条线外接了5片164,可以直接带动5个数码管;
用五条线外接了5个8550,可以动态带动5行数码管。
软件略复杂些,显示效果很好,比16行的汉字点阵显示,轻松的多。本回答被提问者采纳 参考技术C 可以不用芯片,在每段数码管的公共端与三极管连接,这样要使用15个IO口。也可以使用芯片,74HC573,这只要使用8个IO口。 参考技术D MAX7219数码管驱动芯片 在百度搜这个芯片的应用电路
基于51单片机PID算法控制直流电机转速且数码管显示实际转速与设定速度的项目工程
#include<reg52.h> #include<stdio.h> #define uchar unsigned char #define uint unsigned int unsigned char code Duan[]={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴极数码管0-9段码表,高电平导通数码管段显示,低电平导通数码管位显示。 unsigned char Data_Buffer[8]={0,0,0,0,0,0,0,0};//声明数据缓存变量 sbit AddSpeed=P1^1;//位定义加速按键端口 sbit SubSpeed=P1^2;//位定义减速按键端口 sbit PWM_FC=P1^0;//位定义脉冲宽度输入端口 int e ,e1 ,e2 ;//声明当前偏差值变量、之后偏差值变量、再后偏差值变量 int out=0;//PID调节后输出偏差值变量 uint SetSpeed=0;//声明设定速度变量 uint cnt=0;//定时器1中断次数变量 uint Inpluse=0;//声明脉冲计数变量、 uint ActualSpeed=0;//声明实际速度变量 uint PWMTime;//声明脉冲宽度时间变量 float uk ,uk1 ,duk ;//声明目前总偏差值变量、之后偏差值总变量、偏差值总变量 float Kp=0.36,Ki=0.05,Kd=0.016;//声明比例系数、积分系数、微分系数 void PIDControl();//PID控制函数 void SystemInit();//系统初始化函数 void delay(uchar x);//延时函数 void PWMOUT();//脉冲宽度输出函数 void SpeedSet();//设定速度函数 void SegRefre();//数码管显示刷新函数 /**************主函数************/ void main() { SystemInit();//系统初始化函数 while(1) { SpeedSet();//设定速度函数 SegRefre();//数码管显示刷新函数 PWMOUT();//脉冲宽度输出函数 } } void delay(uchar x)//延时函数 { uint i,j; for(i=x;i>0;i--) for(j=50;j>0;j--); } void PIDControl()//PID控制函数 { e=SetSpeed-ActualSpeed;//计算当前偏差值变量 duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2));//PID连续系统离散化增量型PID算法,算出总偏差值变量。 uk=duk+uk1;//计算偏差值总变量加上之后偏差值总变量之和赋给目前总偏差值变量 out=(int)uk;//强制类型转化为整数型的目前总偏差值变量赋给PID调节后输出偏差值变量 if(out>100)//判断PID调节后输出偏差值变量是否大于100 { out=100;//PID调节后输出偏差值变量为100 } else if(out<0)//判断PID调节后输出偏差值变量是否小于0 { out=0;//PID调节后输出偏差值变量为0 } uk1=uk;//目前总偏差值变量赋给之后偏差值总变量 e2=e1;//之前偏差值变量赋给之后偏差值变量 e1=e;//当前偏差值变量赋给之前偏差值变量 PWMTime=out;//PID调节后输出偏差值变量赋给脉冲宽度时间变量 } void PWMOUT()//脉冲宽度输出函数 { if(cnt<PWMTime)//判断定时器1中断次数变量是否小于脉冲宽度时间变量 { PWM_FC=1;//脉冲宽度输入端口输出高电平 } else { PWM_FC=0;//脉冲宽度输入端口输出低电平 } if(cnt>100)//判断定时器1中断次数变量是否大于100 cnt=0;//定时器1中断次数变量归0 } void SystemInit()//系统初始化函数 { TMOD=0X21;//定时器0方式1,定时器1方式2。 TH0=0xf8;//初装定时器0高八位寄存器定时数值 TL0=0x50 ;//初装定时器0低八位寄存器定时数值,即2毫秒。 TH1=0xC0;//初装定时器1高八位寄存器定时数值 TL1=0XC0;//初装定时器1低八位寄存器定时数值,即16毫秒。 EA=1;//开总中断 EX0=1;//开外部中断0 IT0=1;//外部中断0下降沿触发 ET0=1;//开定时器0中断允许 ET1=1;//开定时器1中断允许 TR0=1;//开定时器0中断 TR1=1;//开定时器1中断 e =0;//偏差值变量为0 e1=0;//之后偏差值变量为0 e2=0;//再后偏差值变量为0 } void SpeedSet()//设定速度函数 { if(AddSpeed==0)//判断加速键是否按下 { delay(200);//延时 if(AddSpeed==0)//再次判断加速键是否按下 { SetSpeed+=10;//设定速度变量每次加10 if(SetSpeed>3500)//判断设定速度变量是否大于3500 { SetSpeed=3500;//设定速度变量归为3500 } } } if(SubSpeed==0)//判断减速键是否按下 { delay(200);//延时 if(SubSpeed==0)//再次判断减速键是否按下 { SetSpeed-=10;//设定速度变量每次减10 if(SetSpeed<0)//判断设定速度变量是否小于0 SetSpeed=0;//设定速度变量归0 } } } void SegRefre()//数码管显示刷新函数 { Data_Buffer[0]=SetSpeed/1000;//设定速度变量千位数 Data_Buffer[1]=SetSpeed%1000/100;//设定速度变量百位数 Data_Buffer[2]=SetSpeed%100/10;//设定速度变量十位数 Data_Buffer[3]=SetSpeed%10;//设定速度变量个位数 Data_Buffer[4]=ActualSpeed/1000;//实际速度变量千位数 Data_Buffer[5]=ActualSpeed%1000/100;//实际速度变量百位数 Data_Buffer[6]=ActualSpeed%100/10;//实际速度变量十位数 Data_Buffer[7]=ActualSpeed%10;//实际速度变量个位数 } void int0() interrupt 0//外部中断0函数 { Inpluse++;//脉冲计数变量加加 } void Time0() interrupt 1//定时器0中断服务函数 { static unsigned char Bit=0;//数码管位码静态变量,退出程序,其数值保留。 static unsigned int time=0;//转速测量周期变量 TH0=0xf8;//重装定时器0高八位寄存器计数值 TL0=0x50 ;//重装定时器0低八位寄存器计数值,即2毫秒。 time++;//转速测量周期变量加加 if(time>500)//判断转速测量周期变量是否大于500,等于500就是500x2毫秒=1000毫秒,也就是1s。 { time=0;//转速测量周期变量归0 ActualSpeed=Inpluse;//脉冲计数变量表示实际速度变量 Inpluse=0;//脉冲计数变量归0 PIDControl();//PID控制函数 } PWMOUT();//脉冲宽度输出函数 Bit++;//数码管位码选择位变量 if(Bit>8)//判断数码管位码选择位变量是否大于8 Bit=0;//数码管位码选择位变量归0 P0=0xff;//数码管位码显示关闭 P2=Duan[Data_Buffer[Bit]];//数码管段码显示 switch(Bit)//数码管位码变量选择位 { case 0: P0=0X7F;//实际速度变量千位 break; case 1: P0=0XBF;//实际速度变量百位 break; case 2: P0=0XDF;//实际速度变量十位 break; case 3: P0=0XEF;//实际速度变量个位 break; case 4: P0=0XF7;//设定速度变量千位 break; case 5: P0=0XFB;//设定速度变量百位 break; case 6: P0=0XFD;//设定速度变量十位 break; case 7: P0=0XFE;//设定速度变量个位 break; } } void Timer1() interrupt 3//定时器1中断服务函数 { cnt++;//定时器1中断次数变量 }
以上是关于单片机与数码管的连接的主要内容,如果未能解决你的问题,请参考以下文章
画出单片机连接两位LED数码管显示器的硬件电路,说明显示原理。
单片机中LED显示电路用三极管驱动电路怎么连接啊?四个数码管。