注意:访问本站需要Cookie和JavaScript支持!请设置您的浏览器! 打开购物车 查看留言付款方式联系我们
初中电子 单片机教材一 单片机教材二
搜索上次看见的商品或文章:
商品名、介绍 文章名、内容
首页 电子入门 学单片机 免费资源 下载中心 商品列表 象棋在线 在线绘图 加盟五一 加入收藏 设为首页
本站推荐:
简易计算器,用1602显示,红外线输入,请多指教
文章长度[19170] 加入时间[2007/12/14] 更新时间[2024/12/7 11:02:38] 级别[3] [评论] [收藏]

10为"0"


11为小数点


12为"="号


13/14/15/16为加/减/乘/除


这个是输出程序PUTCHAR.C


#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^5;
sbit P1_7=P1^7;
static bit biao;


static delayn(uint j) //延时
{ uint i;
for(i=0;i<j;i++)
{;}
}
static void Nop()
{;}


static mang() //检查忙信号
{ P1|=0xff;
RS=0;
RW=1;
E=1;
Nop();
while(P1_7);
E=0;
Nop();
Nop();
}


static void writer(uchar mn,i) //写命令
{ if (i==1)
mang(); //i=1检查忙
RS=0;
RW=0;
P1=mn;
E=1;
Nop();
Nop();
E=0;
Nop();

}
static void wrdata(uchar da,i) //写数据
{ if (i==1)
mang();
RS=1;
RW=0;
P1=da;
E=1;
Nop();
Nop();
E=0;
Nop();
}
void rest() //复位
{ delayn(15000);
writer(0x38,0);
delayn(5000);
writer(0x38,0);
delayn(5000);
writer(0x38,1);
writer(0x01,1);
writer(0x06,1);
writer(0x0f,1);
writer(0x80,1);
}
//static uchar code type[]={"0123456789abcdef"};
uchar putchar(uchar c)
{ if(c=='\n') //换行
{ if(!biao)
{ writer(0xc0,1);
biao=1;
}
else
{ writer(0x80,1);
biao=0;
}
}
else if(c=='s') //清屏
{ writer(0x01,1);
writer(0x80,1); //回到首行
biao=0;
}
else
{ wrdata(c,1); //写字符
return (c);
}
}


这个是输入程序GETKEY.C


#include "reg51.h"


#define uchar unsigned char
#define uint unsigned int
sbit in=P3^7;
sbit P1_1=P1^1;
sbit P3_3=P3^3;
uchar bdata message,dat[4];
uchar mess,incon,suma,j;
uint k,*m;


sbit redmsg=message^0; //红外线遥控消息
sbit redread=message^1; //红外接收过程完


void t0int() interrupt 1 //定时中0
{ if(mess!=3)
mess++;
switch(mess)
{ case 1:
if(in) //8ms内为低电平,出错
{ redmsg=0;
mess=0;
}
else
{ while(1)
{ if(in) //等待高电平取同步
{ TH0=0xed;
TL0=0x7c; //4.74ms中断,闭过4.5ms结果码
redread=1; //接收过程标志位
break;
}
}
}
break;
case 2:
while(1)
{ if(in) //取同步
{TH0=0xfc;
TL0=0x8e; //0.882ms延时
break;
}
}
break;
case 3:
TR0=0;
TH0=0xfc;
TL0=0x8e; //延时0.882MS
if(incon==8)
{ j=j+1;
incon=0;
}
incon=incon+1;
if(in) //如果IN为1,则加1后左移,否则直接左移
{ dat[j]=dat[j]>>1;
dat[j]=dat[j]+128;
while(in);
while(!in);
}
else
{ dat[j]=dat[j]>>1;
while(!in);
}
if((incon==8)&(j==3)) //32位接收完,退出
{ redread=1; //接收完成
j=0;
incon=0;
redmsg=0;
mess=0;
P1_1=0;
}
TR0=1;
break;
}
}


bit panduan() //判断接收是否正确
{ TR0=0;
if(dat[0]!=0x00)
return(0);
if(dat[1]!=0xff)
return(0);
if(dat[2]!=(~dat[3]))
return(0);
return(1);
}
daima()
{
switch(dat[2])
{ case 0x10:suma='1';break;
case 0x03:suma='2';break;
case 0x01:suma='3';break;
case 0x06:suma='4';break;
case 0x09:suma='5';break;
case 0x1d:suma='6';break;
case 0x1f:suma='7';break;
case 0x0d:suma='8';break;
case 0x19:suma='9';break;
case 0x1b:suma='0';break;
case 0x11:suma='.';break;
case 0x15:suma='=';break;
case 0x17:suma='+';break;
case 0x12:suma='-';break;
case 0x16:suma='*';break;
case 0x4c:suma='/';break;
case 0x40:suma=' ';break;
default :suma='0';break;
}
}
lia() //连发处理子函数
{ uint i;
m=&k;
for(i=0;i<1000;i++) //4MS之后.还是低电平,则为连发
{ if(in)
return;
}
while(!in);
*m=0; //K值清0
}

