求 用单片机AT89S52 4*4矩阵键盘 LCD1602 实现计算器的功能的C程序 .原理图 硬件 我以做出来

求 用单片机AT89S52 4*4矩阵键盘 LCD1602 实现计算器的功能的C程序 .原理图 硬件 我以做出来,第1张

这也收费,太缺德了。哥给你!

uchar keyval()

{

uchar a,b,i;

b=0xfe;

for(i=0;i<4;i++) //i为行号

{

KEY=b;a=KEY;

if((a&0x10)==0) keynum=i4; //第一列

if((a&0x20)==0) keynum=i4+1; //第二列

if((a&0x40)==0) keynum=i4+2; //第三列

if((a&0x80)==0) keynum=i4+3; //第四列

b<<=1;b++;

}

SpeakContinue(1);

return (keynum);

}

/延时/

void delay(uchar t)

{

uchar i=100;

while(t--)

{while(i--);}

}

void delay1(uchar time)

{

while(time--);

}

/LCD驱动/

//写控制字函数

void lcdcmd(uchar cmd)

{

RS=0;

RW=0;

DAT=cmd;

E=1;

_Nop();

_Nop();

E=0;

delay(2);

}

//写数据函数

void lcddata(uchar dat)

{ RS=1;

RW=0;

DAT=dat;

_Nop();

E=1;

_Nop();

_Nop();

E=0;

delay(2);

}

//LCD初始化函数

void lcdinit() //显示初始化

{

lcdcmd(0x38);

delay(2);

lcdcmd(0x38);

delay(2);

lcdcmd(0x38);

delay(2);

lcdcmd(0x01);

lcdcmd(0x06);

lcdcmd(0x0c);

}

记得给分

给你写一个吧,累死了,要采纳哦:

#include<reg51h>

#define uchar unsigned char

#define uint unsigned int

uchar code table0[]="Tempeture:";

uchar code table1[]="welcom to text!";

sbit lcdrs=P3^5;

//sbit lcdrw=P2^1;

sbit lcden=P3^4;

sbit ds=P2^2;

sbit beep=P2^3;

sbit dula=P2^6;

sbit wela=P2^7;

bit flag;

uchar num;

uint temp,t;

uchar temp_bai,temp_shi,temp_ge,temp_little;

float xs_temp;

void delay(uint z)//延时1ms子程序

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void ds_reset( ) //DS18B20初始化

{

uint i;

bit pw=1;

while(pw)

{

ds=1;

i++;

ds=0;

i=103;

while(i>0)i--;//835us

ds=1;

i=4;

while(i>0)i--;//35us

pw=ds;

}

i=70;

while(i>0)i--;//604us

ds=1;

}

void temp_wr_byte(uchar dat)//DS18B20写一个字节的数据子程序

{

bit testb;

uchar j;

uint i;

for(j=0;j<8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(testb) //textb为真写1,

{

ds=0; //i++;i++;

i=1;

while(i>0)i--; //至少1us

ds=1;

i=8;

while(i>0)i-- ; //66us

}

else

{

ds=0; //写0

i=8;

while(i>0)i--;

ds=1; //对IO线进行写0

i=1;

while(i>0)i--;

}

}

}

bit temp_rd_bit( ) //读一位数据子程序

{

uint i;

bit dat;

ds=1;

i=0;

ds=0; //2us

i++;

i++;

ds=1; //6us

i++; //3us

dat=ds;

i=4;

while(i>0)i--; //32us

return(dat);

}

uchar tempread( )//读一个字节数据

{

uchar i,j,dat;

dat=0;

for(i=0;i<8;i++)

{

j=temp_rd_bit( );

dat=(j<<7)|(dat>>1); //读出数据最低位在最前面,刚好一个字节在dat里

}

return(dat); //读了8次即8个字节

}

void tempchange( ) //启动温度转换

{

ds_reset( );

// delay(1);

temp_wr_byte(0xcc); //跳过ROM

temp_wr_byte(0x44); //启动温度转换

}

