在LCD1602屏幕的某一随机位置上反复出现字符‘8’然后擦除,注意字符‘8’出现在每个位置上的机率应尽量相同。
产生随机位置的方法:
用定时器加 rand()随机函数来实现单片机上电之后通过按键start去启动取随机数,若是单片机上电就立即取随机数的话,那每次上电随机的结果都是一样的。所以用循环来判断是否和前面取的随机数相同,相同则进入下次取随机数,不同则存入数组。
代码如下:
#include <reg51.h>
#include <intrins.h>
#include<stdlib.h>//包含 rand()随机函数的头文件
#define DATA_BUS (P0)
#define CLEAR_DISPLAY 0x01
sbit RS = P2^0;
sbit RW = P2^1;
sbit E = P2^2;
sbit start=P1^7;
unsigned char t,i,j,a,f,n[80];
//t 是计时变量,i 是数组下标,f是随机数重复标志
//n[80]是存放随机地址的数组
// Function Prototypes
void delay(unsigned int);
void check_busy(void);
void write_command(unsigned char com);
void write_data(unsigned char dat);
void LCD_init(void);
void dis_char(unsigned char ad, unsigned char input);
void init() //初始化函数
{
t = 0;
i = 0;
f = 0;
TMOD = 0x02; //设置定时器 0 为工作方式 2
TH0 = 200; //装初值
TL0 = 200;
EA = 1; //开总中断
ET0 = 1; //开定时器 0 中断
PT0 = 1; //设为高级中断
TR0 = 1; //启动定时 0
IT0 = 1; //下降沿触发
}
void main()
{
init();
LCD_init();
while(1)
{
if(~start) //按键按下 触发循环
{
if(!i) //i=0 时取第一个随机数放入数组 n[0]
{
srand(t); //随机数初始化
a = (char)(128+rand() % 80); //取随机地址
n[0] = a; //存入数组
if(n[0]<=143||n[0]>=192)
dis_char(n[0],'8');//显示8
delay(100);
write_command(0x01); // clear display
delay(100);
i++; //数组下标加 1
}
else
while(i < 80) //存放剩下的 79 个随机数
{
srand(t); //随机数初始化
a = (char)(128+rand() % 80); //取随机地址
for(j = 0; j < i; j++) //与前面的随机数比较
{
if(n[j] == a) //与前面的随机数相同
f = 1; //标志f置 1
}
if(f) //有重复执行
{
f = 0; //标志f清 0
continue; //结束本次循环
}
n[i] = a; //不同则存入数组中
if(n[i]<=143||n[i]>=192)
dis_char(n[i],'8');//显示8
delay(100);
write_command(0x01); // clear display
delay(100);
i++; //数组下标加 1
if(i==80)
i=0;
}
}
}
}
void time0() interrupt 1 //定时器 0 中断
{
t++; //时间加 1
if(t == 100)
{
t = 0;
}
}
/*******************************************
Functions
*******************************************/
// Display a character
void dis_char(unsigned char ad, unsigned char input)
{
write_command(ad);
write_data(input);
delay(10);
}
// Delay
void delay(unsigned int j)
{
unsigned char i = 200;
for(; j>0; j--){
while(--i);
}
}
// Test the Busy bit
void check_busy(void)
{
do{
DATA_BUS = 0xff; //set to 1 before read P0
E = 0;
RS = 0;
RW = 1;
E = 1;
_nop_(); // wait a while
}while(DATA_BUS & 0x80); //wait until not busy
E = 0;
}
// Write a command
void write_command(unsigned char com)
{
check_busy(); //write command when LCD is not busy
E = 0;
RS = 0;
RW = 0;
DATA_BUS = com; //write a command
E = 1;
_nop_(); // wait a while
E = 0;
delay(1); // wait till it works
}
// Write Data
void write_data(unsigned char dat)
{
check_busy(); //write data when LCD is not busy
E = 0;
RS = 1;
RW = 0;
DATA_BUS = dat; //write a data
E = 1;
_nop_();// wait a while
E = 0;
delay(1);// wait till it works
}
// Initialize LCD controller
void LCD_init(void)
{
write_command(0x38); // Function set:8-bits, 2 lines, 5*8 dots
write_command(0x08); // Display control:no cursor, no blink, no display
write_command(0x01); // clear display
write_command(0x06); // Entry mode set:auto-increment on
write_command(0x0C); // Display control:no cursor, no blink, enable display
delay(1);
}