uchar _getkey()
{ while(1)
{ if(!in)
redmsg=1;
if(redmsg)
{ TH0=0xde;
TL0=0xcc; //8.5ms中断
TR0=1;
ET0=1;
}
else
{ TR0=0;
ET0=0;
}
while(redmsg);
if(panduan()&redread) //判断接收是否正确
{ TR0=0;
daima(); //解代码
for(k=0;k<10000;k++) //118MS内出现低电平,可能连发
{ if(!in) //判断是否有连发
lia(); //如果有,执行
}
redread=0;
return(suma);
}
}
}


这个是计算程序JISAN.C


#include <reg52.h>
#include <stdio.h>
#include <stdlib.h> //函数atol()
#define uchar unsigned char
#define uint unsigned int
extern void rest();
bit biao1=0,biaoden=0;
uchar value[10] _at_ 0x30;
uint a,c;
char b,n;
float x,y,d;
void del() //延时函数
{ uchar j;
for(j=0;j<=10;j++)
value[j]=0;
}


float getvalue()
{ uchar j;
char k;
del();
while(1)
{ for(j=0;j<10;j++)
{ k=getkey();
if(biaoden)
{ putchar('s');
biaoden=0;
}
putchar(k);
if((k>='0')&(k<='9')|(k=='.')) //数字0-9
{ if(j<=9)
{ value[j]=k;
biao1=1;
}
else
return(atof(value));
}
else
{ b=k; //输入的为符号
return(atof(value));
}
}
}
}


void main()
{ TMOD=0x11; //T1,T0都工作于方式1
EA=1; //允许中断
rest();
while(1)
{ start: x=getvalue(); //输入的数据
if(!biao1) //输入的为符号
x=d;
if(b==' ') //收到清0
{ x=0;
d=0;
putchar('s');
goto start;
}
n=b;
del();
y=getvalue();
biao1=0;
switch(n) //判断运算方法
{ case '+': d=x+y ;
break ;
case '-': d=x-y ;
break ;
case '*': d=x*y ;
break ;
case '/': d=x/y ;
break ;
case '=': putchar(d) ;
x=d ;
biaoden=1 ;
break ;
case ' ': d=0 ; //为清除键
x=0 ;
putchar('s') ;
goto start ;
}
if(b=='=')
{ biaoden=1;
putchar('s');
printf("%g%c%g=\n",x,n,y);
printf("%g",d);
putchar('\n');
}
if(b==' ')
{ d=0;
x=0;
putchar('s');
}
}
}


把这三个程序放到一个工程里就OK了,程序有点大要用52系列的单片机!


请高手多多指教


发贴心情

呵呵,没想到这个兄弟,在我之前把代码给贴出来了


我也来一份了!


/********************************************************************************/
/* Project: 计算器(Calculator) 版本号:V1。0 */
/* */
/* */
/* Designed By: whoami CPU:AT89S51 or C51 */
/* */
/* */
/* 键盘布局如下: */
/* K2(0) K4(1) K6(2) K8(3) K10(8) K12(9) K14(.) K16(+) */
/* K3(4) K5(5) K7(6) K9(7) K11(-) K13(*) K15(/) K17(=) */
/* */
/* 功能描述: */
/* 可以运算+,-,*,/等计算,运算的长度可以自行设定 */
/* 修改 Max_disp_buff 即可。 */
/* */
/* http://www.mculover.net */
/* http://www.mculover.net/bbs 湘灵电子版权所有 */
/* */
/* 转载请保留以上信息,谢谢合作 ! */
/* */
/********************************************************************************/


#include <reg51.h>
#include <math.h>
#include <stdlib.h>


#define Lcd_Data P0 //定义数据端口
#define TH0_TL0 (65536-5000)//设定中断的间隔时长


#define Max_disp_buff 10 //定义最大的显示位数
#define Key_con P1 //定义44键盘的连接口线


sbit RS = P2 ^ 0; //定义和LCM的连接端口
sbit RW = P2 ^ 1;
sbit E = P2 ^ 2;
sbit Busy = P0 ^ 7;


unsigned char Key_value, Time_delay;
static float left_value = 0;
static float right_value = 0;


//开机画面预定义
unsigned char code welcome[] = {"Welcome to : "};
unsigned char code website[] = {"www.mculover.net"};
unsigned char code designed[]= {"Designed By: "};
unsigned char code whoami[] = {" whoami"};


