04_点亮实验板上的LED灯
1 #include <reg52.h>
2 sbit LED1 = P1^0;
3 sbit LED2 = P1^1;
4 sbit LED3 = P1^2;
5 sbit LED8 = P1^7;
6 void main()
7 {
8 LED1 = 0;
9 LED2 = 0;
10 LED3 = 0;
11 LED8 = 0;
12 while(1);
13 }
06_数码管的静态显示
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1 = P1^0;
//uint a;
uchar i;
uchar temp;
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 120; y > 0 ; y--);
}
void main()
{
temp = 0x7f;
P1 = temp;
while(1)
{
for(i = 0; i < 8; i++)
{
temp = _cror_(temp,1);
P1 = temp;
delay(1000);
}
}
}
06_数码管的静态显示
1 #include <reg52.h>
2 #include <intrins.h>
3 #define uchar unsigned char
4 #define uint unsigned int
5 sbit we = P2^7;
6 sbit du = P2^6;
7
8 uchar code leddata[]={
9
10 0x3F, //"0"
11 0x06, //"1"
12 0x5B, //"2"
13 0x4F, //"3"
14 0x66, //"4"
15 0x6D, //"5"
16 0x7D, //"6"
17 0x07, //"7"
18 0x7F, //"8"
19 0x6F, //"9"
20 0x77, //"A"
21 0x7C, //"B"
22 0x39, //"C"
23 0x5E, //"D"
24 0x79, //"E"
25 0x71, //"F"
26 0x76, //"H"
27 0x38, //"L"
28 0x37, //"n"
29 0x3E, //"u"
30 0x73, //"P"
31 0x5C, //"o"
32 0x40, //"-"
33 0x00, //熄灭
34 0x00 //自定义
35
36 };
37
38 void delay(uint z)
39 {
40 uint x,y;
41 for(x = z; x > 0; x--)
42 for(y = 114; y > 0 ; y--);
43 }
44
45 void main()
46 {
47 while(1)
48 {
49 du = 1; //打开段选
50 P0 = leddata[1];
51 du = 0; //关闭段选
52 delay(5);
53
54 we = 1;//打开位选
55 P0 = 0;
56 we = 0; //关闭位选
57 delay(5);
58
59
60 }
61
62
63
64
65 }
07_数码管的动态显示与定时器
1 //数码管动态显示12
2 #include <reg52.h>
3 #define uchar unsigned char
4 #define uint unsigned int
5 sbit we = P2^7;
6 sbit du = P2^6;
7
8 uchar code leddata[]={
9
10 0x3F, //"0"
11 0x06, //"1"
12 0x5B, //"2"
13 0x4F, //"3"
14 0x66, //"4"
15 0x6D, //"5"
16 0x7D, //"6"
17 0x07, //"7"
18 0x7F, //"8"
19 0x6F, //"9"
20 0x77, //"A"
21 0x7C, //"B"
22 0x39, //"C"
23 0x5E, //"D"
24 0x79, //"E"
25 0x71, //"F"
26 0x76, //"H"
27 0x38, //"L"
28 0x37, //"n"
29 0x3E, //"u"
30 0x73, //"P"
31 0x5C, //"o"
32 0x40, //"-"
33 0x00, //熄灭
34 0x00 //自定义
35
36 };
37
38 void delay(uint z)
39 {
40 uint x,y;
41 for(x = z; x > 0; x--)
42 for(y = 114; y > 0 ; y--);
43 }
44
45 void main()
46 {
47
48 while(1)
49 {
50 we = 1;//打开位选
51 P0 = 0xfe;//1111 1110 只选通第一位数码管
52 we = 0; //关闭位选
53
54 du = 1; //打开段选
55 P0 = leddata[1];
56 du = 0; //关闭段选
57 delay(5);//延时5毫秒
58
59 we = 1; //打开位选
60 P0 = 0xfd;//1111 1101 只选通第二位数码管
61 we = 0; //关闭位选
62
63 du = 1;//打开段选
64 P0 = leddata[2]; //显示2
65 du = 0; //关闭段选
66 delay(5);//延时5毫秒
67
68 we = 1; //打开位选
69 P0 = 0xfb;//1111 1011 只选通第二位数码管
70 we = 0; //关闭位选
71
72 du = 1;//打开段选
73 P0 = leddata[3]; //显示3
74 du = 0; //关闭段选
75 delay(5);//延时5毫秒
76
77 }
78 }
7_2定时器1定时例程
1 /*定时器1,定时模式 工作模式1 16位计数器,
2 定时20秒后点亮LED1,数码管显示*/
3 #include <reg52.h>
4 #include <intrins.h>
5 #define uchar unsigned char
6 #define uint unsigned int
7 sbit we = P2^7;
8 sbit du = P2^6;
9
10 uchar code leddata[]={
11
12 0x3F, //"0"
13 0x06, //"1"
14 0x5B, //"2"
15 0x4F, //"3"
16 0x66, //"4"
17 0x6D, //"5"
18 0x7D, //"6"
19 0x07, //"7"
20 0x7F, //"8"
21 0x6F, //"9"
22 0x77, //"A"
23 0x7C, //"B"
24 0x39, //"C"
25 0x5E, //"D"
26 0x79, //"E"
27 0x71, //"F"
28 0x76, //"H"
29 0x38, //"L"
30 0x37, //"n"
31 0x3E, //"u"
32 0x73, //"P"
33 0x5C, //"o"
34 0x40, //"-"
35 0x00, //熄灭
36 0x00 //自定义
37
38 };
39
40 void delay(uint z)
41 {
42 uint x,y;
43 for(x = z; x > 0; x--)
44 for(y = 114; y > 0 ; y--);
45 }
46
47 void display(uchar i)
48 {
49 uchar shi, ge;
50 shi = i / 10;//求模 i除以10取商的整数部分
51 ge = i % 10;//求余 i除以10取余数部分
52
53 P0 = 0xff; //清除断码
54 we = 1;//打开位选
55 P0 = 0xfe;//1111 1110 只选通第一位数码管
56 we = 0; //关闭位选
57
58 du = 1; //打开段选
59 P0 = leddata[shi];
60 du = 0; //关闭段选
61 delay(5);//延时5毫秒
62
63 P0 = 0xff;//清除断码
64 we = 1; //打开位选
65 P0 = 0xfd;//1111 1101 只选通第二位数码管
66 we = 0; //关闭位选
67
68 du = 1;//打开段选
69 P0 = leddata[ge];
70 du = 0; //关闭段选
71 delay(5);//延时5毫秒
72 }
73
74 void main()
75 {
76 uchar a; //50次数计数
77 uchar b;//秒计数
78 TR1 = 1;//启动T1
79 TMOD = 0x10;//T1为定时器,工作模式1 16位计数器
80 TH1 = 0x4b;
81 TL1 = 0xfc;//0x4bfc 定时50ms
82 while(1)
83 {
84 if(TF1 == 1)//判断T1是否溢出
85 {
86 TH1 = 0x4b;
87 TL1 = 0xfc;//0x4bfc 定时50ms
88 TF1 = 0;//清零便于下次判断
89 a++;//50毫秒计数加1
90 }
91 if(a == 20)//判断是否到1秒
92 {
93 a = 0;//清零便于下次记录50ms的次数
94 b++;//秒加1
95 }
96 if(b == 20)//检查是否到20秒
97 {
98 TR1 = 0;//时间到关闭定时器1
99 P1 = 0xfe;//点亮LED1
100 }
101
102 display(b);//显示秒的值
103 }
104 }
7_2定时器0定时例程
1 /*定时器0,定时模式 工作模式1 16位计数器,
2 定时20秒后点亮LED2,数码管显示*/
3 #include <reg52.h>
4 #include <intrins.h>
5 #define uchar unsigned char
6 #define uint unsigned int
7 sbit we = P2^7;
8 sbit du = P2^6;
9
10 uchar code leddata[]={
11
12 0x3F, //"0"
13 0x06, //"1"
14 0x5B, //"2"
15 0x4F, //"3"
16 0x66, //"4"
17 0x6D, //"5"
18 0x7D, //"6"
19 0x07, //"7"
20 0x7F, //"8"
21 0x6F, //"9"
22 0x77, //"A"
23 0x7C, //"B"
24 0x39, //"C"
25 0x5E, //"D"
26 0x79, //"E"
27 0x71, //"F"
28 0x76, //"H"
29 0x38, //"L"
30 0x37, //"n"
31 0x3E, //"u"
32 0x73, //"P"
33 0x5C, //"o"
34 0x40, //"-"
35 0x00, //熄灭
36 0x00 //自定义
37
38 };
39
40 void delay(uint z)
41 {
42 uint x,y;
43 for(x = z; x > 0; x--)
44 for(y = 114; y > 0 ; y--);
45 }
46
47 void display(uchar i)
48 {
49 uchar shi, ge;
50 shi = i / 10;//求模 i除以10取商的整数部分
51 ge = i % 10;//求余 i除以10取余数部分
52
53 P0 = 0xff; //清除断码
54 we = 1;//打开位选
55 P0 = 0xfb;//1111 1011 只选通第三位数码管
56 we = 0; //关闭位选
57
58 du = 1; //打开段选
59 P0 = leddata[shi];
60 du = 0; //关闭段选
61 delay(5);//延时5毫秒
62
63 P0 = 0xff;//清除断码
64 we = 1; //打开位选
65 P0 = 0xf7;//1111 0111 只选通第四位数码管
66 we = 0; //关闭位选
67
68 du = 1;//打开段选
69 P0 = leddata[ge];
70 du = 0; //关闭段选
71 delay(5);//延时5毫秒
72 }
73
74 void main()
75 {
76 uchar a; //50次数计数
77 uchar b;//秒计数
78 TR0 = 1;//启动T0
79 TMOD = 0x01;//T0为定时器,工作模式1 16位计数器
80 TH0 = 0x4b;
81 TL0 = 0xfc;//0x4bfc 定时50ms
82 while(1)
83 {
84 if(TF0 == 1)//判断T0是否溢出
85 {
86 TH0 = 0x4b;
87 TL0 = 0xfc;//0x4bfc 定时50ms
88 TF0 = 0;//清零便于下次判断
89 a++;//50毫秒计数加1
90 }
91 if(a == 20)//判断是否到1秒
92 {
93 a = 0;//清零便于下次记录50ms的次数
94 b++;//秒加1
95 }
96 if(b == 20)//检查是否到20秒
97 {
98 TR0 = 0;//时间到关闭定时器1
99 P1 = 0xfd;//点亮LED2
100 }
101
102 display(b);//显示秒的值
103 }
104 }
7_4定时器0计数例程
1 /*定时器1做计数器,工作模式2,使用定时器0让LED1小灯100毫秒闪烁一次,
2 定时器1记录LED1闪烁次数,并且用数码管实时显示计数数值。*/
3 #include <reg52.h>
4 #include <intrins.h>
5 #define uchar unsigned char
6 #define uint unsigned int
7 sbit we = P2^7;
8 sbit du = P2^6;
9 sbit LED1 = P1^0;
10
11 uchar code leddata[]={
12
13 0x3F, //"0"
14 0x06, //"1"
15 0x5B, //"2"
16 0x4F, //"3"
17 0x66, //"4"
18 0x6D, //"5"
19 0x7D, //"6"
20 0x07, //"7"
21 0x7F, //"8"
22 0x6F, //"9"
23 0x77, //"A"
24 0x7C, //"B"
25 0x39, //"C"
26 0x5E, //"D"
27 0x79, //"E"
28 0x71, //"F"
29 0x76, //"H"
30 0x38, //"L"
31 0x37, //"n"
32 0x3E, //"u"
33 0x73, //"P"
34 0x5C, //"o"
35 0x40, //"-"
36 0x00, //熄灭
37 0x00 //自定义
38
39 };
40
41 void delay(uint z)
42 {
43 uint x,y;
44 for(x = z; x > 0; x--)
45 for(y = 114; y > 0 ; y--);
46 }
47
48 void display(uchar i)
49 {
50 uchar bai, shi, ge;
51 bai = i / 100; //显示百位
52 shi = i % 100 / 10; //显示十位
53 ge = i % 10;//显示个位
54
55 P0 = 0xff; //清除断码
56 we = 1;//打开位选
57 P0 = 0xfe;//1111 1110
58 we = 0; //关闭位选
59
60 du = 1; //打开段选
61 P0 = leddata[bai];
62 du = 0; //关闭段选
63 delay(5);//延时5毫秒
64
65 P0 = 0xff;//清除断码
66 we = 1; //打开位选
67 P0 = 0xfd;//1111 1101
68 we = 0; //关闭位选
69
70 du = 1;//打开段选
71 P0 = leddata[shi];
72 du = 0; //关闭段选
73 delay(5);//延时5毫秒
74
75 P0 = 0xff;//清除断码
76 we = 1; //打开位选
77 P0 = 0xfb;//1111 1011
78 we = 0; //关闭位选
79
80 du = 1;//打开段选
81 P0 = leddata[ge];
82 du = 0; //关闭段选
83 delay(5);//延时5毫秒
84 }
85
86 void main()
87 {
88 uchar a; //50次数计数
89 TR0 = 1;//启动T0
90 TR1 = 1;//启动T1
91 TMOD = 0x61;//T0为定时器,工作模式1 16位计数器,T1为计数器,工作模式2,8位自动重装
92 TH0 = 0x4b;
93 TL0 = 0xfc;//0x4bfc 定时50ms
94 TH1 = 20;//8位自动重装
95 TL1 = 0;//当TL1溢出时自动装入TH1的值
96 while(1)
97 {
98 if(TF0 == 1)//判断T0是否溢出
99 {
100 TH0 = 0x4b;
101 TL0 = 0xfc;//0x4bfc 定时50ms
102 TF0 = 0;//清零便于下次判断
103 a++;//50毫秒计数加1
104 }
105 if(a == 2)//判断是否到100毫秒
106 {
107 a = 0;//清零便于下次记录50ms的次数
108 LED1 = ~LED1;//闪烁LED1
109 }
110 display(TL1);//显示T1计数值
111 }
112 }
1 #include <reg52.h>//51头文件
2
3 #define uchar unsigned char//宏定义
4 #define uint unsigned int //宏定义
5 sbit we = P2^7; //位定义数码管位选锁存器接口
6 sbit du = P2^6; //位定义数码管段选锁存器接口
7
8 //数码管段选表
9 uchar code leddata[]={
10
11 0x3F, //"0"
12 0x06, //"1"
13 0x5B, //"2"
14 0x4F, //"3"
15 0x66, //"4"
16 0x6D, //"5"
17 0x7D, //"6"
18 0x07, //"7"
19 0x7F, //"8"
20 0x6F, //"9"
21 0x77, //"A"
22 0x7C, //"B"
23 0x39, //"C"
24 0x5E, //"D"
25 0x79, //"E"
26 0x71, //"F"
27 0x76, //"H"
28 0x38, //"L"
29 0x37, //"n"
30 0x3E, //"u"
31 0x73, //"P"
32 0x5C, //"o"
33 0x40, //"-"
34 0x00, //熄灭
35 0x00 //自定义
36
37 };
38 //毫秒级延时函数
39 void delay(uint z)
40 {
41 uint x,y;
42 for(x = z; x > 0; x--)
43 for(y = 114; y > 0 ; y--);
44 }
45
46 void main()
47 {
48
49 uchar i;
50 we = 1;//打开位选
51 P0 = 0x00;//所有数码管显示
52 we = 0; //关闭位选
53
54 while(1) //大循环
55 {
56 du = 1; //打开段选
57 P0 = leddata[i];
58 du = 0; //关闭段选
59 delay(500);//延时500毫秒
60 i++; //i自加1
61 if(i == 10) //当数值为10时,清零
62 {
63 i = 0;
64 }
65 }
66 }
8_1独立键盘课程实验1
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7; //数码管位选
sbit du = P2^6; //数码管段选
sbit key_s2 = P3^0;//S2按键位定义
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"
0x40, //"-"
0x00, //熄灭
0x00 //自定义
};
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main()
{
uchar num;
we = 1;
P0 = 0xfe; //选通第一个数码管
we = 0;
while(1)
{
du = 1;
P0 = leddata[num]; //显示S2按下次数
du = 0;
if(key_s2 == 0)//判断S2是否按键
{
delay(5);//软件延时
if(key_s2 == 0)
{
num++; //计数加1
}
while(!key_s2); //松手检测
}
if(num == 10) //当数值为超过9时归零
{
num = 0;
}
}
}
8_2独立键盘课程实验2
1 #include<reg52.h>
2 #define uchar unsigned char
3 #define uint unsigned int
4 sbit we = P2^7;
5 sbit du = P2^6;
6
7 sbit key_s2 = P3^0;
8 sbit key_s3 = P3^1;
9 sbit key_s4 = P3^2;
10 sbit key_s5 = P3^3;
11
12 uchar code leddata[]={
13
14 0x3F, //"0"
15 0x06, //"1"
16 0x5B, //"2"
17 0x4F, //"3"
18 0x66, //"4"
19 0x6D, //"5"
20 0x7D, //"6"
21 0x07, //"7"
22 0x7F, //"8"
23 0x6F, //"9"
24 0x77, //"A"
25 0x7C, //"B"
26 0x39, //"C"
27 0x5E, //"D"
28 0x79, //"E"
29 0x71, //"F"
30 0x76, //"H"
31 0x38, //"L"
32 0x37, //"n"
33 0x3E, //"u"
34 0x73, //"P"
35 0x5C, //"o"
36 0x40, //"-"
37 0x00, //熄灭
38 0x00 //自定义
39
40 };
41
42 void delay(uint z)
43 {
44 uint x,y;
45 for(x = z; x > 0; x--)
46 for(y = 114; y > 0 ; y--);
47 }
48
49 void main()
50 {
51 uchar i;//计数有多少个50毫秒产生
52 uchar num;//计数
53 TMOD = 0x01;//定时器0 做定时 模式1 16位计数器
54 TH0 = (0xffff - 50000) / 0xff;
55 TL0 = (0xffff - 50000) % 0xff;//定时50ms
56 we = 1;
57 P0 = 0xfe; //选通第一位数码管
58 we = 0;
59 while(1)
60 {
61 if(TF0 == 1) //判断50ms是否到
62 {
63 TH0 = (0xffff - 50000) / 0xff;
64 TL0 = (0xffff - 50000) % 0xff;//定时50ms
65 TF0 = 0;//清除溢出标志位
66 i++;
67 }
68 if(i == 20)//判断是否到了1秒
69 {
70 i = 0;//清零秒计数
71 num++;//计数值加1
72 }
73 if(num == 10)//当计数值为10时归零
74 {
75 num = 0;
76 }
77 du = 1;
78 P0 = leddata[num]; //数码管实时显示计数值
79 du = 0;
80 if(key_s2 == 0) //判断是否按下S2
81 {
82 delay(5); //软件消抖
83 if(key_s2 == 0)//再次判断是否按下S2
84 {
85 TR0 = 1;//启动定时器0
86 }
87 while(!key_s2);//松手检测
88 }
89 if(key_s3 == 0) //判断S3是否被按下
90 {
91 delay(5);//软件消抖
92 if(key_s3 == 0)//再次判断S3是否被按下
93 {
94 TR0 = 0;//停止定时器0
95 }
96 while(!key_s3);//松手检测
97 }
98 if(key_s4 == 0) //判断S4是否被按下
99 {
100 delay(5); //软件消抖
101 if(key_s4 == 0) //再次判断S4是否被按下
102 {
103 P1 = 0;//点亮P1口所有LED灯
104 }
105 while(!key_s4);//松手检测
106 }
107 if(key_s5 == 0)//判断S5是否被按下
108 {
109 delay(5); //软件消抖
110 if(key_s5 == 0) //再次判断S5是否被按下
111 {
112 P1 = 0xff;//关闭P1口所有LED灯
113 }
114 while(!key_s5); //松手检测
115 }
116 }
117 }
第七课习题答案
1 #include <reg52.h>
2 #include <intrins.h>
3 #define uchar unsigned char
4 #define uint unsigned int
5 sbit we = P2^7;
6 sbit du = P2^6;
7
8 uchar code leddata[]={
9
10 0x3F, //"0"
11 0x06, //"1"
12 0x5B, //"2"
13 0x4F, //"3"
14 0x66, //"4"
15 0x6D, //"5"
16 0x7D, //"6"
17 0x07, //"7"
18 0x7F, //"8"
19 0x6F, //"9"
20 0x77, //"A"
21 0x7C, //"B"
22 0x39, //"C"
23 0x5E, //"D"
24 0x79, //"E"
25 0x71, //"F"
26 0x76, //"H"
27 0x38, //"L"
28 0x37, //"n"
29 0x3E, //"u"
30 0x73, //"P"
31 0x5C, //"o"
32 0x40, //"-"
33 0x00, //熄灭
34 0x00 //自定义
35
36 };
37
38 void delay(uint z)
39 {
40 uint x,y;
41 for(x = z; x > 0; x--)
42 for(y = 114; y > 0 ; y--);
43 }
44
45 void display(uchar i)
46 {
47 uchar shi, ge;
48 shi = i / 10;//显示十位
49 ge = i % 10;//显示个位
50
51 P0 = 0xff; //清除断码
52 we = 1;//打开位选
53 P0 = 0xbf;//1011 1111
54 we = 0; //关闭位选
55
56 du = 1; //打开段选
57 P0 = leddata[shi];
58 du = 0; //关闭段选
59 delay(5);//延时5毫秒
60
61 P0 = 0xff;//清除断码
62 we = 1; //打开位选
63 P0 = 0x7f;//0111 1111
64 we = 0; //关闭位选
65
66 du = 1;//打开段选
67 P0 = leddata[ge];
68 du = 0; //关闭段选
69 delay(5);//延时5毫秒
70 }
71
72 void main()
73 {
74 uchar a; //50次数计数
75 uchar m;//秒
76 TR1 = 1;//启动T1
77 TMOD = 0x10;//T1为定时器,工作模式1 16位计数器
78 TH1 = 0x4b;
79 TL1 = 0xfc;//0x4bfc 定时50ms
80 while(1)
81 {
82 if(TF1 == 1)//判断T1是否溢出
83 {
84 TH1 = 0x4b;
85 TL1 = 0xfc;//0x4bfc 定时50ms
86 TF1 = 0;//清零便于下次判断
87 a++;//50毫秒计数加1
88 }
89 if(a == 20)//判断是否到1秒
90 {
91 a = 0;//清零便于下次记录50ms的次数
92 m++;
93 }
94 display(m);//显示秒
95 if(m == 60) //60秒时间到
96 {
97 TR1 = 0;//关闭定时器
98 we = 1;
99 P0 = 0xff;//关闭数码管
100 we = 0;
101 P1 = 0x7f;//点亮LED8
102 delay(500); //间隔500毫秒
103 while(1)
104 {
105 P1 = _cror_(P1, 1);//LED流水灯循环右移
106 delay(500); //间隔500毫秒
107 }
108 }
109 }
110 }
08_独立键盘
1 #include <reg52.h>
2 #include <intrins.h>
3 #define uchar unsigned char
4 #define uint unsigned int
5 sbit we = P2^7;
6 sbit du = P2^6;
7
8 uchar code leddata[]={
9
10 0x3F, //"0"
11 0x06, //"1"
12 0x5B, //"2"
13 0x4F, //"3"
14 0x66, //"4"
15 0x6D, //"5"
16 0x7D, //"6"
17 0x07, //"7"
18 0x7F, //"8"
19 0x6F, //"9"
20 0x77, //"A"
21 0x7C, //"B"
22 0x39, //"C"
23 0x5E, //"D"
24 0x79, //"E"
25 0x71, //"F"
26 0x76, //"H"
27 0x38, //"L"
28 0x37, //"n"
29 0x3E, //"u"
30 0x73, //"P"
31 0x5C, //"o"
32 0x40, //"-"
33 0x00, //熄灭
34 0x00 //自定义
35
36 };
37
38 void delay(uint z)
39 {
40 uint x,y;
41 for(x = z; x > 0; x--)
42 for(y = 114; y > 0 ; y--);
43 }
44
45 void display(uchar i)
46 {
47 uchar shi, ge;
48 shi = i / 10;//显示十位
49 ge = i % 10;//显示个位
50
51 P0 = 0xff; //清除断码
52 we = 1;//打开位选
53 P0 = 0xbf;//1011 1111
54 we = 0; //关闭位选
55
56 du = 1; //打开段选
57 P0 = leddata[shi];
58 du = 0; //关闭段选
59 delay(5);//延时5毫秒
60
61 P0 = 0xff;//清除断码
62 we = 1; //打开位选
63 P0 = 0x7f;//0111 1111
64 we = 0; //关闭位选
65
66 du = 1;//打开段选
67 P0 = leddata[ge];
68 du = 0; //关闭段选
69 delay(5);//延时5毫秒
70 }
71
72 void main()
73 {
74 uchar a; //50次数计数
75 uchar m;//秒
76 TR1 = 1;//启动T1
77 TMOD = 0x10;//T1为定时器,工作模式1 16位计数器
78 TH1 = 0x4b;
79 TL1 = 0xfc;//0x4bfc 定时50ms
80 while(1)
81 {
82 if(TF1 == 1)//判断T1是否溢出
83 {
84 TH1 = 0x4b;
85 TL1 = 0xfc;//0x4bfc 定时50ms
86 TF1 = 0;//清零便于下次判断
87 a++;//50毫秒计数加1
88 }
89 if(a == 20)//判断是否到1秒
90 {
91 a = 0;//清零便于下次记录50ms的次数
92 m++;
93 }
94 display(m);//显示秒
95 if(m == 60) //60秒时间到
96 {
97 TR1 = 0;//关闭定时器
98 we = 1;
99 P0 = 0xff;//关闭数码管
100 we = 0;
101 P1 = 0x7f;//点亮LED8
102 delay(500); //间隔500毫秒
103 while(1)
104 {
105 P1 = _cror_(P1, 1);//LED流水灯循环右移
106 delay(500); //间隔500毫秒
107 }
108 }
109 }
110 }
09_四乘四矩阵键盘
1 #include <reg52.h>
2 #define uchar unsigned char
3 #define uint unsigned int
4 sbit we = P2^7;
5 sbit du = P2^6;
6 uchar code leddata[]={
7
8 0x3F, //"0"
9 0x06, //"1"
10 0x5B, //"2"
11 0x4F, //"3"
12 0x66, //"4"
13 0x6D, //"5"
14 0x7D, //"6"
15 0x07, //"7"
16 0x7F, //"8"
17 0x6F, //"9"
18 0x77, //"A"
19 0x7C, //"B"
20 0x39, //"C"
21 0x5E, //"D"
22 0x79, //"E"
23 0x71, //"F"
24 0x76, //"H"
25 0x38, //"L"
26 0x37, //"n"
27 0x3E, //"u"
28 0x73, //"P"
29 0x5C, //"o"
30 0x40, //"-"
31 0x00, //熄灭
32 0x00 //自定义
33
34 };
35 void delay(uint z)
36 {
37 uint x,y;
38 for(x = z; x > 0; x--)
39 for(y = 114; y > 0 ; y--);
40 }
41
42
43 uchar KeyScan() //带返回值的子函数
44 {
45 uchar cord_l,cord_h;//声明列线和行线的值的储存变量
46 P3 = 0xf0;//1111 0000
47 if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
48 {
49 delay(5);//软件消抖
50 if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
51 {
52 cord_l = P3 & 0xf0;// 储存列线值
53 P3 = cord_l | 0x0f;
54 cord_h = P3 & 0x0f;// 储存行线值
55 while( (P3 & 0x0f) != 0x0f );//松手检测
56 return (cord_l + cord_h);//返回键值码
57 }
58 }
59
60 }
61
62 void KeyPro()
63 {
64 switch( KeyScan() )
65 {
66 //第一行键值码
67 case 0xee: P0 = leddata[0]; break;
68 case 0xde: P0 = leddata[1]; break;
69 case 0xbe: P0 = leddata[2]; break;
70 case 0x7e: P0 = leddata[3]; break;
71
72 //第二行键值码
73 case 0xed: P0 = leddata[4]; break;
74 case 0xdd: P0 = leddata[5]; break;
75 case 0xbd: P0 = leddata[6]; break;
76 case 0x7d: P0 = leddata[7]; break;
77
78 //第三行键值码
79 case 0xeb: P0 = leddata[8]; break;
80 case 0xdb: P0 = leddata[9]; break;
81 case 0xbb: P0 = leddata[10]; break;
82 case 0x7b: P0 = leddata[11]; break;
83
84 //第四行键值码
85 case 0xe7: P0 = leddata[12]; break;
86 case 0xd7: P0 = leddata[13]; break;
87 case 0xb7: P0 = leddata[14]; break;
88 case 0x77: P0 = leddata[15]; break;
89 }
90 }
91
92 void main()
93 {
94 we = 1;//打开位选
95 P0 = 0;//八位数码管全显示
96 we = 0;//锁存位选
97
98 du = 1;//打开段选端
99 P0 = leddata[22];
100 while(1)
101 {
102 KeyPro();//提取键值码并且送不同数值给数码管显示
103 }
104 }
11_串口通信
1 #include <reg52.h>
2
3 #define uchar unsigned char
4 #define uint unsigned int
5
6 uchar num;
7
8 /*void delay(uint z)
9 {
10 uint x,y;
11 for(x = z; x > 0; x--)
12 for(y = 114; y > 0 ; y--);
13 } */
14 void UART_init()
15 {
16 TMOD = 0x20; //T1工作模式2 8位自动重装
17 TH1 = 0xfd;
18 TL1 = 0xfd; //比特率9600
19 TR1 = 1; //启动T1定时器
20 SM0 = 0;
21 SM1 = 1; //串口工作方式1 10位异步
22 REN = 1; //串口允许接收
23 EA = 1; //开总中断
24 ES = 1; //串口中断打开
25 }
26 void main()
27 {
28 UART_init(); //串口初始化
29 while(1);
30 }
31
32
33 void UART() interrupt 4
34 {
35 if(RI) //检测是否接收完成
36 {
37 num = SBUF; //num 取出接收缓存器的值
38 P1 = SBUF;
39 num++;
40 RI = 0;
41 SBUF = num;
42 while(!TI);
43 TI = 0;
44 }
45 }
1
1 #include <reg52.h>
2
3 #define uchar unsigned char
4 #define uint unsigned int
5
6 uchar count;//全局变量 存储定时器加一计数器溢出次数
7 /*中断服务特殊功能寄存器配置*/
8 void init()
9 {
10
11 TMOD = 0x01; //T0 16为计数工作模式
12 TH0 = 0x4b;
13 TL0 = 0xfd; //T0 定时50ms
14 ET0 = 1; //T0中断
15 TR0 = 1; //启动T0
16 EA = 1; //开总中断
17 }
18
19 void main()
20 {
21 init(); //调用定时器配置函数
22 while(1); //空循环
23 }
24
25 /*定时器0中断服务程序*/
26 void timer0() interrupt 1 //T0内部查询顺序1
27 {
28 TH0 = 0x4b;
29 TL0 = 0xfd; //定时器0再次放初值 50ms
30 count++; //每次溢出计数变量加1
31 if (count == 20) //溢出20次即20*50=1S
32 {
33 P1 = ~P1; //对P1按位取反
34 count = 0; //计数函数清零
35 }
36 }
2
1 #include <reg52.h>
2 #include <intrins.h>
3
4 #define uchar unsigned char
5 #define uint unsigned int
6 sbit we = P2^7;
7 sbit du = P2^6;
8
9 uchar count0,count1;//全局变量 存储定时器加一计数器溢出次数
10 uchar temp0,temp1 = 0x7f; //temp0负责数码管的值,temp1负责流水灯的值
11
12 uchar code leddata[]={
13
14 0x3F, //"0"
15 0x06, //"1"
16 0x5B, //"2"
17 0x4F, //"3"
18 0x66, //"4"
19 0x6D, //"5"
20 0x7D, //"6"
21 0x07, //"7"
22 0x7F, //"8"
23 0x6F, //"9"
24 0x77, //"A"
25 0x7C, //"B"
26 0x39, //"C"
27 0x5E, //"D"
28 0x79, //"E"
29 0x71, //"F"
30 0x76, //"H"
31 0x38, //"L"
32 0x37, //"n"
33 0x3E, //"u"
34 0x73, //"P"
35 0x5C, //"o"
36 0x40, //"-"
37 0x00, //熄灭
38 0x00 //自定义
39
40 };
41
42 void delay(uint z) //1MS延时
43 {
44 uint x,y;
45 for(x = z; x > 0; x--)
46 for(y = 114; y > 0 ; y--);
47 }
48
49 void display(uchar i) //数码管显示函数
50 {
51 uchar shi,ge;
52 shi = i / 10; //求模
53 ge = i % 10; //求余
54
55 P0 = 0xff; //清除段码
56 we = 1;
57 P0 = 0xfe; //点亮第一位数码管
58 we = 0;
59
60 du = 1;
61 P0 = leddata[shi];
62 du = 0;
63 delay(1);
64
65 P0 = 0xff; //清除段码
66 we = 1;
67 P0 = 0xfd; //点亮第二位数码管
68 we = 0;
69
70 du = 1;
71 P0 = leddata[ge];
72 du = 0;
73 delay(1);
74 }
75
76 /*中断服务特殊功能寄存器配置*/
77 void init()
78 {
79
80 TMOD = 0x11; //定时器T1/T0 16为计数工作模式
81 TH1 = TH0 = 0x4b;
82 TL1 = TL0 = 0xfd; //T1/T0 定时50ms
83 ET1 = ET0 = 1; //开T1/T0中断
84 TR1 = TR0 = 1; //启动T1/T0
85 EX0 = 1; //开外部中断0
86 IT0 = 0; //外部中断0为低电平触发
87 EA = 1; //开总中断
88 }
89
90 void main()
91 {
92 init(); //调用配置函数
93 while(1)
94 {
95 display(temp0);//数码管显示
96 }
97 }
98
99 void int0() interrupt 0 //外部中断0,中断服务程序
100 {
101 TR0 = 0; //关闭定时器0
102 }
103
104 /*定时器0中断服务程序*/
105 void timer0() interrupt 1 //T0内部查询顺序1
106 {
107 TH0 = 0x4b;
108 TL0 = 0xfd; //定时器0再次放初值 50ms
109 count0++;
110 if (count0 == 20)
111 {
112 count0 = 0;
113 temp0++;
114 if (temp0 > 60)
115 {
116 temp0 = 0;
117 }
118 }
119 }
120
121 /*定时器1中断服务程序*/
122 void timer1() interrupt 3 //T1内部查询顺序3
123 {
124 TH1 = 0x4b;
125 TL1 = 0xfd; //定时器1再次放初值 50ms
126 count1++;
127 if (count1 == 10)
128 {
129 count1 = 0;
130 P1 = temp1;
131 temp1 = _cror_(temp1,1);//循环右移一次
132 }
133 }
12_IIC总线EEPROM
1 # include <reg52.h>
2 # include <intrins.h>
3
4 #define uchar unsigned char
5 #define uint unsigned int
6 #define AT24C02_ADDR 0xa0 //AT24C02地址
7
8 /*I2C IO口定义*/
9 sbit SDA = P2^0;
10 sbit SCL = P2^1;
11
12 /*5us延时*/
13 void delay_5us()
14 {
15 _nop_();
16 }
17
18 /*1Ms延时*/
19 void delay(uint z)
20 {
21 uint x,y;
22 for(x = z; x > 0; x--)
23 for(y = 114; y > 0 ; y--);
24 }
25
26 /*I2C初始化*/
27 void I2C_init()
28 {
29 SDA = 1;
30 _nop_();
31 SCL = 1;
32 _nop_();
33 }
34
35 /*I2C起始信号*/
36 void I2C_Start()
37 {
38 SCL = 1;
39 _nop_();
40 SDA = 1;
41 delay_5us();
42 SDA = 0;
43 delay_5us();
44 }
45
46 /*I2C终止信号*/
47 void I2C_Stop()
48 {
49 SDA = 0;
50 _nop_();
51 SCL = 1;
52 delay_5us();
53 SDA = 1;
54 delay_5us();
55 }
56
57 /*主机发送应答*/
58 void Master_ACK(bit i)
59 {
60 SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
61 _nop_(); // 让总线稳定
62 if (i) //如果i = 1 那么拉低数据总线 表示主机应答
63 {
64 SDA = 0;
65 }
66 else
67 {
68 SDA = 1; //发送非应答
69 }
70 _nop_();//让总线稳定
71 SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
72 delay_5us();
73 SCL = 0;//拉低时钟总线, 占用总线继续通信
74 _nop_();
75 SDA = 1;//释放SDA数据总线。
76 _nop_();
77 }
78
79 /*检测从机应答*/
80 bit Test_ACK()
81 {
82 SCL = 1;
83 delay_5us();
84 if (SDA)
85 {
86 SCL = 0;
87 _nop_();
88 I2C_Stop();
89 return(0);
90 }
91 else
92 {
93 SCL = 0;
94 _nop_();
95 return(1);
96 }
97 }
98
99 /*发送一个字节*/
100 void I2C_send_byte(uchar byte)
101 {
102 uchar i;
103 for(i = 0 ; i < 8 ; i++)
104 {
105 SCL = 0;
106 _nop_();
107 if (byte & 0x80)
108 {
109 SDA = 1;
110 _nop_();
111 }
112 else
113 {
114 SDA = 0;
115 _nop_();
116 }
117 SCL = 1;
118 _nop_();
119 byte <<= 1; // 0101 0100B
120 }
121 SCL = 0;
122 _nop_();
123 SDA = 1;
124 _nop_();
125 }
126
127
128 /*I2C 读一字节*/
129 uchar I2C_read_byte()
130 {
131 uchar dat,i;
132 SCL = 0;
133 _nop_();
134 SDA = 1;
135 _nop_();
136 for(i = 0 ; i < 8 ; i++)
137 {
138 SCL = 1;
139 _nop_();
140 if (SDA)
141 {
142 dat |= 0x01; //
143 }
144 else
145 {
146 dat &= 0xfe; //1111 1110
147 }
148 _nop_();
149 SCL = 0 ;
150 _nop_();
151 if(i < 7)
152 {
153 dat = dat << 1;
154 }
155 }
156 return(dat);
157 }
158
159 /*I2C发送数据*/
160 bit I2C_TransmitData(uchar ADDR, DAT)
161 {
162 I2C_Start();
163 I2C_send_byte(AT24C02_ADDR+0);
164 if (!Test_ACK())
165 {
166 return(0);
167 }
168 I2C_send_byte(ADDR);
169 if (!Test_ACK())
170 {
171 return(0);
172 }
173 I2C_send_byte(DAT);
174 if (!Test_ACK())
175 {
176 return(0);
177 }
178 I2C_Stop();
179 return(1);
180 }
181
182 /*I2C接收数据*/
183 uchar I2C_ReceiveData(uchar ADDR)
184 {
185 uchar DAT;
186 I2C_Start();
187 I2C_send_byte(AT24C02_ADDR+0);
188 if (!Test_ACK())
189 {
190 return(0);
191 }
192 I2C_send_byte(ADDR);
193 Master_ACK(0);
194 I2C_Start();
195 I2C_send_byte(AT24C02_ADDR+1);
196 if (!Test_ACK())
197 {
198 return(0);
199 }
200 DAT = I2C_read_byte();
201 Master_ACK(0);
202 I2C_Stop();
203 return(DAT);
204 }
205
206 void main()
207 {
208 I2C_init();//I2C初始化
209 if(!I2C_TransmitData(255,0xf0)); //往AT24C02第255个单元中写入数据0XF0
210 {
211 P1 = 0;
212 }
213 delay(5);
214 /**/
215 P1 = I2C_ReceiveData(255);//从AT24C02第255个单元中读取数据
216 while(1);
217 }
第一题串口接收一字节数码管以十进制显示
1 /*
2 以4800bps从计算机发任意一字节数据,通过数码管以十进制显示
3 的形式显示出来。
4 */
5 #include <reg52.h>
6
7 #define uchar unsigned char
8 #define uint unsigned int
9
10 sbit we = P2^7; //数码管位选
11 sbit du = P2^6; //数码管段选
12
13 /*数码管段码*/
14 uchar code leddata[]={
15
16 0x3F, //"0"
17 0x06, //"1"
18 0x5B, //"2"
19 0x4F, //"3"
20 0x66, //"4"
21 0x6D, //"5"
22 0x7D, //"6"
23 0x07, //"7"
24 0x7F, //"8"
25 0x6F, //"9"
26 0x77, //"A"
27 0x7C, //"B"
28 0x39, //"C"
29 0x5E, //"D"
30 0x79, //"E"
31 0x71, //"F"
32 0x76, //"H"
33 0x38, //"L"
34 0x37, //"n"
35 0x3E, //"u"
36 0x73, //"P"
37 0x5C, //"o"
38 0x40, //"-"
39 0x00, //熄灭
40 0x00 //自定义
41
42 };
43
44 /*1毫秒延时函数*/
45 void delay(uint z)
46 {
47 uint x,y;
48 for(x = z; x > 0; x--)
49 for(y = 114; y > 0 ; y--);
50 }
51
52 /*
53 串口初始化函数
54 工作模式1 10位异步收发 发送速率4800bps
55 */
56 void UART_init()
57 {
58 TMOD = 0x20; //T1工作模式2 8位自动重装
59 TH1 = 0xfa;
60 TL1 = 0xfa; //比特率4800
61 TR1 = 1; //启动T1定时器
62 SM0 = 0;
63 SM1 = 1; //串口工作方式1 10位异步
64 REN = 1; //串口允许接收
65 }
66
67 /*3位数码管显示函数*/
68 void display(uchar num)
69 {
70 uchar bai,shi,ge;
71 bai = num / 100; //求模
72 shi = num % 100 / 10; //求余100后求出有多少个10
73 ge = num % 10; //求余
74
75 P0 = 0xff; //清除断码
76 we = 1;
77 P0 = 0xfe; //点亮第一位数码管
78 we = 0;
79
80 du = 1;
81 P0 = leddata[bai]; //显示百位
82 du = 0;
83 delay(1);
84
85 P0 = 0xff; //清除断码
86 we = 1;
87 P0 = 0xfd;//点亮第二位数码管
88 we = 0;
89
90 du = 1;
91 P0 = leddata[shi]; //显示十位
92 du = 0;
93 delay(1);
94
95 P0 = 0xff; //清除断码
96 we = 1;
97 P0 = 0xfb;//点亮第三位数码管
98 we = 0;
99
100 du = 1;
101 P0 = leddata[ge]; //显示各位
102 du = 0;
103 delay(1);
104 }
105
106 void main()
107 {
108 UART_init();//串口配置初始化
109 while(1)
110 {
111 if (RI) //检测是否接收完成
112 {
113 RI = 0; //清除接收标志位,以便于下次接收
114 }
115 display(SBUF); //取出接收SBUF的值赋给数码管显示
116 }
117 }
第二题发送矩阵键盘的按键值到计算机
1 /*
2 把矩阵键盘的键值以2400bps上传到计算机串口助手
3 */
4 #include <reg52.h>
5
6 #define uchar unsigned char
7 #define uint unsigned int
8
9 /*1毫秒延时函数*/
10 void delay(uint z)
11 {
12 uint x,y;
13 for(x = z; x > 0; x--)
14 for(y = 114; y > 0 ; y--);
15 }
16
17 /*
18 串口初始化函数
19 工作模式1 10位异步收发 发送速率2400bps
20 */
21 void UART_init()
22 {
23 TMOD = 0x20; //T1工作模式2 8位自动重装
24 TH1 = 0xf4;
25 TL1 = 0xf4; //比特率2400,计算公式256-11059200/2400/32/12
26 TR1 = 1; //启动T1定时器
27 SM0 = 0;
28 SM1 = 1; //串口工作方式1 10位异步
29 // REN = 1; //串口允许接收
30 }
31
32 /*
33 4*4矩阵键盘扫描函数
34 带返回值,返回键值码
35 */
36 uchar KeyScan()
37 {
38 uchar cord_l,cord_h;//声明列线和行线的值的储存变量
39 P3 = 0xf0;//1111 0000
40 if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
41 {
42 delay(5);//软件消抖
43 if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下
44 {
45 cord_l = P3 & 0xf0;// 储存列线值
46 P3 = cord_l | 0x0f;
47 cord_h = P3 & 0x0f;// 储存行线值
48 while( (P3 & 0x0f) != 0x0f );//松手检测
49 return (cord_l + cord_h);//返回键值码
50 }
51 }
52
53 }
54
55 /*
56 4*4矩阵键盘键值码处理函数
57 返回转换后的键值码
58 */
59 uchar KeyPro()
60 {
61 uchar key_value; //存放转换后的按键值
62 switch( KeyScan() )
63 {
64 //第一行键值码
65 case 0xee: key_value = 0x01; break;
66 case 0xde: key_value = 0x02; break;
67 case 0xbe: key_value = 0x03; break;
68 case 0x7e: key_value = 0x04; break;
69
70 //第二行键值码
71 case 0xed: key_value = 0x05; break;
72 case 0xdd: key_value = 0x06; break;
73 case 0xbd: key_value = 0x07; break;
74 case 0x7d: key_value = 0x08; break;
75
76 //第三行键值码
77 case 0xeb: key_value = 0x09; break;
78 case 0xdb: key_value = 0x0a; break;
79 case 0xbb: key_value = 0x0b; break;
80 case 0x7b: key_value = 0x0c; break;
81
82 //第四行键值码
83 case 0xe7: key_value = 0x0d; break;
84 case 0xd7: key_value = 0x0e; break;
85 case 0xb7: key_value = 0x0f; break;
86 case 0x77: key_value = 0x10; break;
87 }
88 return (key_value);//返回转换后的键值码
89 }
90
91
92 void main()
93 {
94 UART_init();//串口初始化
95 while(1)
96 {
97 SBUF = KeyPro();//调用带返回值的键值码转换函数,把转换后的键值码送入发送SBUF
98 while(!TI); //检测是否发送完毕
99 TI = 0; //清楚发送完毕标志位,已便于下次发送
100 }
101 }
定时器工作方式0
1 /*利用定时器0工作模式0,编写间隔一秒闪烁灯程序*/
2 # include <reg52.h>
3 sbit D1 = P1^0;//LED灯对于IO口位声明
4
5 void main()
6 {
7 TMOD = 0x00; //定时器0工作模式0,13位计数器
8 TH0 = (8192 - 4608) / 32;//TH储存13位中高8位
9 TL0 = (8192 - 4608) % 32;//TL储存13位中低5位,定时5毫秒
10 ET0 = 1; //开定时器0中断
11 TR0 = 1; //启动定时器0
12 EA = 1; //开总中断
13 while (1);//等待中断
14 }
15
16 void Timer0() interrupt 1//定时器0中断服务程序
17 {
18 static unsigned char i;//溢出次数计数静态变量
19 TH0 = (8192 - 4608) / 32;
20 TL0 = (8192 - 4608) % 32;/*每次溢出后需给定时器0放置初值*/
21 i++;
22 if (i == 200) //200次溢出后1秒时间到
23 {
24 D1 = ~D1;//将LED灯状态取反
25 i = 0; // 清零溢出计次数
26 }
27 }
定时器工作方式1
1 /*晶振平率11.0592Mhz利用定时器0工作模式1,编写间隔一秒闪烁灯程序*/
2 # include <reg52.h>
3 sbit D1 = P1^0;//LED灯对应IO口位声明
4 void main()
5 {
6 TMOD = 0x01;//设置定时器0的工作方式1
7 TH0 = 0x4c;//寄存器TH0中装入4C,或者该语句改为TH0 = (65536 - 46080) /256
8 TL0 = 0x00;//寄存器TL0中装入00,或者该语句改为TL0 = (65536 - 46080) % 256
9 ET0 = 1; //开定时器T0中断
10 EA = 1; //开总中断,上一句和此句可以合并为一句IE=0x82H
11 TR0 = 1; //启动定时器0
12 while (1);//等待中断
13 }
14 void Timer0() interrupt 1//定时器T0中断服务程序
15 {
16 static unsigned char i;//静态计数变量
17 TH0 = 0xDC;
18 TL0 = 0x00;/*每次加1计数器计满溢出后,需给加1计数器重新装入初值*/
19 i++;
20 if (i == 20) //循环次数达到20次,1秒定时时间到
21 {
22 D1 = !D1;//将LED灯状态取反
23 i = 0;//清零计数变量
24 }
25 }
定时器工作方式2
1 /*晶振频率12Mhz利用定时器0工作模式2,编写间隔500毫秒闪烁灯程序*/
2 # include <reg52.h>
3 sbit D1 = P1^0;//LED灯对于IO口位声明
4
5 void main()
6 {
7 TMOD = 0x02; //定时器0工作模式2,自动重装8位计数器
8 TH0 = 256 - 200;//TH储存8位重装初值
9 TL0 = 256 - 200;//TL储存8位初值,定时200微秒
10 ET0 = 1; //开定时器0中断
11 TR0 = 1; //启动定时器0
12 EA = 1; //开总中断
13 while (1);//等待中断
14 }
15
16 void Timer0() interrupt 1//定时器0中断服务程序
17 {
18 static unsigned int i;//溢出次数计数静态变量
19 i++;
20 if (i == 2500) //2500次溢出后500毫秒时间到
21 {
22 D1 = ~D1;//将LED灯状态取反
23 i = 0; // 清零溢出计次数
24 }
25 }
定时器工作方式3
1 /*
2 晶振频率12Mhz利用定时器0工作模式3
3 编写利用TL0计数器所对应的定时器实现间隔500毫秒闪烁一个LED灯
4 利用TH0计数器所对应的定时器实现间隔250毫秒闪烁另一个LED灯
5 */
6 # include <reg52.h>
7 sbit D1 = P1^0;//LED灯对于IO口位声明
8 sbit D2 = P1^1;
9
10 void main()
11 {
12 TMOD = 0x03; //定时器0工作模式3,2个独立的8位计数器
13 TH0 = 256 - 200;//TH0储存8位初值, 定时200微秒
14 TL0 = 256 - 200;//TL0储存8位初值,定时200微秒
15 ET0 = 1; //开定时器TL0中断
16 ET1 = 1; //开定时器TH0中断
17 TR0 = 1; //启动定时器TL0
18 TR1 = 1; //启动定时器TH0
19 EA = 1; //开总中断
20 while (1);//等待中断
21 }
22
23 void TL0_Timer() interrupt 1//定时器TL0中断服务程序
24 {
25 static unsigned int i;//溢出次数计数静态变量
26 TL0 = 256 - 200;//TL0初值重装,定时200微秒
27 i++;
28 if (i == 2500) //2500次溢出后500毫秒时间到
29 {
30 D1 = ~D1;//将第一个LED灯状态取反
31 i = 0; // 清零溢出计次数
32 }
33 }
34
35 void TH0_Timer() interrupt 3//定时器TH0中断服务程序
36 {
37 static unsigned int i;//溢出次数计数静态变量
38 TH0 = 256 - 200;//TH0初值重装,定时200微秒
39 i++;
40 if (i == 1250) //1250次溢出后250毫秒时间到
41 {
42 D2 = ~D2;//将第二个LED灯状态取反
43 i = 0; // 清零溢出计次数
44 }
45 }
定时器计数 模式
1 /*
2 编写利用定时器0工作模式2,8位计数模式,用杜邦线一端接P1.1
3 另一端P3.4引脚,记录P1.1脉冲次数,每10次脉冲触发一次中断,
4 使计数器溢出产生中断点亮LED小灯*/
5 # include <reg52.h>
6 sbit D1 = P1^0;//LED灯对于IO口位声明
7 sbit IN = P1^1;//脉冲输出IO口
8
9 void main()
10 {
11 unsigned int b;//延时变量
12 TMOD = 0x06; //定时器0工作模式2,8位计数模式(00000110)
13 TH0 = 256 - 10; //TH储存8位重装初值
14 TL0 = 256 - 10; //TL储存8位初值
15 ET0 = 1; //开定时器0中断
16 TR0 = 1; //启动定时器0
17 EA = 1; //开总中断
18 while (1)
19 {
20 IN = 1;//置高脉冲输出IO口
21 for(b = 0; b < 60000 ; b++); //延时
22 IN = 0;//置低脉冲输出IO口
23 for(b = 0; b < 60000 ; b++);//延时
24 }
25 }
26
27 void Timer0() interrupt 1//定时器0中断服务程序
28 {
29 D1 = ~D1;//将LED灯状态取反
30 }
1 #include <reg52.h>
2 #include <intrins.h>
3 #define MAIN_Fosc 11059200UL //宏定义主时钟HZ
4 #define PCF8591_ADDR 0x90 //PCF8591地址
5 #define DACOUT_EN 0x40 //DAC输出使能
6
7 /*====================================
8 自定义类型名
9 ====================================*/
10 typedef unsigned char INT8U;
11 typedef unsigned char uchar;
12
13 typedef unsigned int INT16U;
14 typedef unsigned int uint;
15
16 /*====================================
17 硬件接口位声明
18 ====================================*/
19 sbit SDA = P2^0; //I2C串行数据
20 sbit SCL = P2^1; //I2C串行时钟
21 sbit DU = P2^6; //数码管段选
22 sbit WE = P2^7; //数码管位选
23 sbit LED1= P1^0; //读取AD的值是否成功(亮成功,灭失败)
24 sbit LED2= P1^1; //DAC成功输出(亮成功,灭失败)
25 sbit BEEP= P2^3; //蜂鸣器引脚定义
26
27 uchar AD_Value; //存储AD转换回的数字量
28 /*====================================
29 共阴极数码管段选码
30 ====================================*/
31 uchar code table[]={
32 //0 1 2 3 4 5 6 7 8
33 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
34 //9 A B C D E F - . 关显示
35 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
36 };
37
38 /*====================================
39 数码管位选码
40 ====================================*/
41 //第1位 2位 3位 4位 5位 6位 7位 8位
42 uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
43
44 /*====================================
45 函数:void Delay_Ms(INT16U ms)
46 参数:ms,毫秒延时形参
47 描述:12T 51单片机自适应主时钟毫秒级延时函数
48 ====================================*/
49 void Delay_Ms(INT16U ms)
50 {
51 INT16U i;
52 do{
53 i = MAIN_Fosc / 96000;
54 while(--i); //96T per loop
55 }while(--ms);
56 }
57
58 /*====================================
59 函数:void Delay5us()
60 描述:12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M)
61 ====================================*/
62 void Delay5us()
63 {
64 #if MAIN_Fosc == 11059200
65 _nop_();
66 #elif MAIN_Fosc == 12000000
67 _nop_();
68 #elif MAIN_Fosc == 22118400
69 _nop_(); _nop_(); _nop_();
70 #endif
71 }
72
73 /*====================================
74 函数:void Display(INT8U Value)
75 参数:Value,显示值 取值0-255
76 描述:共阴极数码管显示函数可显示一个字节的数
77 ====================================*/
78 void Display(INT8U Value)
79 {
80 //------------------------------
81 DU = 1;
82 P0 = table[Value/100]; //管显示百位
83 DU = 0;
84
85 P0 = 0xff; //清除断码
86
87 WE = 1;
88 P0 = T_COM[0]; //第一位数码管
89 WE = 0;
90 Delay_Ms(5);
91 //-------------------------------
92 DU = 1;
93 P0 = table[Value%100/10]; //显示十位
94 DU = 0;
95
96 P0 = 0xff; //清除断码
97
98 WE = 1;
99 P0 = T_COM[1]; //第二位数码管
100 WE = 0;
101 Delay_Ms(5);
102 //-------------------------------
103 DU = 1;
104 P0 = table[Value%10]; //显示个位
105 DU = 0;
106
107 P0 = 0xff; //清除断码
108
109 WE = 1;
110 P0 = T_COM[2]; //第三位数码管
111 WE = 0;
112 Delay_Ms(5);
113 }
114
115 /*====================================
116 函数:I2C_init()
117 描述:I2C总线初始化
118 ====================================*/
119 void I2C_init()
120 {
121 SDA = 1; //数据总线高
122 _nop_();
123 SCL = 1; //时钟总线高
124 _nop_();
125 }
126
127 /*====================================
128 函数:I2C_Start()
129 描述:I2C起始信号
130 ====================================*/
131 void I2C_Start()
132 {
133 SCL = 1;
134 _nop_();
135 SDA = 1;
136 Delay5us();
137 SDA = 0;
138 Delay5us();
139 }
140
141 /*====================================
142 函数:I2C_Stop()
143 描述:I2C停止信号
144 ====================================*/
145 void I2C_Stop()
146 {
147 SDA = 0;
148 _nop_();
149 SCL = 1;
150 Delay5us();
151 SDA = 1;
152 Delay5us();
153 }
154
155 /*====================================
156 函数:Master_ACK(bit i)
157 参数:i 为0时发送非应答 为1时发送应答
158 描述:I2C主机发送应答
159 ====================================*/
160 void Master_ACK(bit i)
161 {
162 SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
163 _nop_(); // 让总线稳定
164 if (i) //如果i = 1 那么拉低数据总线 表示主机应答
165 {
166 SDA = 0;
167 }
168 else
169 {
170 SDA = 1; //发送非应答
171 }
172 _nop_();//让总线稳定
173 SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号
174 _nop_();
175 SCL = 0;//拉低时钟总线, 占用总线继续通信
176 _nop_();
177 SDA = 1;//释放SDA数据总线。
178 _nop_();
179 }
180
181 /*====================================
182 函数:Test_ACK()
183 返回:0为非应答 1为应答
184 描述:I2C检测从机应答
185 ====================================*/
186 bit Test_ACK() // 检测从机应答
187 {
188 SCL = 1;//时钟总线为高电平期间可以读取从机应答信号
189 Delay5us();
190 if (SDA)
191 {
192 SCL = 0;
193 I2C_Stop();
194 return(0);
195 }
196 else
197 {
198 SCL = 0;
199 return(1);
200 }
201 }
202
203 /*====================================
204 函数:I2C_send_byte(uchar byte)
205 参数:byte 要发送的字节
206 描述:I2C发送一个字节
207 ====================================*/
208 void I2C_send_byte(uchar byte)
209 {
210 uchar i;
211 for(i = 0 ; i < 8 ; i++)
212 {
213 SCL = 0;
214 _nop_();
215 if (byte & 0x80) //
216 {
217 SDA = 1;
218 _nop_();
219 }
220 else
221 {
222 SDA = 0;
223 _nop_();
224 }
225 SCL = 1;
226 _nop_();
227 byte <<= 1;
228 }
229 SCL = 0;
230 _nop_();
231 SDA = 1;
232 _nop_();
233 }
234
235 /*====================================
236 函数:I2C_read_byte()
237 返回:读取的字节
238 描述:I2C读一个字节
239 ====================================*/
240 uchar I2C_read_byte()
241 {
242 uchar i, dat;
243 SCL = 0 ;
244 _nop_();
245 SDA = 1;
246 _nop_();
247 for(i = 0 ; i < 8 ; i++)
248 {
249 SCL = 1;
250 _nop_();
251 dat <<= 1;
252 if (SDA)
253 {
254 dat |= 0x01;
255 }
256 _nop_();
257 SCL = 0;
258 _nop_();
259 }
260 return(dat);
261 }
262
263 /*DAC输出*/
264 bit DAC_OUT(uchar DAT)
265 {
266 I2C_Start();
267 I2C_send_byte(PCF8591_ADDR+0);
268 if (!Test_ACK())
269 {
270 return(0);
271 }
272 I2C_send_byte(DACOUT_EN); //DA输出使能
273 if (!Test_ACK())
274 {
275 return(0);
276 }
277 I2C_send_byte(DAT);
278 if (!Test_ACK())
279 {
280 return(0);
281 }
282 I2C_Stop();
283 return(1);
284 }
285
286 /*读AD数据*/
287 bit ADC_Read(uchar CON)
288 {
289 I2C_Start();
290 I2C_send_byte(PCF8591_ADDR+0);
291 if (!Test_ACK())
292 {
293 return(0);
294 }
295 I2C_send_byte(CON);
296 Master_ACK(0);
297 I2C_Start();
298 I2C_send_byte(PCF8591_ADDR+1);
299 if (!Test_ACK())
300 {
301 return(0);
302 }
303 AD_Value = I2C_read_byte();
304 Master_ACK(0);
305 I2C_Stop();
306 return(1);
307 }
308
309 void main()
310 {
311 I2C_init();
312 while(1)
313 {
314 //单端输入,读出通道2的值
315 if (ADC_Read(0x02)) LED1 = 0; else LED1 = 1;
316 if (DAC_OUT(AD_Value)) LED2 = 0; else LED2 = 1;
317 Display(AD_Value);
318 if (AD_Value > 150) BEEP = 0; else BEEP = 1;
319 Delay_Ms(5);
320 }
321 }
14_数字温度传感器DS18B20
1 #include <reg52.h>
2 #include <intrins.h>
3 #define MAIN_Fosc 11059200UL //宏定义主时钟HZ
4 /*====================================
5 自定义类型名
6 ====================================*/
7 typedef unsigned char INT8U;
8 typedef unsigned char uchar;
9
10 typedef unsigned int INT16U;
11 typedef unsigned int uint;
12
13 /*====================================
14 硬件接口位声明
15 ====================================*/
16 sbit DS = P2^2; //DS18B20单总线
17 sbit DU = P2^6; //数码管段选
18 sbit WE = P2^7; //数码管位选
19 /*====================================
20 共阴极数码管段选码
21 ====================================*/
22 uchar code table[]={
23 //0 1 2 3 4 5 6 7 8
24 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
25 //9 A B C D E F - . 关显示
26 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
27 };
28
29 /*====================================
30 数码管位选码
31 ====================================*/
32 //第1位 2位 3位 4位 5位 6位 7位 8位
33 uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
34
35 /*====================================
36 函数:void Delay_Ms(INT16U ms)
37 参数:ms,毫秒延时形参
38 描述:12T 51单片机自适应主时钟毫秒级延时函数
39 ====================================*/
40 void Delay_Ms(INT16U ms)
41 {
42 INT16U i;
43 do{
44 i = MAIN_Fosc / 96000;
45 while(--i); //96T per loop
46 }while(--ms);
47 }
48 /*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/
49 void Delay_us(uchar us)
50 {
51 while(us--);
52 }
53 /*====================================
54 函数:void Display(INT16U Value)
55 参数:Value,显示值 取值0-65535
56 描述:共阴极数码管显示函数可显示一个字节的数
57 ====================================*/
58 void Display(INT16U Value) //注意由于需要显示的数大于一个字节所有形参需为int型
59 {
60 //------------------------------
61 DU = 0; //关闭段选
62 P0 = table[Value/100]; //数码管显示百位
63 DU = 1; //打开段选
64 DU = 0; //关闭段选
65
66 WE = 0; //关闭位选
67 P0 = T_COM[0]; //第一位数码管
68 WE = 1; //打开位选
69 WE = 0; //关闭位选
70 Delay_Ms(3);
71 //-------------------------------
72 DU = 0;
73 P0 = table[Value%100/10]|0x80; //显示十位
74 DU = 1;
75 DU = 0;
76
77 WE = 0;
78 P0 = T_COM[1]; //第二位数码管
79 WE = 1;
80 WE = 0;
81 Delay_Ms(3);
82 //-------------------------------
83 DU = 0;
84 P0 = table[Value%10]; //显示个位
85 DU = 1;
86 DU = 0;
87
88 WE = 0;
89 P0 = T_COM[2]; //第三位数码管
90 WE = 1;
91 WE = 0;
92 Delay_Ms(3);
93 }
94 /*单总线初始化时序*/
95 bit ds_init()
96 {
97 bit i;
98 DS = 1;
99 _nop_();
100 DS = 0;
101 Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
102 DS = 1; //释放总线
103 Delay_us(4); //延时37.95us 等待18B20发回存在信号
104 i = DS;
105 Delay_us(20); //141.95us
106 DS = 1;
107 _nop_();
108 return (i);
109 }
110 /*写一个字节*/
111 void write_byte(uchar dat)
112 {
113 uchar i;
114 for(i=0;i<8;i++)
115 {
116 DS = 0;
117 _nop_();//产生些时序
118 DS = dat & 0x01;
119 Delay_us(10);//76.95us
120 DS = 1; //释放总线准备下一次数据写入
121 _nop_();
122 dat >>= 1;
123 }
124 }
125
126 uchar read_byte()
127 {
128 uchar i, j, dat;
129 for(i=0;i<8;i++)
130 {
131 DS = 0;
132 _nop_();//产生读时序
133 DS = 1;
134 _nop_();//释放总线
135 j = DS;
136 Delay_us(10);//76.95us
137 DS = 1;
138 _nop_();
139 dat = (j<<7)|(dat>>1);
140 }
141 return (dat);
142 }
143 void main()
144 {
145 uint i;
146 uchar L, M;
147 /* ds_init();//初始化DS18B20
148 write_byte(0xcc);//发送跳跃ROM指令
149 write_byte(0x4e);//写暂存器指令
150 write_byte(0x7f);
151 write_byte(0xf7);
152 write_byte(0x1f);//配置工作在9位模式下
153 ds_init();//初始化DS18B20
154 write_byte(0xcc);//发送跳跃ROM指令
155 write_byte(0x48);*/
156 while(1)
157 {
158 ds_init();//初始化DS18B20
159 write_byte(0xcc);//发送跳跃ROM指令
160 write_byte(0x44);//发送温度转换指令
161 ds_init();//初始化DS18B20
162 write_byte(0xcc);//发送跳跃ROM指令
163 write_byte(0xbe);//读取DS18B20暂存器值
164 L = read_byte();
165 M = read_byte();
166 i = M;
167 i <<= 8;
168 i |= L;
169 i = i * 0.0625 * 10 + 0.5;
170 Display(i);
171 }
172 }
15_课红外通讯
1 /*NEC协议红外通信
2 单片机解码后通过串口以9600的比特率发送出去
3 */
4 #include <reg52.h>
5 /*====================================
6 自定义类型名
7 ====================================*/
8 typedef unsigned char INT8U;
9 typedef unsigned char uchar;
10
11 typedef unsigned int INT16U;
12 typedef unsigned int uint;
13
14 uchar IRtime; //储存检测红外高低电平持续时间
15 uchar IRcord[4]; //储存解码后的4个字节数据
16 uchar IRdata[33]; //包含起始码在内的33位数据
17 bit IRpro_ok; //解码后4个字节数据接收完成标志位
18 bit IRok; //33位数据接收完成标志
19
20 //初始化定时器0,外部中断0,串口
21 void init()
22 {
23 TMOD |= 0x02;//设置定时器0工作模式2,8位自动重装
24 TL0 = TH0 = 0;//初始化定时器0寄存器,定时器0溢出一次时间为256个机器周期
25 EA = 1;//开总中断
26 ET0 = 1;//开定时器0中断
27 TR0 = 1;//启动定时器0
28
29 IT0 = 1;//设置外部中断0跳变沿触发方式
30 EX0 = 1;//开外部中断0中断
31
32 TMOD |= 0x20;//设置定时器1工作模式2 ,8位自动重装
33 TL1 = TH1 = 0xfd;//比特率9600
34 SM1 = 1;//设置串口工作模式1,10位异步收发
35 TR1= 1; //启动定时器1
36 }
37
38 //定时器0中断,每中断一次需要256*1.085us = 277.76us
39 void time0() interrupt 1
40 {
41 IRtime++;//277.76us
42 }
43
44 //外部中断0 存入33次脉宽
45 void int0() interrupt 0
46 {
47 static uchar i;//静态变量用于存入33次数据计数
48 static bit startflag;//开始储存脉宽标志位
49 if(startflag)
50 {
51 /*判断引导码,如果是引导码则从起始码开始存*/
52 if((IRtime < 53) && (IRtime >= 32)) i = 0;
53 IRdata[i] = IRtime;//以TO溢出的次数来计算脉宽把这个时间存放在数组中
54 IRtime = 0;//计数清零
55 i++;//计数脉宽存入次数自加
56 if(i == 33) //i等于33那么就表示已经存入了33次脉宽
57 {
58 IRok = 1; //脉宽检查完成
59 i = 0; //把脉宽计数清零准备下次存入
60 }
61 }
62 else
63 {
64 IRtime = 0; //定时器0计数清零
65 startflag = 1;//开始处理标志位置1
66 }
67
68 }
69
70 //把提取的33次脉宽进行解码 NEC协议
71 void IRcordpro()
72 {
73 uchar i;//i是用于计数处理4个字节
74 uchar j;//j用于计数处理1个字节的8位数据
75 uchar k;//k用于计数处理33次脉宽
76 k = 1;//从第一位脉宽开始处理,丢掉起始码
77 for(i = 0; i < 4; i++)
78 {
79 for(j = 0; j < 8; j++)
80 {
81 //如果脉宽大于数据0标准的1125us那么就判定为数据1
82 if(IRdata[k] > 5) IRcord[i] |= 0x80;//写1
83 //只能右移7次,如果右移8次则会把第一位数据移出去
84 if(j < 7) IRcord[i] >>= 1;
85 k++; //处理下一次脉宽
86 }
87 }
88 IRpro_ok = 1;//解码完成
89 }
90
91 void main()
92 {
93 uchar i; //计数串口发送字节数
94 init();//初始化
95 while(1)
96 {
97 if(IRok)//判断33次脉宽是否提取完成
98 {
99 IRcordpro();//根据脉宽解码出4个字节的数据
100 IRok = 0;//清零脉宽检查完成标志位等待下一次脉宽检查
101 if(IRpro_ok)//判断解码是否完成
102 {
103 for(i = 0; i < 4; i++) //串口发送4个字节数据
104 {
105 SBUF = IRcord[i]; //发送数据
106 while(!TI); //等待发送完成标志
107 TI = 0; //清零发送完成标志位
108 }
109 IRpro_ok = 0;//清零解码标志位
110 }
111 }
112 }
113
114 }