void temp_rec( ) //读取温度数据

{

uchar a,b;

ds_reset( );

// delay(1);

temp_wr_byte(0xcc);

temp_wr_byte(0xbe); //从暂存寄存器读字节

a=tempread( );

b=tempread( );

temp=b;

temp<<=8; //保留最高位

temp=temp|a;

if(temp<0x7fff)//是否为正数?

{

flag=0;

}

else

{

flag=1; //为负数时,温度数据要反向

temp=~temp+1;

}

xs_temp=temp00625; //分辨率为1/2^12

}

void write_com(uchar com)//液晶写指令 *** 作子程序

{

lcdrs=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_date(uchar date)//液晶写数据 *** 作子程序

{

lcdrs=1;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void lcd_init( )//液晶初始化子程序

{

dula=0;

wela=0;

lcden=0;//lcdrw=0;

write_com(0x38); //基本指令集

write_com(0x0c); //整体显示开,游标和游标位置关

write_com(0x06); //写一个字节时,地址指针加1,光标加1

write_com(0x01); // 清DDRAM

// write_com(0x80); //将DDRAM地址到地址计数器AC,12864中用

while(table1[num]!='\0')

{write_date(table1[num]);

num++;

delay(50);

}

}

void shujucl( )//数据处理子函数

{

t=xs_temp10; //小数点后边只显示1位,

temp_bai=t/1000+0x30; //让其显示0x3x,对应着asc的数字

temp_shi=t%1000/100+0x30;

temp_ge=t%100/10+0x30;

temp_little=t%10+0x30;

if(xs_temp<12||xs_temp>15)

beep=0;

else beep=1;

}

void xianshi( )

{ write_com(0x80); //设定DDRAM地址

for(num=0;num<11;num++)

{

write_date(table0[num]);

delay(5);

}

write_com(0x80+0x40); //设置显示到对应的地址

if(flag==1)

write_date('-'); //表示温度为负数

else

write_date(temp_bai);

write_com(0x8a+0x40); //设定到0x8b所在位

write_date(temp_shi);

write_com(0x8b+0x40);

write_date(temp_ge);

write_com(0x8c+0x40);

write_date('');

write_com(0x8d+0x40); //设置到第二个字节

write_date(temp_little);

delay(5);

}

void main( )

{

lcd_init( );

ds_reset( ) ;

while(1)

{

tempchange( ); //启动温度转换

temp_rec( ); //读取温度数据

shujucl( ); //数据处理

xianshi( ); //数据显示

}

}

#include <intrinsh>

#define uchar unsigned char

#define ROWP P3

#define LINP P2

void Delay(uchar i) {

uchar j;

for(;i>0;i--)

for(j=0;j<112;j++)

_nop_();

}

uchar Keyscan(){

uchar i,j,RLP,num;

for(i=0;i<4;i++){

LINP=(LINP|0xf0)&(~(0x10<<i));

Delay(1);

for(j=0;j<5;j++){

RLP=(ROWP|0x1f)&(~(0x10>>j));

if(ROWP==RLP){

Delay(2);

if(ROWP==RLP)

num=i5+j+1;

}

}

}

return num;

}

54的,稍微修改,就是44的

这个你看看可以参考!

#include<reg51h>

#include<intrinsh>

#define uint unsigned int

#define uchar unsigned char

uchar code table[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};

//这三个引脚参考资料

sbit E=P2^7; //1602使能引脚

sbit RW=P2^6; //1602读写引脚

sbit RS=P2^5; //1602数据/命令选择引脚

/

名称 : Delay_1ms()

功能 : 延时子程序,延时时间为 1ms x

输入 : x (延时一毫秒的个数)

输出 : 无

/

void Delay_1ms(uint i)//1ms延时

{

uchar x,j;

for(j=0;j<i;j++)

for(x=0;x<=148;x++);

}

/

名称 : delay()

功能 : 延时,延时时间大概为5US。

输入 : 无

输出 : 无

/

void delay()

{

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

}

/

名称 : bit Busy(void)

功能 : 这个是一个读状态函数,读出函数是否处在忙状态

输入 : 输入的命令值

输出 : 无

/

bit Busy(void)

{

bit busy_flag = 0;

RS = 0;

RW = 1;

E = 1;

delay();

busy_flag = (bit)(P0 & 0x80);

E = 0;

return busy_flag;

}

/

名称 : wcmd(uchar del)

功能 : 1602命令函数

输入 : 输入的命令值

输出 : 无

/

void wcmd(uchar del)

{

while(Busy());

RS = 0;

RW = 0;

E = 0;

delay();

P0 = del;

delay();

E = 1;

delay();

E = 0;

}

/

名称 : wdata(uchar del)

功能 : 1602写数据函数

输入 : 需要写入1602的数据

输出 : 无

/

void wdata(uchar del)

{

while(Busy());

RS = 1;

RW = 0;

E = 0;

delay();

P0 = del;

delay();

E = 1;

delay();

E = 0;

}

/

名称 : L1602_init()

功能 : 1602初始化,请参考1602的资料

输入 : 无

输出 : 无

/

void L1602_init(void)

{

wcmd(0x38);

wcmd(0x0c);

wcmd(0x06);

wcmd(0x01);

}

/

名称 : L1602_char(uchar hang,uchar lie,char sign)

功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下

L1602_char(1,5,'b')

输入 : 行,列,需要输入1602的数据

输出 : 无

/

void L1602_char(uchar hang,uchar lie,char sign)

{

uchar a;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

wcmd(a);

wdata(sign);

}

/

名称 : L1602_string(uchar hang,uchar lie,uchar p)

功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下

L1602_string(1,5,"ab cd ef;")

输入 : 行,列,需要输入1602的数据

输出 : 无

/

void L1602_string(uchar hang,uchar lie,uchar p)

{

uchar a,b=0;

if(hang == 1) a = 0x80;

if(hang == 2) a = 0xc0;

a = a + lie - 1;

while(1)

{

wcmd(a++);

b++;

if((p == '\0')||(b==16)) break;

wdata(p);

p++;

}

}

/

名称 : Keyscan()

功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。

输入 : 无

输出 : 按键值

/

uchar Keyscan(void)

{

uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};

for(j=0; j<4; j++)

{

P1 = Buffer[j];

temp = 0x10;

for(i=0; i<4; i++)

{

if(!(P1 & temp))

{

return (i+j4);

}

temp <<= 1;

}

}

}

/

名称 : Main()

功能 : 主函数

输入 : 无

输出 : 无

/

void Main(void)

{

uchar Key_Value; //读出的键值

L1602_init();

L1602_string(1,1," 44 KeyBoard ");

L1602_string(2,1,"You Press The ");

while(1)

{

P1 = 0xf0;

if(P1 != 0xf0)

{

Delay_1ms(20); //按键消抖

if(P1 != 0xf0)

{

Delay_1ms(20); //按键消抖

if(P1 != 0xf0)

{

Key_Value = Keyscan();

}

}

}

L1602_char(2,15,Key_Value / 10 + 48);

L1602_char(2,16,Key_Value % 10 + 48);

}

}

假设按下的是S1键进行如下检测(44键盘)

先在P3口输出

p3 00001111

低四位 行会有变化

cord_h =00001111&00001110 =00001110

if !=00001111

延时01us

cord_h=00001110&00001111=00001110

if !=00001111

P3再输出11111110

P3 =00001110|11110000=11111110

输出高四位

cord_l=P3&0xf0 //此时P3口就是输入值01111110 而不是上面的11111110

cord_l=01111110&11110000=01110000

cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码

#include <reg52h>//包含头文件

#define uchar unsigned char

#define uint unsigned int

unsigned char const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,

0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F

uchar keyscan(void);

void delay(uint i);

void main()

{

uchar key;

P2=0x00;//1数码管亮 按相应的按键,会显示按键上的字符

while(1)

{

key=keyscan();//调用键盘扫描,

switch(key)

{

case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值

case 0x7d:P0=table[1];break;//1

case 0x7b:P0=table[2];break;//2

case 0x77:P0=table[3];break;//3

case 0xbe:P0=table[4];break;//4

case 0xbd:P0=table[5];break;//5

case 0xbb:P0=table[6];break;//6

case 0xb7:P0=table[7];break;//7

case 0xde:P0=table[8];break;//8

case 0xdd:P0=table[9];break;//9

case 0xdb:P0=table[10];break;//a

case 0xd7:P0=table[11];break;//b

case 0xee:P0=table[12];break;//c

case 0xed:P0=table[13];break;//d

case 0xeb:P0=table[14];break;//e

case 0xe7:P0=table[15];break;//f

}

}

}

uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法

{

uchar cord_h,cord_l;//行列值

P3=0x0f; //行线输出全为0

cord_h=P3&0x0f; //读入列线值

if(cord_h!=0x0f) //先检测有无按键按下

{

delay(100); //去抖

cord_h=P3&0x0f; //读入列线值

if(cord_h!=0x0f)

{

P3=cord_h|0xf0; //输出当前列线值

cord_l=P3&0xf0; //读入行线值

return(cord_h+cord_l);//键盘最后组合码值

}

}return(0xff); //返回该值

}

void delay(uint i)//延时函数

{

while(i--);

}

void delay() //延时子程序

{

unsigned char n, m;

for (n = 100; n > 0; n--)

for (m = 300; m > 0; m--);

}

unsigned char Keycan(void) //按键扫描程序 P10--P13为行线 P14--P17为列线

{

unsigned char rcode, ccode;

P1 = 0xF0; // 发全0行扫描码,列线输入

if((P1&0xF0) != 0xF0) // 若有键按下

{

delay();// 延时去抖动

if((P1&0xF0) != 0xF0)

{ rcode = 0xFE; // 逐行扫描初值

while((rcode&0x10) != 0)

{

P1 = rcode; // 输出行扫描码

if((P1&0xF0) != 0xF0) // 本行有键按下

{

ccode = (P1&0xF0)|0x0F;

do{;}while((P1&0xF0) != 0xF0); //等待键释放

return ((~rcode) + (~ccode)); // 返回键编码

}

else

rcode = (rcode<<1)|0x01; // 行扫描码左移一位

}

}

}

return 0; // 无键按下,返回值为0

}

这个。。流水灯用for()语句来循环,循环内部用delay来延时控制流水的运转速度。

设置一个变量M,这个变量在每次循环的情况下都要赋值一次,从哪里赋值呢??就是判断一下你指定按键是否按下,按下了,这个变量M为1,没按下,这个变量M为0,然后你在for语句的中间那个判断表达式中加入一个条件:那就是这个变量M是(M=1就满足条件,继续循环,M=0不满足,就跳出循环)。这样就实现了按键终止循环的行为

然后你在for循环外边也不断判断这个按键的状态,并随时给这个M变量更新值,这样,你跳出来循环之后就不会回不去,如此的话,你就按住不放就会暂停,放开就继续流水

但是你如果要求按一下就流水,再按一下就暂停,第三次按又流水,那你将按键按下计数,然后根据你按下按键次数进行对流水灯的 *** 作。。。。。

以上就是关于求 用单片机AT89S52 4*4矩阵键盘 LCD1602 实现计算器的功能的C程序 .原理图 硬件 我以做出来全部的内容,包括:求 用单片机AT89S52 4*4矩阵键盘 LCD1602 实现计算器的功能的C程序 .原理图 硬件 我以做出来、求一个C程序:(温度控制系统)用矩阵键盘中的三个键设定温度调节然后再用1602液晶显示、4*4矩阵键盘控制四位数码管显示单片机C语言程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9280115.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存