|
#include <AT89x51.h>
#include <intrins.h>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include<stdlib.h> //包含rand()隨機(jī)函數(shù)的頭文件
#define uchar unsigned char
#define uint unsigned int
#define N 15 //十五個(gè)隨機(jī)數(shù)
#define M 15 //加減符號
#define LCD_DB P0
sbit LCD_RS=P2^6; //P2^0是p2.0的意思;LCD_RS與P2.0等效起來,對LCD_RS 讀寫,就是對P2.0讀寫 好處在于LCD_RS含義直接明了,寫程序多了就會知道有必要de
sbit LCD_RW=P2^5; //P2^1是p2.1的意思
sbit LCD_E=P2^7; //P2^2是p2.2的意思
sbit k1=P3^2; //外部中斷0
/*
t = 0;
i = 0;
f = 0;
k = 0; */
unsigned char t=0,k=0,i=0,j=0,f=0; //t是計(jì)時(shí)變量,k是按鍵標(biāo)志,i,j是數(shù)組下標(biāo),f是隨機(jī)數(shù)重復(fù)標(biāo)志,
unsigned char shuzu[M],fuhao[N];
//uchar *shuzu[M],fuhao[N];
int a,b,d,e;
/**************************參數(shù)輸入控制********************/
int m=2; //canshu位數(shù) (1代表3位數(shù) 2代表4位數(shù) 3代表5位數(shù))
int n=2; //加或加減混合1代表加,2代表加減混合
int z=1; //顯示快慢(1代表10秒顯示完15個(gè)數(shù),234567 8代表3秒顯示完,其余按規(guī)律遞減)
//int *x=0; //數(shù)組和的答案,需要顯示
/******函數(shù)聲明****************/
void LCD_init(void); //LCD1602初始化函數(shù)
void LCD_write_command(uchar command); //寫指令函數(shù)
void LCD_write_data(uchar dat); //寫數(shù)據(jù)函數(shù)
void LCD_disp_char(uchar x,uchar y,uchar dat); //在某個(gè)屏幕位置上顯示一個(gè)字符,X(0-15),y(1-2)
void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602顯示字符串函數(shù)
void delay_n10us(uint n); //延時(shí)函數(shù)10ms
//void suijishu();
void initzhongduan(); //定時(shí)器0及外部中斷0初始化函數(shù)
void chanshengshuzu(); //產(chǎn)生數(shù)組函數(shù)
void lcddisplay(); // 將數(shù)組顯示到LCD1602上的函數(shù)*
/*--------------------------------------
;模塊名稱:LCD_init();
;功 能:初始化LCD1602
;占用資源:--
;參數(shù)說明:--
;創(chuàng)建日期:2008.08.15
;版 本:FV1.0(函數(shù)版本Function Version)
;修改日期:--
;修改說明:--
;-------------------------------------*/
void LCD_init(void)
{
delay_n10us(10);
LCD_write_command(0x38);//設(shè)置8位格式,2行,5x7
delay_n10us(10);
LCD_write_command(0x0c);//整體顯示,關(guān)光標(biāo),不閃爍
delay_n10us(10);
LCD_write_command(0x06);//設(shè)定輸入方式,增量不移位
delay_n10us(10);
LCD_write_command(0x01);//清除屏幕顯示
delay_n10us(100); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
}
/*--------------------------------------
;模塊名稱:LCD_write_command();
;功 能:LCD1602寫指令函數(shù)
;占用資源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
;參數(shù)說明:dat為寫命令參數(shù)
;創(chuàng)建日期:2008.08.15
;版 本:FV1.0(函數(shù)版本Function Version)
;修改日期:--
;修改說明:--
;-------------------------------------*/
void LCD_write_command(uchar dat)
{
delay_n10us(10);
LCD_RS=0; //指令
LCD_RW=0; //寫入
LCD_E=1; //允許
LCD_DB=dat;
delay_n10us(10); //實(shí)踐證明,我的LCD1602上,用for循環(huán)1次就能完成普通寫指令。
LCD_E=0;
delay_n10us(10); //實(shí)踐證明,我的LCD1602上,用for循環(huán)1次就能完成普通寫指令。
}
/*--------------------------------------
;模塊名稱:LCD_write_data();
;功 能:LCD1602寫數(shù)據(jù)函數(shù)
;占用資源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
;參數(shù)說明:dat為寫數(shù)據(jù)參數(shù)
;創(chuàng)建日期:2008.08.15
;版 本:FV1.0(函數(shù)版本Function Version)
;修改日期:--
;修改說明:--
;-------------------------------------*/
void LCD_write_data(uchar dat)
{
delay_n10us(10);
LCD_RS=1; //數(shù)據(jù)
LCD_RW=0; //寫入
LCD_E=1; //允許
LCD_DB=dat;
delay_n10us(10);
LCD_E=0;
delay_n10us(10);
}
/*--------------------------------------
;模塊名稱:LCD_disp_char();
;功 能:LCD1602顯示一個(gè)字符函數(shù),在某個(gè)屏幕位置上顯示一個(gè)字符,X(0-15),y(1-2)。
;占用資源:--
;參數(shù)說明:X為1602的列值(取值范圍是0-15),y為1602的行值(取值范圍是1-2),dat為所要顯示字符對應(yīng)的地址參數(shù)。
;創(chuàng)建日期:2008.08.15
;版 本:FV1.0(函數(shù)版本Function Version)
;修改日期:--
;修改說明:--
;-------------------------------------*/
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
/*--------------------------------------
;模塊名稱:LCD_disp_str();
;功 能:LCD1602顯示字符串函數(shù),在某個(gè)屏幕起始位置{X(0-15),y(1-2)}上顯示一個(gè)字符串。
;占用資源:--
;參數(shù)說明:X為1602的列值(取值范圍是0-15),y為1602的行值(取值范圍是1-2),str為所要顯示字符串對應(yīng)的指針參數(shù)。
;創(chuàng)建日期:2008.08.16
;版 本:FV1.0(函數(shù)版本Function Version)
;修改日期:--
;修改說明:--
;-------------------------------------*/
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
while(*str!='\0')
{
LCD_write_data(*str);
str++;
}
}
/*--------------------------------------
;模塊名稱:delay_n10us();
;功 能:延時(shí)函數(shù),延時(shí)約n個(gè)10us
;占用資源:--
;參數(shù)說明:--
;創(chuàng)建日期:2008.08.15
;版 本:FV1.1(函數(shù)版本Function Version)
;修改日期:2008.08.26
;修改說明:修改為較精確的延時(shí)函數(shù),"_nop_()"延時(shí)1us@12M晶振
;-------------------------------------*/
void delay_n10us(uint n) //延時(shí)n個(gè)10us@12M晶振
{
uint i;
for(i=n;i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
//****************************************************第一部分LCD1602設(shè)置 END********************************************************************************************************
/**************主函數(shù)部分**************/
/*********主函數(shù)******************/
void main(void)
{
// int c;
LCD_init();
LCD_disp_str(0,1,"setting:");
LCD_disp_str(0,2,"diffuit:");
LCD_disp_char(9,1,m); //顯示參數(shù)
LCD_disp_char(11,1,n);
LCD_disp_char(13,1,z);
LCD_disp_char(9,2,m+n+z); //
delay_n10us(2000000000000); //延時(shí)0.2s
LCD_write_command(0x01); //清除屏幕顯示
delay_n10us(100); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
chanshengshuzu(); //產(chǎn)生數(shù)組函數(shù)
lcddisplay(); // 將數(shù)組顯示到LCD1602上的函數(shù)*
}
/*****************************************************************************************************************************************************************************/
/*:用定時(shí)器加rand()隨機(jī)函數(shù)來實(shí)現(xiàn)
單片機(jī)上電之后通過按鍵去啟動取隨機(jī)數(shù),若是單片機(jī)上電就立即取
隨機(jī)數(shù)的話,那每次上電隨機(jī)的結(jié)果都是一樣的。然后是0到9不重復(fù)的
隨機(jī)數(shù),程序中用了循環(huán)來判斷是否和前面取的隨機(jī)數(shù)相同,相同則進(jìn)入
下次取隨機(jī)數(shù),不同則存入數(shù)組。
程序如下:
/************************************產(chǎn)生15數(shù)字的函數(shù),并且存到數(shù)組shuzu[15]中***************************************************
/************************************產(chǎn)生14個(gè)運(yùn)算符號(其實(shí)內(nèi)部只有0和1)的函數(shù),并且存到數(shù)組符號fuhao[14]中***************************************************/
/************這里只是產(chǎn)生了兩個(gè)數(shù)組,還沒有將數(shù)組輸出顯示到LCD1602上,還需將符號fuhao[15]數(shù)組改變成加減號******************/
void initzhongduan() //定時(shí)器0及外部中斷0初始化函數(shù)
{
TMOD = 0x02; //設(shè)置定時(shí)器0為工作方式2
TH0 = 7; //裝初值
TL0 = 7;
EA = 1; //開總中斷
ET0 = 1; //開定時(shí)器0中斷
TR0 = 1; //啟動定時(shí)0
EX0 = 1; //開外部中斷0,同按鍵的效果一樣
IT0 = 1; //下降沿觸發(fā)
}
////////////////************************//產(chǎn)生數(shù)組函數(shù)**************////////////////////////////////
void chanshengshuzu() //產(chǎn)生數(shù)組函數(shù)
{
int i=0,j;
// unsigned char t,k,i=0,j,f; //t是計(jì)時(shí)變量,k是按鍵標(biāo)志,i,j是數(shù)組下標(biāo),f是隨機(jī)數(shù)重復(fù)標(biāo)志,
//int a,b,d,shuzu[N],fuhao[M]; // 局部變量a,b分別是兩個(gè)數(shù)組的暫存值,d,e用于循環(huán)控制
int x=0,min=1,max=1;
/*scanf("%d,%d",&m,&n); //參數(shù)設(shè)置m:位數(shù)(可輸入1(三位) 2 3)n:只加(1)
//加減混合(2) */
//可用直接賦值輸入代替,例 /*
//m=3; //5位 此參數(shù)是全局變量,已在程序開頭輸入控制了
//n=2; //加減混合
for(d=0;d<m+1;d++) //以下幾行程序作用是調(diào)整產(chǎn)生數(shù)字的位數(shù)
min=10*min; //參數(shù)1:
for(d=0;d<m+2;d++)
max=10*max;
initzhongduan();
while(1) //這個(gè)無限循環(huán)應(yīng)去掉。檢測按鍵按鍵放到主函數(shù)中來做
{
while(k) //外部中斷0觸發(fā)循環(huán)
{
if(!i) //i=0時(shí)取第一個(gè)隨機(jī)數(shù)放入數(shù)組n[0]
{
srand(t); //隨機(jī)數(shù)初始化
//srand((unsigned) time(NULL));
//for(i=0;i<N;i++)
a=min+rand()%(max-min); //數(shù)字?jǐn)?shù)組
shuzu[0]=a;//min+rand()%(max-min); //數(shù)字?jǐn)?shù)組
//srand((unsigned) time(NULL));
//for(j=0;j<M;j++)
srand(t+8); //隨機(jī)數(shù)初始化
fuhao[0]=rand()%2; //隨機(jī)的0 1數(shù)組
// a = (char)(rand() % 10); //取隨機(jī)數(shù)(0~9)
// n[0] = a; //存入數(shù)組
i++; //數(shù)組下標(biāo)加1
}
else
while(i < 15) //存放剩下的14個(gè)隨機(jī)數(shù)
{
srand(t); //隨機(jī)數(shù)初始化
a=min+rand()%(max-min); //數(shù)字?jǐn)?shù)組
srand(t+8); //隨機(jī)數(shù)初始化
b=rand()%2; //隨機(jī)的0 1數(shù)組
/// shuzu[]=a;
// a=(char)(rand() % 10); //取隨機(jī)數(shù)
//shuzi
for(j = 0; j < i; j++) //與前面的隨機(jī)數(shù)比較
{
if(shuzu[j] == a) //與前面的隨機(jī)數(shù)相同
f = 1; //標(biāo)志置1
}
if(f) //有重復(fù)執(zhí)行
{
f = 0; //標(biāo)志清0
continue; //結(jié)束本次循環(huán)
}
//fuhao
for(j = 0; j < i; j++) //與前面的隨機(jī)數(shù)比較
{
if(fuhao[j] == b) //與前面的隨機(jī)數(shù)相同
f = 1; //標(biāo)志置1
}
if(f) //有重復(fù)執(zhí)行
{
f = 0; //標(biāo)志清0
continue; //結(jié)束本次循環(huán)
}
//n = a; //不同則存入數(shù)組中
shuzu=a;
fuhao=b;
i++; //數(shù)組下標(biāo)加1
}
}
}
}
void inter0() interrupt 0 //外部中斷0 這里需要將第四個(gè)即主持人決定開始的按鍵的接口接在單片機(jī)外部中斷0的IO口
{
k = 1; //按鍵標(biāo)志置1,主函數(shù)執(zhí)行取隨機(jī)數(shù)
}
void time0() interrupt 1 //定時(shí)器0中斷 不用聲明
{
t++; //時(shí)間加1
if(t == 100)
{
t = 0;
}
}
/****************************************************產(chǎn)生兩個(gè)隨機(jī)數(shù)組函數(shù)結(jié)束***************************************/
/********************將數(shù)組顯示到LCD1602上的函數(shù)************************************************************************************/
void lcddisplay() // 將數(shù)組顯示到LCD1602上的函數(shù)*
{
if(n==1) //b【】數(shù)組:全是加 因?yàn)閰?shù)1代表著只是加法
{
for(j=0,i=1;j<M;j++,i++)
{
// x=x+shuzu;
LCD_disp_str(5,1,"+"); //顯示+號
// LCD_disp_str(6,1,shuzu); //
delay_n10us(8000000000000);
LCD_write_command(0x01);//清除屏幕顯示
delay_n10us(1000000); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
// printf("+%d",a); //只是加的運(yùn)算結(jié)果
}
}
else
{ //加減隨機(jī)
for(j=1,i=1;j<M;j++,i++)
{
if(fuhao[j]==1)
{
// x=x+shuzu[i-1];//+shuzu; //加減混合運(yùn)算結(jié)果
LCD_disp_str(5,1,"+"); //顯示+號
// LCD_disp_str(6,1,shuzu); //
delay_n10us(8000000000000);
LCD_write_command(0x01);//清除屏幕顯示
delay_n10us(1000000); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
// printf("+%d",a);
}
else
{
// x=x+a[i-1]-a; //
LCD_disp_str(5,1,"-"); //顯示-號
// LCD_disp_str(6,1,shuzu); //
delay_n10us(8000000000000);
LCD_write_command(0x01);//清除屏幕顯示
delay_n10us(1000000); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
// printf("-%d",a);
}
}
}
//顯示答案x
//// LCD_disp_str(6,1,x); //
// delay_n10us(8000000000000);
// LCD_write_command(0x01);//清除屏幕顯示
// delay_n10us(1000000); //延時(shí)清屏,延時(shí)函數(shù),延時(shí)約n個(gè)10us
}
|
|
|