標(biāo)題:
簡(jiǎn)易單片機(jī)計(jì)算器程序設(shè)計(jì) LCD1602顯示
[打印本頁]
作者:
2992606192
時(shí)間:
2023-11-28 10:27
標(biāo)題:
簡(jiǎn)易單片機(jī)計(jì)算器程序設(shè)計(jì) LCD1602顯示
基于51單片機(jī)的簡(jiǎn)易計(jì)算器設(shè)計(jì) 單片機(jī)型號(hào)選擇STC89C52RC,讀取16*16矩陣式鍵盤對(duì)應(yīng)的鍵值,可以進(jìn)行五位數(shù)的加、減、乘、除運(yùn)算,計(jì)算結(jié)果通過LCD1602顯示,并可通過AT24C02存儲(chǔ)模塊對(duì)計(jì)算結(jié)果進(jìn)行存儲(chǔ)與調(diào)用。
IMG_3221.JPG
(2.65 MB, 下載次數(shù): 30)
下載附件
實(shí)物演示
2023-11-28 10:26 上傳
單片機(jī)源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^5; //指令or數(shù)據(jù)
sbit wela=P2^6; //讀or寫
sbit lcden=P2^7; //使能信號(hào)
sbit K1 = P2^3;
sbit K2 = P2^2;
sbit I2C_SCL = P2^1;
sbit I2C_SDA = P2^0;
uchar code table[]= " ";
//uchar code XUEHAO[]= "190302051";
long int data_a,data_b; //第一個(gè)數(shù)和第二個(gè)數(shù)
long int data_c; //計(jì)算結(jié)果
uchar dispaly[10]; //顯示緩沖
//--聲明全局變量--//
void I2C_Delay10us();
void I2C_Start(); //起始信號(hào):在I2C_SCL時(shí)鐘信號(hào)在高電平期間I2C_SDA信號(hào)產(chǎn)生一個(gè)下降沿
void I2C_Stop(); //終止信號(hào):在I2C_SCL時(shí)鐘信號(hào)高電平期間I2C_SDA信號(hào)產(chǎn)生一個(gè)上升沿
uchar I2C_SendByte(uchar dat, uchar ack);//使用I2c讀取一個(gè)字節(jié)
uchar I2C_ReadByte(); //通過I2C發(fā)送一個(gè)字節(jié)。在I2C_SCL時(shí)鐘信號(hào)高電平期間,保持發(fā)送信號(hào)I2C_SDA保持穩(wěn)定
void I2C_Delay10us()
{
uchar a, b;
for(b=1; b>0; b--)
{
for(a=2; a>0; a--);
}
}
void I2C_Start()
{
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立時(shí)間是I2C_SDA保持時(shí)間>4.7us
I2C_SDA = 0;
I2C_Delay10us();//保持時(shí)間是>4us
I2C_SCL = 0;
I2C_Delay10us();
}
void I2C_Stop()
{
I2C_SDA = 0;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();//建立時(shí)間大于4.7us
I2C_SDA = 1;
I2C_Delay10us();
}
uchar I2C_SendByte(uchar dat, uchar ack)
{
uchar a = 0,b = 0;//最大255,一個(gè)機(jī)器周期為1us,最大延時(shí)255us。
for(a=0; a<8; a++)//要發(fā)送8位,從最高位開始
{
I2C_SDA = dat >> 7;
dat = dat << 1;
I2C_Delay10us();
I2C_SCL = 1;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
I2C_SDA = 1;
I2C_Delay10us();
I2C_SCL = 1;
while(I2C_SDA && (ack == 1))
{
b++;
if(b > 200)
{
I2C_SCL = 0;
I2C_Delay10us();
return 0;
}
}
I2C_SCL = 0;
I2C_Delay10us();
return 1;
}
uchar I2C_ReadByte()
{
uchar a = 0,dat = 0;
I2C_SDA = 1; //起始和發(fā)送一個(gè)字節(jié)之后I2C_SCL都是0
I2C_Delay10us();
for(a=0; a<8; a++)//接收8個(gè)字節(jié)
{
I2C_SCL = 1;
I2C_Delay10us();
dat <<= 1;
dat |= I2C_SDA;
I2C_Delay10us();
I2C_SCL = 0;
I2C_Delay10us();
}
return dat;
}
void AT24C02Write(unsigned char addr,unsigned char dat)
{
I2C_Start();
I2C_SendByte(0xa0, 1);//發(fā)送寫器件地址
I2C_SendByte(addr, 1);//發(fā)送要寫入內(nèi)存地址
I2C_SendByte(dat, 0); //發(fā)送數(shù)據(jù)
I2C_Stop();
}
unsigned char AT24C02Read(unsigned char addr)
{
unsigned char num;
I2C_Start();
I2C_SendByte(0xa0, 1); //發(fā)送寫器件地址
I2C_SendByte(addr, 1); //發(fā)送要讀取的地址
I2C_Start();
I2C_SendByte(0xa1, 1); //發(fā)送讀器件地址
num=I2C_ReadByte(); //讀取數(shù)據(jù)
I2C_Stop();
return num;
}
void LCD_Delay_us(unsigned int t)
{
while(t--); //t=0,退出
}
void LCD_Delay_ms(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++) //執(zhí)行t次循環(huán)
for(j=0;j<113;j++) //執(zhí)行113次循環(huán)
;
}
void write_com(uchar com) //1602液晶寫指令
{
rs=0; //寫指令
lcden=0; //使能1602
P0=com; //寫入指令com
LCD_Delay_ms(1); //延時(shí)1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延時(shí)2ms
lcden=0; //使能1602
}
void write_date(uchar date) //1602液晶寫數(shù)據(jù)
{
rs=1; //寫數(shù)據(jù)
lcden=0; //使能1602
P0=date; //寫入數(shù)據(jù)date
LCD_Delay_ms(1); //延時(shí)1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延時(shí)2ms
lcden=0; //使能1602
}
void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xc0 + x);} //第二行
write_date( Data); //寫入數(shù)據(jù)
}
//指定x,y寫入字符串函數(shù)
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0){write_com(0x80 + x);} //第一行
else{write_com(0xC0 + x);} //第二行
while (*s) //
{write_date( *s); s++;} //寫入數(shù)據(jù)
}
void init_lcd(void) //初始化液晶,及畫面初始化
{
wela=0; //寫液晶
lcden=0; //使能1602
write_com(0x38); //8 位總線,雙行顯示,5X7 的點(diǎn)陣字符
LCD_Delay_us(100); //延時(shí)100us
write_com(0x0c); //開顯示,無光標(biāo),光標(biāo)不閃爍
write_com(0x06); //光標(biāo)右移動(dòng)
write_com(0x01); //清屏
write_com(0x80); //DDRAM 地址歸0
}
short keycheckdown() /* 反轉(zhuǎn)法鍵盤掃描 */
{
short temp1,temp2,temp,a=0xff;
P1=0xf0; /* 輸入行值(或列值) */
LCD_Delay_ms(20); /* 延時(shí) */
temp1=P1; /* 讀列值(或行值) */
P1=0xff;
LCD_Delay_ms(20); /* 延時(shí) */
P1=0x0f; /* 輸入列值(或行值) */
LCD_Delay_ms(20); /* 延時(shí) */
temp2=P1; /* 讀行值(或列值) */
P1=0xff;
temp=(temp1&0xf0)|(temp2&0xf); /* 將兩次讀入數(shù)據(jù)組合 */
switch(temp) /* 通過讀入數(shù)據(jù)組合判斷按鍵位置 */
{
case 0x77 :a=0x0d;break;// 按鍵/
case 0x7b :a=0x0e; break;// 按鍵=
case 0x7d :a=0; break;// 按鍵0
case 0x7e :a=0x0f; break;// 按鍵CE
case 0xb7 :a=0x0c;break;// 按鍵*
case 0xbb :a=0x9;break; // 按鍵9
case 0xbd :a=0x8;break; // 按鍵8
case 0xbe :a=0x7;break; // 按鍵7
case 0xd7 :a=0x0b;break;// 按鍵-
case 0xdb :a=0x6;break; // 按鍵6
case 0xdd :a=0x5;break; // 按鍵5
case 0xde :a=0x4;break; // 按鍵4
case 0xe7 :a=0x0a; break;// 按鍵+
case 0xeb :a=3;break; // 按鍵3
case 0xed :a=2;break; // 按鍵2
case 0xee :a=1;break; // 按鍵1
default :a=0xff;
}
return a; /* 返回按鍵值 */
}
void display_a() //顯示數(shù)據(jù)a
{
dispaly[4]=data_a%100000/10000;
dispaly[3]=data_a%10000/1000; //千
dispaly[2]=data_a%1000/100; //百
dispaly[1]=data_a%100/10; //十
dispaly[0]=data_a%10; //個(gè)
write_com(0x80+0); //顯示數(shù)據(jù)a
if(data_a>9999){ write_date('0'+dispaly[4]); }
if(data_a>999){ write_date('0'+dispaly[3]);} //顯示千位
if(data_a>99){ write_date('0'+dispaly[2]);} //顯示百位
if(data_a>9){ write_date('0'+dispaly[1]);} //顯示十位
write_date('0'+dispaly[0]); //顯示個(gè)位
}
void display_b() //顯示數(shù)據(jù)b
{
write_com(0x80+7); //第一行
dispaly[4]=data_b%100000/10000;
dispaly[3]=data_b%10000/1000; //千
dispaly[2]=data_b%1000/100; //百
dispaly[1]=data_b%100/10; //十
dispaly[0]=data_b%10; //個(gè)
if(data_b>9999){ write_date('0'+dispaly[4]); }
if(data_b>999){ write_date('0'+dispaly[3]); } //顯示千位
if(data_b>99) { write_date('0'+dispaly[2]); } //顯示百位
if(data_b>9) { write_date('0'+dispaly[1]); } //顯示十位
write_date('0'+dispaly[0]); //顯示個(gè)位
}
void display_c(x)
{
if(data_c<100000000&&data_c>-1)//溢出時(shí)顯示錯(cuò)誤
{
dispaly[8]=data_c%1000000000/100000000; //萬萬
dispaly[7]=data_c%100000000/10000000; //千萬
dispaly[6]=data_c%10000000/1000000; //百萬
dispaly[5]=data_c%1000000/100000; //十萬
dispaly[4]=data_c%100000/10000; //萬
dispaly[3]=data_c%10000/1000; //千
dispaly[2]=data_c%1000/100; //百
dispaly[1]=data_c%100/10; //十
dispaly[0]=data_c%10; //個(gè)
write_com(0x80+6+0x40); //第一行
if(x==4)
{
if(data_c>99999999) { write_date('0'+dispaly[8]);} //顯示萬萬
if(data_c>9999999) { write_date('0'+dispaly[7]);} //千萬
if(data_c>999999) { write_date('0'+dispaly[6]);} //百萬
if(data_c>99999) { write_date('0'+dispaly[5]);} //十萬
write_date('0'+dispaly[4]); //萬
write_date('.');
write_date('0'+dispaly[3]); //千
write_date('0'+dispaly[2]); //百
write_date('0'+dispaly[1]); //十
write_date('0'+dispaly[0]); //個(gè)
}
else{
if(data_c>99999999) { write_date('0'+dispaly[8]);} //顯示萬萬
if(data_c>9999999) { write_date('0'+dispaly[7]);} //千萬
if(data_c>999999) { write_date('0'+dispaly[6]);} //百萬
if(data_c>99999) { write_date('0'+dispaly[5]);} //十萬
if(data_c>9999) { write_date('0'+dispaly[4]);} //萬
if(data_c>999) { write_date('0'+dispaly[3]);} //千
if(data_c>99) { write_date('0'+dispaly[2]);} //百
if(data_c>9) { write_date('0'+dispaly[1]);} //十
write_date('0'+dispaly[0]); //個(gè)
}
}
else //溢出時(shí)顯示錯(cuò)誤
{
write_com(0x80+11+0x40); //第一行
write_date('E'); //顯示 E
write_date('r'); //顯示R
write_date('r'); //顯示R
write_date('o'); //顯示O
write_date('r'); //顯示E
}
}
復(fù)制代碼
原理圖: 無
仿真: 無
代碼:
程序代碼.7z
(34.48 KB, 下載次數(shù): 11)
2023-11-28 10:27 上傳
點(diǎn)擊文件名下載附件
完整程序
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1