#include <AT89X51H>
//设CPU是时钟12MHz的8051系列
data unsigned int ms;
sbit KEY=P2^3;
void SetupTimer0()
{
TMOD &= 0XF0; //仅保留T1信息
TMOD |= 0X02; //设置T0: 定时功能,方式2,自动重载8位定时器/计数器
TH0 = 256-250;//定时每025ms中断一次
TL0 = 256-250;
TR0 = 1; //开启定时器
ET0 = 1; //定时器0中断打开
}
void Timer0_ISR() interrupt 1 //中断服务程序
{
static data unsigned char us250;
if (++us250>=4) {++ms; us250=0;}
}
void process1()
{
unsigned char i,d;
unsigned int time,dlt;
//第一步8灯整体一直闪(闪10下)。
for (i=0; i<10; ++i)
{
P1=0;
for (time=ms,dlt=0; dlt<500; dlt=ms-time);
P1=0xFF;
for (time=ms,dlt=0; dlt<500; dlt=ms-time);
}
//第二步整体灭5秒。
P1=0xff;
for (time=ms,dlt=0; dlt<5000; dlt=ms-time);
//第三步从右边逐个点亮并循环4遍。
for (i=0; i<4; ++i)
for (d=1;d;d<<=1)
for (P1=~d,time=ms,dlt=0; dlt<500; dlt=ms-time);
//第4步循环完毕后全部熄灭;
P1=0xff;
}
void process2()
{
unsigned char i,d;
unsigned int time,dlt;
//第一步8灯整体闪3次。
for (i=0; i<3; ++i)
{
P1=0;
for (time=ms,dlt=0; dlt<500; dlt=ms-time);
P1=0xFF;
for (time=ms,dlt=0; dlt<500; dlt=ms-time);
}
//第二步从左边逐个点亮并循环2遍。
for (i=0; i<2; ++i)
for (d=0x80;d;d>>=1)
for (P1=~d,time=ms,dlt=0; dlt<500; dlt=ms-time);
//第三步循环完毕后8灯一直流水;
for (;KEY;)
for (d=1; d && KEY; d<<=1)
for (P1=d,time=ms,dlt=0; dlt<500 && KEY ; dlt=ms-time);
}
void process3()
{
unsigned char i,j,d;
unsigned int time,dlt;
//第一步8灯整体保持全灭, 灭的时间为500ms, 可以修改
P1=0XFF;
for (time=ms,dlt=0; dlt<500; dlt=ms-time);
//第二步8灯从外到里依次点亮,重复两遍。
for (i=0; i<2; ++i)
for (d=0x1,j=0x80;d<=0x8;d<<=1,j>>=1)
for (P1=~(d|j),time=ms,dlt=0; dlt<500; dlt=ms-time);
//第三步8灯从里到外依次点亮,重复两遍循环完毕后8灯保持在4亮4灭的状态
for (i=0; i<2; ++i)
for (d=0x8,j=0x10;d;d>>=1,j<<=1)
for (P1=~(d|j),time=ms,dlt=0; dlt<500 && KEY ; dlt=ms-time);
P1=0xc3;
for (;KEY;);
}
void process4()
{
unsigned char i,d;
unsigned int time,dlt;
//第一步整体保持全灭。灭的时间为1000ms, 可以修改
P1=0XFF;
for (time=ms,dlt=0; dlt<1000; dlt=ms-time);
//第二步从左到右流水两遍。
for (i=0; i<2; ++i)
for (d=1; d; d<<=1)
for (P1=d,time=ms,dlt=0; dlt<500; dlt=ms-time);
//第三步从右到左逐个点亮三遍。
for (i=0; i<3; ++i)
for (d=0x1;d;d<<=1)
for (P1=~d,time=ms,dlt=0; dlt<500; dlt=ms-time);
//第4步其中一盏灯保持闪
for (;KEY;)
{
for (d=0x8;KEY;d^=0x8)
for (P1=~d,time=ms,dlt=0; dlt<500 && KEY; dlt=ms-time);
}
}
void main()
{
// data unsigned char p0;
ms=0;
SetupTimer0();
EA = 1; //全局中断打开
while(1)
{
process1();
process2();
process3();
process4();
}
}
/
要求是能进行9999秒倒计时
用C语言实现
/
#include<at89X51h>
#define uchar unsigned char
#define uint unsigned int
uchar num_qian,num_bai,num_shi,num_ge;//定义千位,百位,十位,个位。
uint time;//要显示的时间0~9999
uint tcnt;//计时单元
////
//以下是端口定义
////
sbit key_qian=P1^0;//按键"千加1"
sbit key_bai =P1^2;//按键"百加1"
sbit key_shi =P1^4;//按键"十加1"
sbit key_ge =P1^6;//按键"个加1"
sbit laba =P3^1;//喇叭
void delay(unsigned int z)//1毫秒延时子函数
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
////
//以下是七段数码管驱动程序
////
/
功能描述: 中断接受字符串驱动程序
占用引脚资源 P30
占用系统资源 串口中断;中断向量4
/
#define DUAN P0
#define WEI P2
unsigned char code dispcode[]=
{
0x3F,/0/
0x06,/1/
0x5B,/2/
0x4F,/3/
0x66,/4/
0x6D,/5/
0x7D,/6/
0x07,/7/
0x7F,/8/
0x6F,/9/
}; //共阴段码表
//0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,NULL,-
uchar code dispbitcode[]=
{0xef,0xdf,0xbf,0x7f}; //共阴位码表
uchar dispbuf[4],dispcount;//开辟四个显示缓冲区
void ledinit()/初始化子函数,定时器0刷新显示内容/
{
TMOD|=0x01; // 定时器0方式1
TH0=(65536-5000)/256; //定时器16位模式
TL0=(65536-5000)%256; //溢出时间:5ms
TR0=1; //开启定时器0
ET0=1; //使能定时器0
EA=1; //系统使能
}
void leddisp()//固定显示某些数字
{
dispbuf[0]=time/1000;
dispbuf[1]=time%1000/100;
dispbuf[2]=time%100/10;
dispbuf[3]=time%10;
}
void keytest()//按键检测程序
{
if(!key_qian)//如果千位按键
{
delay(5);//5毫秒延时去抖
if(!key_qian)//如果千位按键的确按下了
{
num_qian++;//千位数字加一
while(!key_qian);//等待按键松开
}
time+=num_qian1000;//千位数字加1
}
if(!key_bai)//如果百位按键
{
delay(5);//5毫秒延时去抖
if(!key_bai)//如果百位按键的确按下了
{
num_bai++;//百位数字加一
while(!key_bai);//等待按键松开
}
time+=num_bai100;//百位数字加1
}
if(!key_shi)//如果十位按键
{
delay(5);//5毫秒延时去抖
if(!key_shi)//如果十位按键的确按下了
{
num_shi++;//千位数字加一
while(!key_shi);//等待按键松开
}
time+=num_shi10;//十位数字加1
}
if(!key_ge)//如果千位按键
{
delay(5);//5毫秒延时去抖
if(!key_ge)//如果个位按键的确按下了
{
num_qian++;//千位数字加一
while(!key_ge);//等待按键松开
}
time+=num_ge;//个位数字加1
}
}
void main()//主程序
{
ledinit();//数码管中断初始化,定时器0刷新显示内容
while(1)//大循环
{
if((!key_qian)||(!key_bai)||(!key_shi)||(!key_ge))//如果四个按键中的任何一个被按下
keytest();//执行按键检测程序
leddisp();//不断的刷新显示内容
}
}
//
//以下是定时器0刷新数码管显示内容驱动程序
//
/
功能描述: 七段数码管驱动程序
占用引脚资源: 数码管段选,数码管位选
占用系统资源T0
/
void t0(void) interrupt 1 //using 0
{
TH0=(65536-5000)/256; //5ms中断
TL0=(65536-5000)%256; //16位定时器模式
WEI=0xff;//关位选
DUAN=dispcode[dispbuf[dispcount]]; //段选
WEI=dispbitcode[dispcount]; //开位选
dispcount++;
if(dispcount==5)
dispcount=0;
tcnt++; //计数个数加一
if(tcnt==5200)//满足1S了
{
tcnt=0;//计数个数归零
time--;//时间减一
if(time==0)//时间
while(1);
}
if(time<10)//时间小于10
laba=~laba;//声音报警
}
这是9999秒倒计时的
刚写的程序,我的思想是用定时器加rand()随机函数来实现的,单片机上电之后通过按键去启动取随机数,若是单片机上电就立即取随机数的话,那每次上电随机的结果都是一样的。然后是0到9不重复的随机数,程序中用了循环来判断是否和前面取的随机数相同,相同则进入下次取随机数,不同则存入数组。程序如下:#include<reg52h>
#include<stdlibh> //包含rand()随机函数的头文件
unsigned char t,k,i,j,a,f,n[10];
//t是计时变量,k是按键标志,i是数组下标,f是随机数重复标志,n[10]是存放随机数的数组
void init() //初始化函数
{
t=0;
i=0;
f=0;
k=0;
TMOD=0x02; //设置定时器0为工作方式2
TH0=7; //装初值
TL0=7;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时0
EX0=1; //开外部中断0,同按键的效果一样
IT0=1; //下降沿触发
}
void main()
{
init();
while(1)
{
while(k) //外部中断0触发循环
{
if(!i) //i=0时取第一个随机数放入数组n[0]
{
srand(t); //随机数初始化
a=(char)(rand()%10); //取随机数(0~9)
n[0]=a; //存入数组
i++; //数组下标加1
}
else
while(i<10) //存放剩下的9个随机数
{
srand(t); //随机数初始化
a=(char)(rand()%10); //取随机数
for(j=0;j<i;j++) //与前面的随机数比较
{
if(n[j]==a) //与前面的随机数相同
f=1; //标志置1
}
if(f) //有重复执行
{
f=0; //标志清0
continue; //结束本次循环
}
n[i]=a; //不同则存入数组中
i++; //数组下标加1
}
}
}
}
void inter0() interrupt 0 //外部中断0
{
k=1; //按键标志置1,主函数执行取随机数
}
void time0() interrupt 1 //定时器0中断
{
t++; //时间加1
if(t==100) t=0;
}
以上就是关于51单片机C语言编程全部的内容,包括:51单片机C语言编程、基于51单片机的999倒计时C语言程序。、51单片机产生随机数c程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)