久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機計算器源程序 1602液晶顯示
[打印本頁]
作者:
535663152
時間:
2018-4-9 21:53
標題:
單片機計算器源程序 1602液晶顯示
可以用語音來實現加減乘除之類計算 并顯示到1602上面
單片機源程序如下:
/*
接盤按鍵說明:
--------------------------------------------------
| 1 | 2 | 3 | + |
- - - - - - - - - - - - -
| 4 | 5 | 6 | - |
- - - - - - - - - - - - -
| 7 | 8 | 9 | * |
- - - - - - - - - - - - -
| C | 0 | = | / |
--------------------------------------------------*/
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define XTAL 12000000 //CPU晶振頻率
#define baudrate 9600 //通信波特率
//--------LCD1602-------------------
//P00-07==== D0-7
sbit rs=P1^5; //指令or數據 2.6
sbit wela=P1^4; //讀or寫 2.5
sbit lcden=P1^6; //使能信號 2.7
sbit feng=P1^0; //蜂鳴器
//--------LCD1602-------------------
//--------KEY-----------------------
//P1口
//--------KEY-----------------------
uchar code table[]= " ";
unsigned char data_a,data_b; //計算結果
unsigned char data_c;
unsigned char num1; //第一個數
unsigned char num2; //第二個數
unsigned char count; //一個起識別作用的變量
unsigned char yusuanfu; //加減乘除等運算符
uchar dispaly[10]; //顯示緩沖
//************************************************************************/
// 描述: 延時t us函數
//************************************************************************/
void LCD_Delay_us(unsigned int t)
{
while(t--); //t=0,退出
}
//************************************************************************/
// 描述: 延時t ms函數
//************************************************************************/
void LCD_Delay_ms(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++) //執行t次循環
for(j=0;j<113;j++) //執行113次循環
;
}
//************************************************************************/
// 描述: 1602液晶寫指令
//************************************************************************/
void write_com(uchar com) //1602液晶寫指令
{
rs=0; //寫指令
lcden=0; //使能1602
P2=com; //寫入指令com
LCD_Delay_ms(1); //延時1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延時2ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:1602液晶寫數據
//************************************************************************/
void write_date(uchar date) //1602液晶寫數據
{
rs=1; //寫數據
lcden=0; //使能1602
P2=date; //寫入數據date
LCD_Delay_ms(1); //延時1ms
lcden=1; //使能1602
LCD_Delay_ms(2); //延時2ms
lcden=0; //使能1602
}
//************************************************************************/
// 描述:指定x,y寫入字符函數
//************************************************************************/
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); //寫入數據
}
//指定x,y寫入字符串函數
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++;} //寫入數據
}
//************************************************************************/
// 描述:初始化液晶,及畫面初始化
//************************************************************************/
void init_lcd(void) //初始化液晶,及畫面初始化
{
wela=0; //寫液晶
lcden=0; //使能1602
write_com(0x38); //8 位總線,雙行顯示,5X7 的點陣字符
LCD_Delay_us(100); //延時100us
write_com(0x0c); //開顯示,無光標,光標不閃爍
write_com(0x06); //光標右移動
write_com(0x01); //清屏
write_com(0x80); //DDRAM 地址歸0
}
//************************************************************************/
// 描述: 反轉法鍵盤掃描
//************************************************************************/
short keycheckdown() /* 反轉法鍵盤掃描 */
{
short temp1,temp2,temp,a=0xff;
P1=0xf0; /* 輸入行值(或列值) */
LCD_Delay_ms(20); /* 延時 */
temp1=P1; /* 讀列值(或行值) */
P1=0xff;
LCD_Delay_ms(20); /* 延時 */
P1=0x0f; /* 輸入列值(或行值) */
LCD_Delay_ms(20); /* 延時 */
temp2=P1; /* 讀行值(或列值) */
P1=0xff;
temp=(temp1&0xf0)|(temp2&0xf); /* 將兩次讀入數據組合 */
switch(temp) /* 通過讀入數據組合判斷按鍵位置 */
{
case 0x77 :a=0x0d;break; // 按鍵/ 77
case 0xb7 :a=0x0e; break;// 按鍵= 7b
case 0xd7 :a=0; break;// 按鍵0 7d
case 0xe7 :a=0x0f; break;// 按鍵CE 7e
case 0x7b :a=0x0c;break;// 按鍵* b7
case 0xbb :a=0x9;break; // 按鍵9 bb
case 0xdb :a=0x8;break; // 按鍵8 bd
case 0xeb :a=0x7;break; // 按鍵7 be
case 0x7d :a=0x0b;break;// 按鍵- d7
case 0xbd :a=0x6;break; // 按鍵6 db
case 0xdd :a=0x5;break; // 按鍵5 dd
case 0xed :a=0x4;break; // 按鍵4 de
case 0x7e :a=0x0a; break;// 按鍵+ e7
case 0xbe :a=3;break;// 按鍵3 eb
case 0xde :a=2;break;// 按鍵2 ed
case 0xee :a=1;break;// 按鍵1 ee
default :a=0xff;
}
return a; /* 返回按鍵值 */
}
void display_a() //顯示運算結果
{
dispaly[3]=data_a%10000/1000; //千
dispaly[2]=data_a%1000/100; //百
dispaly[1]=data_a%100/10; //十
dispaly[0]=data_a%10; //個
write_com(0x80+7); //顯示運算結果在7的位置上
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]); //顯示個位
}
void display_num1() //顯示數據a
{
dispaly[3]=num1%10000/1000; //千
dispaly[2]=num1%1000/100; //百
dispaly[1]=num1%100/10; //十
dispaly[0]=num1%10; //個
write_com(0x80+0); //顯示第一個數在0的位置上
if(num1>999){ write_date('0'+dispaly[3]);} //顯示千位
if(num1>99){ write_date('0'+dispaly[2]);} //顯示百位
if(num1>9){ write_date('0'+dispaly[1]);} //顯示十位
write_date('0'+dispaly[0]); //顯示個位
}
void display_yusuanfu() //顯示運算符
{
switch(yusuanfu)
{
case 219: write_com(0x80+1); write_date('+'); break; //寫屏“+? 在1的位置上
case 221: write_com(0x80+1); write_date('-'); break; //寫屏“-” 在1的位置上
case 136: write_com(0x80+1); write_date('*'); break; //寫屏“*” 在1的位置上
case 223: write_com(0x80+1); write_date('/'); break; //寫屏“/” 在1的位置上
}
}
void display_num2() //顯示第二個數
{
dispaly[3]=num2%10000/1000; //千
dispaly[2]=num2%1000/100; //百
dispaly[1]=num2%100/10; //十
dispaly[0]=num2%10; //個
write_com(0x80+2); //顯示第二個數在2的位置上
if(num1>999){ write_date('0'+dispaly[3]);} //顯示千位
if(num1>99){ write_date('0'+dispaly[2]);} //顯示百位
if(num1>9){ write_date('0'+dispaly[1]);} //顯示十位
write_date('0'+dispaly[0]); //顯示個位
}
void display_c(x) //此函數在此工程中沒有用到,僅提供一個思路
{
if(data_c<100000000&&data_c>-1)//溢出時顯示錯誤
{
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; //個
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]);} //十萬
if(data_b!=0) {
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]); //個
}
}
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]); //個
}
}
else //溢出時顯示錯誤
{
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
}
}
//加減乘除運算
void eql(uchar x) //此函數在此工程中沒有用到 提供一個思路
{
switch(x) /*功能鍵選擇*/
{
case 1:data_c=data_a+data_b;break; //加 /* + S=1 */ /* 數值轉換函數 */
case 2:if(data_a>=data_b){data_c=data_a-data_b;} /* - S=2 *///減
else{data_c=data_b-data_a;W_lcd(5,1,'-');} //負數符號
break;
case 3:data_c=(data_a*data_b);break; /* * S=3 *///乘
case 4:if(data_b==0){LCD_Write_String(0,1,"Error ! ");}else{data_c=(data_a*10000)/data_b;}break; /* / S=4 *///除//溢出時顯示錯誤
case 0:break;
}
}
void UART_Init(void) // 串口初始化
{
SCON = 0x50;
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
EA = 1;
ES = 1;
TR1 = 1;
}
void INT_UartRcv(void) interrupt 4 //串口中斷函數
{
unsigned char Rcv = 0;
if(RI)
{
RI = 0;
Rcv = SBUF; //串口讀數據
if((Rcv>9||Rcv<0)&&(count==1)) //count=1,表明輸入的是運算符
{
yusuanfu = Rcv; //將讀回的數據存入yunsuanfu這個變量
switch(yusuanfu) //判斷讀回的運算符,并將他們顯示在屏上1的位置
{
case 75 : write_com(0x80+1); write_date('+'); LCD_Delay_ms(1000); break;
case 77 : write_com(0x80+1); write_date('-'); break;
case 248 : write_com(0x80+1); write_date('*'); break;
case 79 : write_com(0x80+1); write_date('/'); break;
}
count++;
}
else if(count==2) //count=2表明第二個數據來了
{
num2= Rcv-2;
display_num2();
count++;
}
else if(count==3) //count=3表明該計算結果了
{
switch(yusuanfu) //判斷運算符是哪個,并執行相應的計算
{
case 75: data_a = num1 +num2-110; break; //檢測到”+“號,讓兩個數據相加
case 77: data_a = num1 -num2-146; break; //檢測到”-“號,讓兩個數據相減
case 248: data_a = ((num2-110) *num1); break; //檢測到”x“號,讓兩個數據相乘
case 79: data_a = num1 /(num2-110); break; //檢測到”/“號,讓兩個數據相除
}
display_a(); //顯示運算結果
LCD_Delay_ms(1000); //延時,讓顯示的結果延時一下
count=0; //計算完一遍,讓變量清0
LCD_Write_String(0,0,table);LCD_Write_String(0,1,table);W_lcd(0,0,'0'); //清屏,讓屏顯示0,表示已準備好計算下一次
}
else if (count==0) //count=0,表示一次計算剛剛開始
{
num1 = Rcv-112; // 第一個數據發回來的碼值減去112就是想要得到的數據
display_num1(); // 顯示第一個數
count++; //變量加1
feng=1; //蜂鳴器響一下,此語句是調試階段用到的
LCD_Delay_ms(1000);
feng=0; //關掉蜂鳴器
}
}
}
void main()
{
UART_Init(); //串口初始化
init_lcd(); //1602液晶初始化
while(1) //什么也不做,等待執行中斷函數
{
;
}
}
復制代碼
所有資料51hei提供下載:
1-計算器程序.rar
(51.11 KB, 下載次數: 10)
2018-4-9 21:53 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
精品久久成人
|
免费午夜电影
|
中文字幕二区
|
国产91视频免费
|
国内自拍视频在线观看
|
欧美一级欧美三级在线观看
|
91免费福利视频
|
日韩高清一区
|
国产精品久久一区二区三区
|
亚洲精品久久久久久宅男
|
久久一二
|
精品国产aⅴ
|
欧美亚洲视频在线观看
|
亚洲国产精品va在线看黑人
|
欧美高清视频
|
伊人春色在线观看
|
国内精品视频在线
|
蜜桃视频一区二区三区
|
99热精品在线
|
精品国产一级
|
色性av
|
中文字幕韩在线第一页
|
91人人爽
|
一区二区三区av
|
91麻豆精品国产91久久久久久
|
亚洲视频二区
|
国产精品一区二区三区在线播放
|
天天躁日日躁狠狠躁2018小说
|
亚洲人成人网
|
日韩靠逼
|
亚洲一区二区三区久久
|
欧美在线视频网站
|
亚洲精品久久久久久久久久久久久
|
亚洲网站在线观看
|
国产一区不卡
|
久久亚洲一区二区
|
亚洲午夜精品一区二区三区
|
欧美日韩在线一区二区三区
|
欧美二三区
|
欧美午夜视频
|
成人在线影视
|