功能:实现了一个简单的交通灯控制程序,模拟了一个交叉路口的交通信号灯控制系统,通过控制红灯、黄灯和绿灯的亮灭来模拟车辆和行人的通行情况。
效果:
红灯亮,绿灯亮
注意:绿灯结束后需要黄灯闪烁,红灯结束直接是绿灯
代码:
#include
#define uchar unsigned char
#define uint unsigned int
sbit RED_A=P0^0; //东西向灯
sbit YELLOW_A=P0^1;
sbit GREEN_A=P0^2;
sbit RED_B=P0^3; //南北向灯
sbit YELLOW_B=P0^4;
sbit GREEN_B=P0^5;
uchar Flash_Count=0,Operation_Type=1; //闪烁次数,操作类型变量
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
//交通灯切换
void Traffic_Light()
{
switch(Operation_Type)
{
case 1: //东西向绿灯与南北向红灯亮
RED_A=1;YELLOW_A=1;GREEN_A=0;
RED_B=0;YELLOW_B=1;GREEN_B=1;
DelayMS(4000);
Operation_Type=2;
break;
case 2: //东西向黄灯闪烁,绿灯关闭
DelayMS(300);
YELLOW_A=~YELLOW_A;GREEN_A=1;
if(++Flash_Count!=10) return; //闪烁5次
Flash_Count=0;
Operation_Type=3;
break;
case 3: //东西向红灯,南北向绿灯亮
RED_A=0;YELLOW_A=1;GREEN_A=1;
RED_B=1;YELLOW_B=1;GREEN_B=0;
DelayMS(4000);
Operation_Type=4;
break;
case 4: //南北向黄灯闪烁5 次
DelayMS(300);
YELLOW_B=~YELLOW_B;GREEN_B=1` ;
if(++Flash_Count!=10) return; //闪烁5次
Flash_Count=0;
Operation_Type=1;
break;
}
}
//主程序
void main()
{
while(1) Traffic_Light();
}
功能:实现了一个LED灯从中间向两边亮的效果,通过对P0寄存器的位操作,控制LED灯的亮灭状态。
效果:
流水灯从中间向两边亮:
这个实验最主要的就是对P0口的移位操作
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit p00=P0^0;
sbit p01=P0^1;
sbit p02=P0^2;
sbit p03=P0^3;
sbit p04=P0^4;
sbit p05=P0^5;
sbit p06=P0^6;
sbit p07=P0^7;
//延时函数
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
uchar temp,m,n;
uint i;
//中间向两边亮
void main()
{
m=0xef;
n=0xf7;
while(1)
{
P0=m&n;
m=_crol_(m,1);
n=_cror_(n,1);
if(m == 0xfe)
{
m=0xef;
n=0xf7;
}
DelayMS(500);
}
}
功能:实现了一个数字显示器的功能,通过循环显示0到F的数字。
效果:
#include
#define uchar unsigned char
#define uint unsigned int
//共阴极 0 1 2 3 4 5 6 7 8 9 A B C D E F
uint table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
//主程序
void main()
{
uchar i;
while(1)
{
for(i=1; i<=16; i++)
{
P0 = table[i-1];
DelayMS(500);
}
}
}
功能:实现了一个多位数码管显示器的功能,通过循环依次点亮数码管的每一位,并在每一位上显示0到F的数字。
#include
#include
#define uchar unsigned char
#define uint unsigned int
//共阴极 0 1 2 3 4 5 6 7 8 9 A B C D E F
uint table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//二极管位 1 2 3 4 5 6 7 8
uint b[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
//主程序
void main()
{
uchar i;
while(1)
{
for(i=1; i<=8; i++)
{
P2= b[i-1];
P0 = ~table[i];
DelayMS(500);
}
}
}
功能:一个基于51单片机的多位数码管显示器控制程序,程序中使用了P0和P2端口来控制数码管的段选和位选,通过循环依次点亮数码管的每一位,并在每一位上显示学号的十位数字。
效果:
#include
#include
#define uchar unsigned char
#define uint unsigned int
//共阴极 0 1 2 3 4 5 6 7 8 9 A B C D E F
uint code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//二极管位 1 2 3 4 5 6 7 8
uint code b[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//设置位
sbit A8 = P2^0;
sbit A9 = P2^1;
//延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void show(uint duanma,uint weima) //输入位码和段码进行展示
{
P0=~b[weima];A9=1;A9=0; //锁+位码 -- 哪一位显示
P0=~table[duanma];A8=1;A8=0; //琐+段码 -- 显示什么字
DelayMS(500);
}
//主程序
void main()
{
P0=~0x00;A9=1;A9=0; //段码
P0=~0x00;A8=1;A8=0;DelayMS(10); //位码
while(1)
{
uint i,j;
uchar my_xuehao[]={2,0,2,1,2,1,2,9,8,1}; //十位学号
for(i=0;i<10;i++) // 我
{
for(j=0;j<9;j++)
{
show(my_xuehao[(i*8+j)%10],j);
}
}
}
}
功能:基于51单片机的控制程序,用于控制LED灯的亮灭。程序中使用了P0端口来控制LED灯的亮灭状态,通过独立按键控制LED灯的全亮、全灭、从上往下依次亮。
效果:
#include
#include
#define uchar unsigned char
#define uint unsigned int
//共阴极 0 1 2 3 4 5 6 7 8 9 A B C D E F
uint code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//二极管位 1 2 3 4 5 6 7 8
uint code b[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//定义按键位
sbit mp30 = P3^0;
sbit mp31 = P3^1;
sbit mp32 = P3^2;
//延时
//void DelayMS(uint x)
//{
//uchar i;
//while(x--) for(i=0;i<120;i++);
//}
void updown();
//主程序
void main()
{
while(1)
{
if(mp30 == 0) // 全亮
{
P0 =0x00;
}
if(mp31 == 0) // 全灭
{
P0 =0xFF;
}
if(mp32 == 0) // 从上往下亮
{
updown();
}
}
}
updown.c
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit mp30 = P3^0;
sbit mp31 = P3^1;
sbit mp32 = P3^2;
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void updown()
{
uchar mp0;
mp0 = 0x01;
while(1)
{
uchar temp = 0xfe;
uchar i;
for(i=1; i<=4; i++)
{
P0 = temp;
temp = _crol_(temp,1); //移位
DelayMS(500);
}
if((mp30 == 0)||(mp31 ==0))
{
break;
}
}
}
功能:基于51单片机的程序,用于实现一个简单的键盘输入并在数码管上显示相应数字的功能,通过矩阵键盘,扫描行列按键
效果:
#include
#include
#define uchar unsigned char
#define uint unsigned int
// 共阴极 0 1 2 3 4 5 6 7 8 9 A B C D E F
uint code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
// 1 2 3 4 5 6 7 8
// uint code wei[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar num_key=17,pre_num_key=17;
// 延时函数
void DelayMS(uint x)
{
uint i;
while(x--) for(i=0;i<120;i++);
}
//键盘扫描
void scan_key()
{
uint temp;
P1=0Xf0; // 11110000 先行
DelayMS(5);
temp=P1^0Xf0;
if(temp==16)
num_key=0;
if(temp==32)
num_key=1;
if(temp==64)
num_key=2;
if(temp==128)
num_key=3;
P1=0X0f; // 00001111 再列
DelayMS(5);
temp=P1^0X0f;
if(temp==8)
num_key+=0;
if(temp==4)
num_key+=4;
if(temp==2)
num_key+=8;
if(temp==1)
num_key+=12;
}
void main()
{
P0=0X00;
DelayMS(200);
while(1)
{
P1=0XF0;
if(P1!=0XF0)
{
scan_key();
if(num_key!=pre_num_key)
{
P0=table[num_key];
DelayMS(200);
}
}
}
}
功能:基于 8051 单片机的程序,实现了一个简单的计数器功能,并使用数码管进行显示,通过计数按键,每按一次个位加一,累计进位,按下清零归零。
效果:
#include
#define uchar unsigned char
#define uint unsigned int
//共阴极 0 1 2 3 4 5 6 7 8 9 10
uint table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
sbit clear_key = P3^6;
uint count = 0;
uchar ge,shi,bai;
// 延时
void DelayMS(uint x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
//External interrupt0 service routine
void exint0() interrupt 0 //INT0, interrupt 0 (location at 0003H) 自动调用
{
count++;
}
void main()
{
P0 = 0;
P1 = 0;
P2 = 0;
DelayMS(200);
IT0 = 1; //set INT0 interrupt type (1:Falling 0:Low level) 下降沿触发
EX0 = 1; //enable INT0 interrupt 允许
EA = 1; //open global interrupt switch 中断总允许 -- 两条可以写为一条 IE = 0x81
while (1)
{
if(clear_key ==0) count =0;
bai = count / 100;
shi = count / 10 % 10;
ge = count % 10;
if(bai == 0)
{
bai = 10;
if(shi == 0)
{
shi = 10;
}
}
P0 = table[ge];
P1 = table[shi];
P2 = table[bai];
}
}
功能:按下按键开始10秒的计时,再次按下停止秒表,再次按下清零。
效果:
#include
#include
#define uchar unsigned char
#define uint unsigned int
// 共阴极7段显示
uchar code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit K1=P3^7; // 3.7引脚--按键 赋值为K1
uint Timer_count =0; // 定时器中断计数
bit key_state;//按键状态
uint key_flag_idx=0,sec_counter=0;//key_flag_idx-按键的三个状态,初始为0 sec_counter-秒表
void DelayMS(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
void handle_key()
{
if(key_state==0) // 按下按钮
{
key_flag_idx=(key_flag_idx+1)%3; // 按钮的状态在0-2
if(key_flag_idx==1) // 按下开启定时器
{
TR0=1;
ET0=1;
EA=1;
}
if(key_flag_idx==2) // 再次按下停止
{
TR0=0;
ET0=0;
EA=0;
}
if(key_flag_idx==0) // 再次按下清零
{
sec_counter=0; // 计数清零
P2=0x3f; // 显示0
P0=0x00;
DelayMS(200);
}
}
}
//定时器中断 -- 7段显示器
void Timer0_Rountine(void) interrupt 1
{
TL0=(65536-50000)%256; // 计数器每50ms产生一次中断
TH0=(65536-50000)/256;
if(Timer_coun % 20 == 0) // 20 * 50ms = 1秒
{
sec_counter++;// 每1秒,sec_counter 显示屏加一
P2=table[sec_counter%10]; // 显示
P0=table[sec_counter/10];
DelayMS(200);
Timer_coun=0; // 1秒,定时器中断清0
if(sec_counter==100)//100s清零
{
sec_counter=0;
}
}
Timer_coun++;
}
void main()
{
P2=0x00;
P0=0x00;
TMOD=0X01;
TL0=(65536-50000)%256;// 定时器寄存器初始化 -- 50ms
TH0=(65536-50000)/256;
TR0=0;
ET0=0;
EA=0;
key_state=0; // 初始化按钮状态为0
while(1)
{
if(key_state!=K1) // 按键检测
{
DelayMS(5); // 消抖
key_state=K1; // 按下按键 key_state = K1 = 0
handle_key();
}
}
}
功能:显示 09:30:30 的动态时钟
效果:
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; //段码
uchar code wei[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; // 位码
sbit A8=P2^0;
sbit A9=P2^1;
sbit A11=P2^3;
uint Timer_count=0; // 定时器计数标志
bit key_state;
uint shi=9,fen=30,miao=30;
// 延时函数
void DelayMS(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
// 显示函数
void show(uint duanma,uint weima)
{
P0=wei[weima];A9=1;A9=0;
P0=table[duanma];A8=1;A8=0;DelayMS(5);
}
// 定时器
void Timer0_Rountine(void) interrupt 1
{
TR0=0; // 关中断
TL0=(65536-50000)%256; // 同理定时50ms
TH0=(65536-50000)/256;
Timer_count++; // Timer_count定时器
TR0=1; // 开中断
}
void main()
{
P0=0x00;
TMOD=0X01; // 定时器工作在模式1
TL0=(65536-50000)%256; // 定时器初始化 50 ms
TH0=(65536-50000)/256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(Timer_count==20) // 1秒
{
Timer_count=0; // 定时器初始化
miao++; // 增加秒
if(miao>=60)
{
miao=0; // 秒清零
fen++; // 60秒增加一分钟
if(fen>=60) // 60分钟增加一小时
{
fen=0; // 分清零
shi++; // 增加时
if(shi==24) // 24小时变00:00:00
{
shi=0,fen=0,miao=0;
}
}
}
}
show(shi/10,0); // 综合显示 时:分:秒 ,利用显示函数
show(shi%10,1);
show(fen/10,3);
show(fen%10,4);
show(miao/10,6);
show(miao%10,7);
}
}
功能:实现单片机的串口通信,不断打印学号
效果:
#include
#define uchar unsigned char
#define uint unsigned int
//延时
void DelayMS(uint ms)
{
uchar i;
while(ms--) for(i=0;i<120;i++);
}
//向串口发送字符
void Putc_to_SerialPort(uchar c)
{
SBUF=c;
while(TI==0);
TI=0;
}
//向串口发送字符串
void Puts_to_SerialPort(uchar *s)
{
while(*s!='\0')
{
Putc_to_SerialPort(*s);
s++;
DelayMS(5);
}
}
//主程序
void main()
{
uchar c = 89, n = 0, i = 0; // i 用来计数打印的学号个数
char xuehao[]="2021212981";
SCON=0x40; //串口模式1
TMOD=0x20; //T1 工作模式2
TH1=0xfd; //波特率9600
TL1=0xfd;
PCON=0x00; //波特率不倍增TI=0;
TR1=1;
DelayMS(200);
//向主机发送数据
Puts_to_SerialPort("Receiving From 8051...\r\n");
Puts_to_SerialPort("-------------------------------\r\n");
Puts_to_SerialPort("Class: 08052102 Name:WZQ \r\n");
Puts_to_SerialPort("-------------------------------\r\n");
DelayMS(50);
while(1)
{
n = c + i;
xuehao[8] = n / 10 + '0'; //将学号转换为字符串
xuehao[9] = n % 10 + '0';
Puts_to_SerialPort(xuehao);
DelayMS(100);
Putc_to_SerialPort(' ');
if(i== 24) //每输出25个学号换行打印一系列--------
{
c = 81;
Puts_to_SerialPort("\r\n-------------------------------\r\n");
DelayMS(100);
}
i = (i+1)%25;
if(i%5==0) //每输出5个学号后换行
{
Puts_to_SerialPort("\r\n");
DelayMS(100);
}
}
}
2023.12.13
渝北仙桃数据谷