资讯详情

51单片机矩阵键盘与左右流水灯控制C程序

本程序所用的原理图下载: 点这里 ,单片机芯片使用的stc89c52;找到本程序所使用的相应部分即可.这是一整个单片机的电路图其他的忽略. hex文件及其工程文件下载:http://www.51hei.com/f/jzzyou.rar 以下是测试ok的源代码:

/* *功能:使用矩阵按键使得按键按下时上显示各自对应的数字的平方数; * 且使用定时器0中断使得彩色流水灯先以20毫秒的速度左移流动4秒后, * 然后使得彩色流水灯以20毫秒的速度右移流动; *日期:2013-05-02-16:46 *作者:徐冉 *特别说明:本程序代码已经通过调试,仅供学习使用; * */ /***********AT89C52-RC 单片机- 51hei-5 实验板***********/ /*****************51hei开发板*********************/ #include <reg52.h> typedef unsigned int uint; typedef unsigned char uchar; sbit wela = P2^7; sbit dula = P2^6; sbit FM = P2^3; uchar code table[] = { 0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F //"9" }; uint key1 = 0; uchar counter = 0, x = 0, flag = 0; void display(uint num); void delay(uint xms); void Marix_keyscan(); void init(); //主程序 void main() { init();//定时器0初始化 while(1) { if(counter == 200)//定时器定时左移流动4秒 { counter = 0; flag = 1; TR0 = 0; TH0 = 0xB8; TL0 = 0X00; TR0 = 1; x = 0; } Marix_keyscan(); display(key1); } } //定时器0初始化子程序 void init() { TMOD = 0x01; TH0 = 0xB8; TL0 = 0X00; EA = 1; ET0 = 1; TR0 = 1; } //数码管优化显示子程序 void display(uint num) { uchar bai, shi, ge; bai = num / 100 % 10; shi = num / 10 % 10; ge = num % 10; if(num < 10) { dula = 1; P0 = table[ge]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfe; wela = 0; P0 = 0x00; delay(1); } else if(num < 100) { dula = 1; P0 = table[shi]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfe; wela = 0; P0 = 0x00; delay(1); dula = 1; P0 = table[ge]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfd; wela = 0; P0 = 0x00; delay(1); } else { dula = 1; P0 = table[bai]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfe; wela = 0; P0 = 0x00; delay(1); dula = 1; P0 = table[shi]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfd; wela = 0; P0 = 0x00; delay(1); dula = 1; P0 = table[ge]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfb; wela = 0; P0 = 0x00; delay(1); } } //延时子程序 void delay(uint xms) { uint i, j; for(i = xms; i > 0; i--) for(j = 125; j > 0; j--); } //矩阵按键检测子程序 void Marix_keyscan() { uchar temp; //定义一个变量存放P3口的值 //第一次矩阵按键检测 P3 = 0xfe; //给P3口赋一个值,使得矩阵按键的第一行置为低电平,其余口置为高电平; temp = P3; //将P3口的值赋给temp temp &= 0xf0; //通过与0xf0&来检测矩阵按键的各列通过行列检测与检测矩阵按键 if(temp != 0xf0) { //检测有矩阵按键按下 delay(5);//消抖 temp = P3;//再次将P3口的值赋给temp,即再次赋初值检测矩阵按键; temp &= 0xf0; //再次按位与检测矩阵按键行列 if(temp != 0xf0) { //确认有键按下 FM = 0;//发声 temp = P3; //将此时的P3口的值赋给temp switch(temp) { case 0xee: key1 = 1 * 1; break; //检测到key1按下 case 0xde: key1 = 2 * 2; break; //检测到key2按下 case 0xbe: key1 = 3 * 3; break; //检测到key3按下 case 0x7e: key1 = 4 * 4; break; //检测到key4按下 default: break; } //按键释放 while(temp != 0xf0) { //重新赋初值检测矩阵按键 temp = P3; temp &= 0xf0; } delay(5);//释放去抖 //按键释放 while(temp != 0xf0) { //重新赋初值检测矩阵按键 temp = P3; temp &= 0xf0; } //按键释放关闭蜂鸣器 FM = 1; } } //第二次矩阵按键检测 P3 = 0xfd; //给P3口赋初值,使得矩阵按键的第二行置0,其余行为高电平; temp = P3;//将用于检测的值赋给变量temp temp &= 0xf0; if(temp != 0xf0) { delay(5);//消抖 //重新装入待于检测的初值; temp = P3; temp &= 0xf0; if(temp != 0xf0) { //确定矩阵按键有键被按下 //将此时的P3口的值赋给temp FM = 0; temp = P3; //开始检测 switch(temp) { case 0xed: key1 = 5 * 5; break; case 0xdd: key1 = 6 * 6; break; case 0xbd: key1 = 7 * 7; break; case 0x7d: key1 = 8 * 8; break; default: break; } //检测按下释放 while(temp != 0xf0) { //重新装入初值 temp = P3; temp &= 0xf0; } delay(5);//释放去抖 while(temp != 0xf0) { //重新装入初值 temp = P3; temp &= 0xf0; } //按键释放关闭蜂鸣器 FM = 1; } } //第三次矩阵按键检测 P3 = 0xfb; temp = P3; temp &= 0xf0; if(temp != 0xf0) { delay(5);//消抖 //重新装入检测初值 temp = P3; temp &= 0xf0; if(temp != 0xf0) { //将此时P3口的值赋给temp temp = P3; FM = 0;//蜂鸣器发声 //检测按下的是哪一个按键,行列检测 switch(temp) { case 0xeb: key1 = 9 * 9; break; case 0xdb: key1 = 10 * 10; break; case 0xbb: key1 = 11 * 11; break; case 0x7b: key1 = 12 * 12; break; default: break; } //检测按键释放 while(temp != 0xf0) { temp = P3; temp &= 0xf0; } delay(5); while(temp != 0xf0) { temp = P3; temp &= 0xf0; } //按键释放关闭蜂鸣器 FM = 1; } } //第四次检测矩阵按键 P3 = 0xf7;//第四行为低电平,其余行为高电平; temp = P3;//将待检测的值赋给temp; temp &= 0xf0; if(temp != 0xf0) { delay(5); //消抖 //重新装入检测初值 temp = P3; temp &= 0xf0; if(temp != 0xf0) { //确认有按键按下 //将此时的P3口的实际值赋给temp; temp = P3; FM = 0; //开始检测 switch(temp) { case 0xe7: key1 = 13 * 13; break; case 0xd7: key1 = 14 * 14; break; case 0xb7: key1 = 15 * 15; break; case 0x77: key1 = 16 * 16; break; default: break; } //检测按键释放 while(temp != 0xf0) { //重新装入初值 temp = P3; temp &= 0xf0; } delay(5); while(temp != 0xf0) { temp = P3; temp &= 0xf0; } //关闭蜂鸣器 FM = 1; } } } //定时器0中断服务子程序 void int_time0() interrupt 1 { TH0 = 0xB8; TL0 = 0X00; counter++; if(flag == 0) { //流水灯左移流动 if(counter % 1 == 0) { P1 = ~(1 << x++); if(x == 8) { x = 0; } } } else { //流水灯右移流动 if(counter % 1 == 0) { P1 = ~(0x80 >> x++); if(x == 8) { x = 0; } } } }

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台