#include <AT89x51.h> #include <intrins.h> #include <math.h> //Keil library #include <stdio.h> //Keil library #include<stdlib.h> //包含rand()随机函数的头文件 #define uchar unsigned char #define uint unsigned int #define N 15 //十五个随机数 #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是计时变量,k是按键标志,i,j是数组下标,f是随机数重复标志, unsigned char shuzu[M],fuhao[N]; //uchar *shuzu[M],fuhao[N]; int a,b,d,e; /**************************参数输入控制********************/ int m=2; //canshu位数 (1代表3位数 2代表4位数 3代表5位数) int n=2; //加或加减混合1代表加,2代表加减混合 int z=1; //显示快慢(1代表10秒显示完15个数,234567 8代表3秒显示完,其余按规律递减) //int *x=0; //数组和的答案,需要显示 /******函数声明****************/ void LCD_init(void); //LCD1602初始化函数 void LCD_write_command(uchar command); //写指令函数 void LCD_write_data(uchar dat); //写数据函数 void LCD_disp_char(uchar x,uchar y,uchar dat); //在某个屏幕位置上显示一个字符,X(0-15),y(1-2) void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数 void delay_n10us(uint n); //延时函数10ms //void suijishu(); void initzhongduan(); //定时器0及外部中断0初始化函数 void chanshengshuzu(); //产生数组函数 void lcddisplay(); // 将数组显示到LCD1602上的函数* /*-------------------------------------- ;模块名称:LCD_init(); ;功 能:初始化LCD1602 ;占用资源:-- ;参数说明:-- ;创建日期:2008.08.15 ;版 本:FV1.0(函数版本Function Version) ;修改日期:-- ;修改说明:-- ;-------------------------------------*/ void LCD_init(void) { delay_n10us(10); LCD_write_command(0x38);//设置8位格式,2行,5x7 delay_n10us(10); LCD_write_command(0x0c);//整体显示,关光标,不闪烁 delay_n10us(10); LCD_write_command(0x06);//设定输入方式,增量不移位 delay_n10us(10); LCD_write_command(0x01);//清除屏幕显示 delay_n10us(100); //延时清屏,延时函数,延时约n个10us } /*-------------------------------------- ;模块名称:LCD_write_command(); ;功 能:LCD1602写指令函数 ;占用资源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E). ;参数说明:dat为写命令参数 ;创建日期:2008.08.15 ;版 本:FV1.0(函数版本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); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。 LCD_E=0; delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。 } /*-------------------------------------- ;模块名称:LCD_write_data(); ;功 能:LCD1602写数据函数 ;占用资源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E). ;参数说明:dat为写数据参数 ;创建日期:2008.08.15 ;版 本:FV1.0(函数版本Function Version) ;修改日期:-- ;修改说明:-- ;-------------------------------------*/ void LCD_write_data(uchar dat) { delay_n10us(10); LCD_RS=1; //数据 LCD_RW=0; //写入 LCD_E=1; //允许 LCD_DB=dat; delay_n10us(10); LCD_E=0; delay_n10us(10); } /*-------------------------------------- ;模块名称:LCD_disp_char(); ;功 能:LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)。 ;占用资源:-- ;参数说明:X为1602的列值(取值范围是0-15),y为1602的行值(取值范围是1-2),dat为所要显示字符对应的地址参数。 ;创建日期:2008.08.15 ;版 本:FV1.0(函数版本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显示字符串函数,在某个屏幕起始位置{X(0-15),y(1-2)}上显示一个字符串。 ;占用资源:-- ;参数说明:X为1602的列值(取值范围是0-15),y为1602的行值(取值范围是1-2),str为所要显示字符串对应的指针参数。 ;创建日期:2008.08.16 ;版 本:FV1.0(函数版本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(); ;功 能:延时函数,延时约n个10us ;占用资源:-- ;参数说明:-- ;创建日期:2008.08.15 ;版 本:FV1.1(函数版本Function Version) ;修改日期:2008.08.26 ;修改说明:修改为较精确的延时函数,"_nop_()"延时1us@12M晶振 ;-------------------------------------*/ void delay_n10us(uint n) //延时n个10us@12M晶振 { uint i; for(i=n;i>0;i--) { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); } } //****************************************************第一部分LCD1602设置 END******************************************************************************************************** /**************主函数部分**************/ /*********主函数******************/ 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); //显示参数 LCD_disp_char(11,1,n); LCD_disp_char(13,1,z); LCD_disp_char(9,2,m+n+z); // delay_n10us(2000000000000); //延时0.2s LCD_write_command(0x01); //清除屏幕显示 delay_n10us(100); //延时清屏,延时函数,延时约n个10us chanshengshuzu(); //产生数组函数 lcddisplay(); // 将数组显示到LCD1602上的函数* } /*****************************************************************************************************************************************************************************/ /*:用定时器加rand()随机函数来实现 单片机上电之后通过按键去启动取随机数,若是单片机上电就立即取 随机数的话,那每次上电随机的结果都是一样的。然后是0到9不重复的 随机数,程序中用了循环来判断是否和前面取的随机数相同,相同则进入 下次取随机数,不同则存入数组。 程序如下: /************************************产生15数字的函数,并且存到数组shuzu[15]中*************************************************** /************************************产生14个运算符号(其实内部只有0和1)的函数,并且存到数组符号fuhao[14]中***************************************************/ /************这里只是产生了两个数组,还没有将数组输出显示到LCD1602上,还需将符号fuhao[15]数组改变成加减号******************/ void initzhongduan() //定时器0及外部中断0初始化函数 { TMOD = 0x02; //设置定时器0为工作方式2 TH0 = 7; //装初值 TL0 = 7; EA = 1; //开总中断 ET0 = 1; //开定时器0中断 TR0 = 1; //启动定时0 EX0 = 1; //开外部中断0,同按键的效果一样 IT0 = 1; //下降沿触发 } ////////////////************************//产生数组函数**************//////////////////////////////// void chanshengshuzu() //产生数组函数 { int i=0,j; // unsigned char t,k,i=0,j,f; //t是计时变量,k是按键标志,i,j是数组下标,f是随机数重复标志, //int a,b,d,shuzu[N],fuhao[M]; // 局部变量a,b分别是两个数组的暂存值,d,e用于循环控制 int x=0,min=1,max=1; /*scanf("%d,%d",&m,&n); //参数设置m:位数(可输入1(三位) 2 3)n:只加(1) //加减混合(2) */ //可用直接赋值输入代替,例 /* //m=3; //5位 此参数是全局变量,已在程序开头输入控制了 //n=2; //加减混合 for(d=0;d<m+1;d++) //以下几行程序作用是调整产生数字的位数 min=10*min; //参数1: for(d=0;d<m+2;d++) max=10*max; initzhongduan(); while(1) //这个无限循环应去掉。检测按键按键放到主函数中来做 { while(k) //外部中断0触发循环 { if(!i) //i=0时取第一个随机数放入数组n[0] { srand(t); //随机数初始化 //srand((unsigned) time(NULL)); //for(i=0;i<N;i++) a=min+rand()%(max-min); //数字数组 shuzu[0]=a;//min+rand()%(max-min); //数字数组 //srand((unsigned) time(NULL)); //for(j=0;j<M;j++) srand(t+8); //随机数初始化 fuhao[0]=rand()%2; //随机的0 1数组 // a = (char)(rand() % 10); //取随机数(0~9) // n[0] = a; //存入数组 i++; //数组下标加1 } else while(i < 15) //存放剩下的14个随机数 { srand(t); //随机数初始化 a=min+rand()%(max-min); //数字数组 srand(t+8); //随机数初始化 b=rand()%2; //随机的0 1数组 /// shuzu[]=a; // a=(char)(rand() % 10); //取随机数 //shuzi for(j = 0; j < i; j++) //与前面的随机数比较 { if(shuzu[j] == a) //与前面的随机数相同 f = 1; //标志置1 } if(f) //有重复执行 { f = 0; //标志清0 continue; //结束本次循环 } //fuhao for(j = 0; j < i; j++) //与前面的随机数比较 { if(fuhao[j] == b) //与前面的随机数相同 f = 1; //标志置1 } if(f) //有重复执行 { f = 0; //标志清0 continue; //结束本次循环 } //n = a; //不同则存入数组中 shuzu=a; fuhao=b; i++; //数组下标加1 } } } } void inter0() interrupt 0 //外部中断0 这里需要将第四个即主持人决定开始的按键的接口接在单片机外部中断0的IO口 { k = 1; //按键标志置1,主函数执行取随机数 } void time0() interrupt 1 //定时器0中断 不用声明 { t++; //时间加1 if(t == 100) { t = 0; } } /****************************************************产生两个随机数组函数结束***************************************/ /********************将数组显示到LCD1602上的函数************************************************************************************/ void lcddisplay() // 将数组显示到LCD1602上的函数* { if(n==1) //b【】数组:全是加 因为参数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); //延时清屏,延时函数,延时约n个10us // printf("+%d",a); //只是加的运算结果 } } else { //加减随机 for(j=1,i=1;j<M;j++,i++) { if(fuhao[j]==1) { // x=x+shuzu[i-1];//+shuzu; //加减混合运算结果 LCD_disp_str(5,1,"+"); //显示+号 // LCD_disp_str(6,1,shuzu); // delay_n10us(8000000000000); LCD_write_command(0x01);//清除屏幕显示 delay_n10us(1000000); //延时清屏,延时函数,延时约n个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); //延时清屏,延时函数,延时约n个10us // printf("-%d",a); } } } //显示答案x //// LCD_disp_str(6,1,x); // // delay_n10us(8000000000000); // LCD_write_command(0x01);//清除屏幕显示 // delay_n10us(1000000); //延时清屏,延时函数,延时约n个10us } |
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |