这两天一直在帮毕业生做毕业设计,也算是回报一下当初帮助过我的人吧。也希望技术以后不再有壁垒,大家都能彼此的帮助,这样科技才能更好地发展。把刚做的一个毕业设计的电路和代码贴出来,希望能给需要的人提供写帮助。
课题要求很简单:
按键1加计数,按键2减计数,在2位数码管显示。若显示值为:0-5 ,LED1亮;6-10 ,LED1和LED2亮;11-15, LED1 LED2 LED3亮。以此类推,到36-40时,全部八个LED都亮。
其实就是按键判断和数码管显示的问题,总共用来半天的时间就把程序和仿真做出来了。仿真结果如下:
程序如下:
/*免责声明:
作者:陈伯林
时间:2010-5-16
版本:v1.0
用途:按键显示
本程序为本人所编写,任何人可以随意使用或修改本代码
包括商业用途。但是本人不承担任何责任,具体请遵循GPL协议*/
#include <reg51.h>
#include <intrins.h> //内部包含延时函数 _nop_()
#define uchar unsigned char
#define uint unsigned int
#define BUTTON1 1 //按键1
#define BUTTON2 2 //按键2
sbit SDATA_595 = P1^7; //串行移位输入
sbit SHcp_595 = P1^5; //移位寄存器时钟输入SHcp
sbit STcp_595 = P1^6; //存储寄存器时钟输入STcp
sbit DIGIT1 = P1^1;
sbit DIGIT2 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
uchar Counter = 10;
uchar code DAT[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x90};
/*-----------延时子程序---------*/
void delay(void)
{
uchar m;
for(m=0 ; m<200 ; m++);
}
//-------------按键延时---------------//
void ButtonDelay(uchar x)
{
uchar i,j;
for(i = 0; i++; i < x)
for(j = 0; j++; j < 200);
}
/*将移位寄存器内的数据锁存到输出寄存器并显示 */
void OUT_595(void)
{
STcp_595 = 0;
_nop_();
_nop_();
STcp_595=1; //上升沿将数据送到输出锁存器
_nop_();
_nop_();
STcp_595 = 0 ;
}
/*将显示数据送入74HC595内部移位寄存器 */
void WR_595(uchar x)
{
uchar temp;
uchar j;
DIGIT1 = 0;
DIGIT2 = 0;
temp = x;
SHcp_595 = 0;
for (j=0; j<8; j++)
{
temp = temp<<1;
SDATA_595 = CY;
SHcp_595 = 1; //上升沿发生移位
_nop_();
_nop_();
SHcp_595 = 0;
_nop_();
_nop_();
}
OUT_595();
}
/*数码管按照共阳极编写*/
void display(void)
{
uchar num1,num2;
num1 = Counter/10;
num2 = Counter%10;
WR_595(DAT[num1]);
DIGIT1 = 1;
DIGIT2 = 0;
delay();
WR_595(DAT[num2]);
DIGIT1 = 0;
DIGIT2 = 1;
delay();
}
//------------按键扫描------------//
uchar ButtonScan (void)
{
uchar ButtonNum = 0;
if(P13 == 0)
{
/*延时防止按键抖动,如果晶振是12M的话。
如果是其他的只要让延时在30ms就可以了*/
ButtonDelay(150);
if(P13 == 0)
while(!P13); /*等待按键松开*/
ButtonNum = BUTTON1;
}
if(P14 == 0)
{
ButtonDelay(150);
if(P14 == 0)
while(!P14); /*等待按键松开*/
ButtonNum = BUTTON2;
}
return ButtonNum;
}
//----------按键判断-------------//
void ButtonJugde (void)
{
switch(ButtonScan())
{
case 1: //增加
if (Counter != 40)
Counter++;
break;
case 2: //减小
if (Counter != 0)
Counter--;
break;
default: break;
}
}
//---------LED点亮处理--------//
uchar LED (void)
{
uchar LedEnable;
if((Counter > 0) && (Counter <= 5))
{
/*二极管是接地的,高电平点亮
根据实际电路情况调整*/
LedEnable = 0x01;
}
if((Counter > 5) && (Counter <= 10))
{
LedEnable = 0x03;
}
if((Counter > 10) && (Counter <= 15))
{
LedEnable = 0x07;
}
if((Counter > 15) && (Counter <= 20))
{
LedEnable = 0x0f;
}
if((Counter > 20) && (Counter <= 25))
{
LedEnable = 0x01f;
}
if((Counter > 25) && (Counter <= 30))
{
LedEnable = 0x3f;
}
if((Counter > 30) && (Counter <= 35))
{
LedEnable = 0x7f;
}
if((Counter > 35) && (Counter <= 40))
{
LedEnable = 0xff;
}
return LedEnable;
}
void main(void)
{
while(1)
{
ButtonJugde (); //按键扫描
P2 = LED(); //点亮二极管
display(); //数码管显示
}
}