//定义数组变量
unsigned char code keycodes[16]={'0','1','2','3','4','5','6','7','8','9','.','+','-','*','/','=',};
unsigned char number[Max_disp_buff + 1];//定义按键数字的缓冲大小


//函数声明
void Delay(unsigned char x);//延时处理
void Delay_1ms(unsigned char t);//延时子程序,延时 1MS*t S
unsigned char Read_key(void);//按键处理,返回按键的值
unsigned char Test_key(void);//按键检测函数
void Read_Busy(void);//读忙信号判断
void Write_Comm(unsigned char lcdcomm); //写指令函数
void Write_Data(unsigned char lcddata);//写数据函数
void Init_LCD_Cal(void);//初始化LCD
void Init_LCD_Logo(void);//初始化LCD
void Init_Timer0(void);//定时器0初始化
void Display (char *buf); //显示函数
void Display_Logo(unsigned char code *DData);//显示LOGO
void Digit_input_calcul(void);//字符输入
void Fun_calculator(unsigned int fuhao);//运算函数
void Calculator_output(float value);//输出计算结果函数
void Show_logo(void);//显示开机画面


/******************************************************************************/
void Delay(unsigned char x)//延时处理
{
Time_delay = x;


while(Time_delay != 0);
}


/******************************************************************************/
void Delay_1ms(unsigned char t)//延时子程序,延时 1MS*t S
{
unsigned char a;
while(--t != 0)
{
for(a = 0; a < 125; a++);
}
}


/******************************************************************************/
unsigned char Read_key(void)//按键处理,返回按键的值
{
unsigned char j, k, s, key;


Key_con = 0xf0;//

if(Key_con != 0xf0)
{
Delay_1ms(30);//延时消抖
if(Key_con != 0xf0)
{
Key_con=0xfe;
k=0xfe;
for(j=0;j<4;j++)
{
s=Key_con & 0xf0;
switch(s)
{
case 0xe0: key=4*j+0; break;
case 0xd0: key=4*j+1; break;
case 0xb0: key=4*j+2; break;
case 0x70: key=4*j+3; break;
default: break;
}
k = (k << 1) | 0x01;
Key_con = k;


}//for

Key_value = keycodes[key];
}
}//if

else
Key_value = 0x00;//如果为O, 则表示无键按下


return Key_value;
}


/******************************************************************************/
void Timer0_int(void) interrupt 1 using 1//定时0中断处理
{
// 调整出入栈的时间,在精度不高的场合可不要!
TR0 = 0;
TL0 += (TH0_TL0 + 9) % 256;
TH0 += (TH0_TL0 + 9) / 256 + (char)CY;
TR0 = 1;


if(Time_delay != 0)//延时函数用
{
Time_delay--;
}


Read_key();//读取键盘的值
}


/******************************************************************************/
unsigned char Test_key(void)//按键检测函数
{
unsigned char mykey;


while((mykey = Key_value) == 0x00);//等待


return mykey;
}


/******************************************************************************/
void Read_Busy(void)//读忙信号判断
{
do{
Lcd_Data = 0xff;
RS = 0;
RW = 1;
E = 0;
Delay(2);//调用中断延时
E = 1;
}while(Busy);
}


/******************************************************************************/
void Write_Comm(unsigned char lcdcomm) //写指令函数
{
Lcd_Data = lcdcomm;
RS = 0;
RW = 0;
E = 0;
Read_Busy();
E = 1;
}


/******************************************************************************/
void Write_Data(unsigned char lcddata)//写数据函数
{
Lcd_Data = lcddata;
RS = 1;
RW = 0;
E = 0;
Read_Busy();
E = 1;
}


/******************************************************************************/
void Init_LCD_Cal(void)//初始化LCD
{
Delay_1ms(400); //稍微延时,等待LCM进入工作状态
Write_Comm(0x01);//清显示


Write_Comm(0x38); // 8位 2行.
Write_Comm(0x0c); //
Write_Comm(0x07); // 显示模式,从左至右增加
Write_Comm(0x80+0x10); // 定义首地址.
}


/******************************************************************************/
void Init_LCD_Logo(void)//初始化LCD
{
Delay_1ms(400); //稍微延时,等待LCM进入工作状态
Write_Comm(0x01);//清显示


Write_Comm(0x38);//8位2行5*8
Write_Comm(0x06);//文字不动,光标右移
Write_Comm(0x0c);//显示开/关,光标开闪烁开
}


/******************************************************************************/
void Init_Timer0(void)//定时器0初始化
{
TMOD=0x01;
TH0=TH0_TL0 / 256;
TL0=TH0_TL0 % 256;
TR0=1;
ET0=1;
EA=1;
}


