标题:
51单片机计算器程序代码 数码管显示加矩阵键盘加电路介绍
[打印本页]
作者:
das
时间:
2015-4-16 03:13
标题:
51单片机计算器程序代码 数码管显示加矩阵键盘加电路介绍
51单片机做的计算器程序代码 姬家寨电子科技实验室 程序编程:姬学瑞 版权所有,侵权必究!51hei补充:程序采用stc单片机强推挽输出免去了驱动芯片,电路图很简单这里不画了
电路介绍:矩阵键盘接在接在P1口,八位数码管八个段选接p0口,8个位选接p2口,电路简单吧,程序已经测试通过了.
#include <REGX51.H>
#define FOSC 12000000 //--- 宏定义时钟频率 ---
//=================================================================================================
//--- 数码管显示定义与函数声明区 ---
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
#define TIMER1MS 1000 //--- 宏定义定时1ms,1000us ---
unsigned char code SEGLED[] = //--- 显示0~9,A~F笔段代码表 ---
{
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0x40,
};
unsigned char code DIGLED[] = //--- 数码管显示的位选通段代码表 ---
{
0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
};
unsigned char LEDBuffer[8] = {0,16,16,16,16,16,16,16}; //--- 定义的显示缓冲区 ---
unsigned char LEDPointer; //--- 定义的扫描计数变量 ---
unsigned char GetKeyCount=0;
unsigned char GetKeyMaxFlag=0;
unsigned long NumberA;
unsigned long NumberB;
long Result;
unsigned char NagFlag=0;
unsigned char DotPosition=0;
unsigned char CurrentFunction=0;
unsigned char Signal;
unsigned char code KEYCODE[] = //--- 矩阵按键代码表 --
{
0x7e,0xbe,0xde,0xee,//0 1 2 3
0x7d,0xbd,0xdd,0xed,//4 5 6 7
0x7b,0xbb,0xdb,0xeb,//8 9 A b
0x77,0xb7,0xd7,0xe7,//C d E F
};
void DelaymS(unsigned char t) //--- 延时函数 ---
{
unsigned char i,j;
while(t --)
{
for(j=2;j>0;j--)
for(i=248;i>0;i--); //--- 12MHZ晶振延时约1mS ---
}
}
//=================================================================================================
//--- main()主程序 ---
void main(void)
{
char i,j;
unsigned char Key;
unsigned char KeyTemp;
P0M1 = 0x00; //--- 配置P0端口的P0.0~P0.7为推挽输出模式 ---
P0M0 = 0xFF;
P2M1 = 0x00; //--- 配置P2端口的P2.0~P2.7为推挽输出模式 ---
P2M0 = 0xFF;
TMOD = 0x01; //--- 配置T0为16位的定时方式 ---
TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- 初始化T0定时1mS ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
TR0 = 1; //--- 启动T0工作 ---
ET0 = 1; //--- 使能T0的溢出中断 ---
EA = 1; //--- CPU开中断 ---
while(1)
{
P1 = 0xF0;
if((P1 & 0xF0) != 0xF0) //--- 判断是否有键按下 ---
{
DelaymS(5); //--- 去抖动 ---
if((P1 & 0xF0) != 0xF0) //--- 再判断是否真得按下 ---
{
KeyTemp = P1 & 0xF0; //--- 反转一次 ---
P1 = 0x0F;
KeyTemp |= (P1 & 0x0F); //--- 读取按键的内容 ---
Key = 0;
while(KeyTemp != KEYCODE[Key])Key ++; //--- 在代码中寻找Key的数值 ---
switch(CurrentFunction)
{
case 0: //--- 输入第1个数据 ---
if((Key >= 0) && (Key <= 9))
{
if(0 == GetKeyMaxFlag)
{
for(i=GetKeyCount;i>0;i--)LEDBuffer[i] = LEDBuffer[i - 1];
LEDBuffer[0] = Key;
GetKeyCount++;
if(5 == GetKeyCount)GetKeyMaxFlag = 1;
}
}
else if((Key >= 10) && (Key <= 13))
{
NumberA = 0;
i = 4;
while(i >= 0)
{
if(16 != LEDBuffer[i])
NumberA = NumberA * 10 + LEDBuffer[i];
i --;
}
CurrentFunction = 1;
Signal = Key;
GetKeyMaxFlag = 0;
GetKeyCount = 0;
for(i=0;i<sizeof(LEDBuffer);i++)LEDBuffer[i] = 16;
LEDBuffer[0] = 0;
}
else if(14 == Key)
{
CurrentFunction = 0;
GetKeyMaxFlag = 0;
GetKeyCount = 0;
NagFlag = 0;
DotPosition = 0;
for(i=0;i<sizeof(LEDBuffer);i++)LEDBuffer[i] = 16;
LEDBuffer[0] = 0;
}
else
{
}
break;
case 1:
if((Key >= 0) && (Key <= 9))
{
if(0 == GetKeyMaxFlag)
{
for(i=GetKeyCount;i>0;i--)LEDBuffer[i] = LEDBuffer[i - 1];
LEDBuffer[0] = Key;
GetKeyCount++;
if(5 == GetKeyCount)GetKeyMaxFlag = 1;
}
}
else if(15 == Key)
{
NumberB = 0;
i = 4;
while(i >= 0)
{
if(16 != LEDBuffer[i])
NumberB = NumberB * 10 + LEDBuffer[i];
i --;
}
switch(Signal)
{
case 10:
Result = NumberA;
Result += NumberB;
break;
case 11:
Result = NumberA;
Result -= NumberB;
break;
case 12:
Result = NumberA;
Result *= NumberB;
break;
case 13:
Result = NumberA;
Result *= 10000;
Result /= NumberB;
break;
}
for(i=0;i<sizeof(LEDBuffer);i++)LEDBuffer[i] = 16;
LEDBuffer[0] = 0;
DotPosition = 0;
NagFlag = 0;
if(Result < 0)
{
Result = ~Result;
Result ++;
NagFlag = 1;
}
if(13 == Signal)//除法运算中除得结果小于0的处理
{
if(Result >= 1000)DotPosition = 4;
else if(Result >= 100)DotPosition = 3;
else if(Result >= 10)DotPosition = 2;
else if(Result >= 1)DotPosition = 1;
for(i=DotPosition;i<5;i++)LEDBuffer[i] = 0;
DotPosition = 4;
}
else DotPosition = 0;
i = 0;//将运算结果送出显示缓冲区
while(Result)
{
LEDBuffer[i] = Result % 10;
Result /= 10;
i ++;
}
if(1 == NagFlag)LEDBuffer[i] = 17;//运算结果为负的处理
if(13 == Signal)//除法运算中最后位"0"的处理
{
j = 0;
while(0 == LEDBuffer[j])
{
for(i=0;i<sizeof(LEDBuffer);i++)
LEDBuffer[i] = LEDBuffer[i+1];
LEDBuffer[sizeof(LEDBuffer)-1]=16;
DotPosition--;
}
}
CurrentFunction = 2;
}
break;
case 2:
if(14 == Key)
{
CurrentFunction = 0;
GetKeyMaxFlag = 0;
GetKeyCount = 0;
NagFlag = 0;
DotPosition = 0;
for(i=0;i<sizeof(LEDBuffer);i++)LEDBuffer[i] = 16;
LEDBuffer[0] = 0;
}
break;
}
while((P1 & 0x0F)!=0x0F); //--- 等待按键释放 ---
}
}
}
}
//=================================================================================================
//--- 定时器T0溢出中断服务程序 ---
void T0_ISR(void) interrupt 1
{
TH0 = (65536 - FOSC / 12 / TIMER1MS) / 256; //--- 重装T0的定时初值 ---
TL0 = (65536 - FOSC / 12 / TIMER1MS) % 256;
P0 = SEGLED[LEDBuffer[LEDPointer]]; //--- 显示数字 ---
if((0 != DotPosition) && (DotPosition == LEDPointer))
P0 |= 0x80; //--- 显示小数点 ---
P2 = DIGLED[LEDPointer]; //--- 数码管的位选段选择 ---
LEDPointer++; //--- 动态扫描计数变量加1 ---
if(sizeof(LEDBuffer) == LEDPointer)LEDPointer = 0; //--- 所有数码管扫描完,计数归0 ---
}
复制代码
作者:
mybigapple
时间:
2015-4-16 21:57
感谢分享。
作者:
Blackadmin
时间:
2016-6-9 22:49
本帖最后由 Blackadmin 于 2016-6-9 22:51 编辑
unsigned char LEDPointer;为何初不用始化?????
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1