/******************************************************************************/
void Display(char *buf)//显示函数
{
unsigned char i;

Write_Comm(0x01);//clearscreen,清屏命令
Write_Comm(0x80+0x10);


for (i=0 ; buf[i] != 0; i++)
Write_Data(buf[i]);
}


/******************************************************************************/
void Display_Logo(unsigned char code *DData)//显示LOGO
{
unsigned char j;

for(j=0;j<16;j++)
{
Write_Data(DData[j]); //显示单个字符
Delay(20);
}
}


/*******************************************************************************/
void Digit_input_calcul(void)//字符输入
{
static unsigned char pos;
float tmp;


unsigned int last_op = 0;


Write_Data('0'); //上电显示" 0 "
pos = 0;//位置为0


while(1)
{
Key_value = Test_key();//判断是数字还是运算符号,具有等待功能


if((Key_value == '.') || ((Key_value >= '0') && (Key_value <= '9')))//如果是数字或小数点
{
if (pos != Max_disp_buff ) //最大计算位
{
number[pos++] = Key_value;
number[pos] = 0;
Display(number);
}
}
else //如果输入的是运算符号(+,-,*,/,=)
{


tmp = atof(number);//atof函数就是把字符转换成双精度的值


if((Key_value == '+') || (Key_value == '-') || (Key_value == '*') || (Key_value == '/'))
{
left_value = tmp;
last_op = Key_value;
}
else if (Key_value == '=')
{
right_value = tmp;


Fun_calculator(last_op);//计算
}

pos = 0;//从新归位,输入右值
}//else
}//for
}


/**********************************************************************************/
void Fun_calculator(unsigned int fuhao)//运算函数
{
bit result = 1;


switch(fuhao)
{
case '+': left_value += right_value;result = 1;break;
case '-': left_value -= right_value;result = 1;break;
case '*': left_value *= right_value;result = 1;break;
case '/':
if(right_value != 0)
{
left_value /= right_value;
result = 1;
}
else
result = 0;//出错
break;
default : break;
}


if(result == 1)
Calculator_output(left_value);
else
Display("*ERROR*");
}


/******************************************************************************/
void Calculator_output(float value)//输出计算结果函数
{
unsigned char buff[Max_disp_buff + 1];//定义显示缓冲
unsigned char p1=0, p=0;
float divisor = 100000000;//除数
float digit = 0;


if(value >= 0)
buff[p++] = ' ';
else
{
buff[p++] = '-';
value = -value;
}


if(value >= divisor )
buff[p++]='E';
else
while((p < Max_disp_buff ) && (divisor > 1 || value >= 0.00000001))
{
divisor /= 10;
digit = floor(value/divisor);//小于指定数的最小整数
if (divisor < 1 && divisor > 0.01)
buff[p++] = '.';
if (digit != 0 || divisor < 10)
{
buff[p++] = digit + '0';
p1 = 1;
}
else if (p1)
buff[p++] = '0';
value -= digit*divisor;
}
buff[p] = 0;
Display(buff);
}


/******************************************************************************/
void Show_logo(void)//显示开机画面
{
Write_Comm(0x80);//写入"welcome to"首地址(第一行)
Display_Logo(welcome);


Write_Comm(0xc0);//写入"website"首地址(第2行)
Display_Logo(website);
Delay(200);


Write_Comm(0x01);//清屏


Write_Comm(0x80);//写入"designed "首地址(第一行)
Display_Logo(designed);



Write_Comm(0xc0);//写入"whoami"首地址(第2行)
Display_Logo(whoami);
Delay(200);


Write_Data(0x01);//清屏
}


/******************************************************************************/
void main(void)//主函数
{
Init_Timer0();//初始化T0
Init_LCD_Logo(); //初始化 Logo


Show_logo();//开机画面显示

Init_LCD_Cal(); //初始化 LCM
Digit_input_calcul();//计算值输入函数
}

1、 本站不保证以上观点正确,就算是本站原创作品,本站也不保证内容正确。
2、如果您拥有本文版权,并且不想在本站转载,请书面通知本站立即删除并且向您公开道歉! 以上可能是本站收集或者转载的文章,本站可能没有文章中的元件或产品,如果您需要类似的商品请 点这里查看商品列表!
本站协议 | 版权信息 |  关于我们 |  本站地图 |  营业执照 |  发票说明 |  付款方式 |  联系方式
深圳市宝安区西乡五壹电子商行——粤ICP备16073394号-1;地址:深圳西乡河西四坊183号;邮编:518102
E-mail:51dz$163.com($改为@);Tel:(0755)27947428
工作时间:9:30-12:00和13:30-17:30和18:30-20:30,无人接听时可以再打手机13537585389