单片机实验程序代码

实验一 电子琴模拟实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#define KeyPort P3
/*------------------------------------------------
全局变量
------------------------------------------------*/

unsigned char High,Low; //定时器预装值的高8位和低8位

sbit SPK=P1^2; //定义喇叭接口

unsigned char code freq[][2]={
0xD8,0xF7,//00440HZ 1
0xBD,0xF8,//00494HZ 2
0x87,0xF9,//00554HZ 3
0xE4,0xF9,//00587HZ 4
0x90,0xFA,//00659HZ 5
0x29,0xFB,//00740HZ 6
0xB1,0xFB,//00831HZ 7
0xEF,0xFB,//00880HZ `1
};


/*------------------------------------------------
函数声明
------------------------------------------------*/
void Init_Timer0(void);//定时器初始化


/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
unsigned char num;

Init_Timer0(); //初始化定时器0,主要用于数码管动态扫描
SPK=0; //在未按键时,喇叭低电平,防止长期高电平损坏喇叭
while (1) //主循环
{
switch(KeyPort)
{
case 0xfe:num= 1;break;
case 0xfd:num= 2;break;
case 0xfb:num= 3;break;
case 0xf7:num= 4;break;
case 0xef:num= 5;break;
case 0xdf:num= 6;break;
case 0xbf:num= 7;break;
case 0x7f:num= 8;break;
default:num= 0;break;
}


if(num==0)
{
TR0=0;
SPK=0; //在未按键时,喇叭低电平,防止长期高电平损坏喇叭
}
else
{
High=freq[num-1][1];
Low =freq[num-1][0];
TR0=1;
}
}
}


/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA=1; //总中断打开
ET0=1; //定时器中断打开
//TR0=1; //定时器开关打开
}

/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=High;
TL0=Low;

SPK=!SPK;
}

实验二 LCD显示实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*************************************************
**名称:LCD显示实验
**功能:在液晶显示模块上显示zhejiang Qiu Shi,jiaoxueyiqi.
**时间:2017.3.13
*************************************************/
#include<reg52.h>
#define uchar unsigned char
sbit lcdEN=P1^0; //使能信号
sbit lcdRW=P1^1; //读、写选择
sbit lcdRS=P1^2; //数据、命令选择
uchar code tab[]="Zhejiang Qiu Shi";
uchar code tabl[]="Jiao Xue Yi Qi";
void delayms(uchar t);
void write_dat(uchar dat);
void write_com(uchar com);
void init(void);
void main(void)
{
uchar i;
init();
for(i=0;i<16;i++)
write_dat(tab[i]);
write_com(0x80+0x40);
for(i=0;i<14;i++)
write_dat(tabl[i]);
while(1);
}
/*************************************************
**名 称:初始化子函数
**入口参数:无
**返 回 值:无
*************************************************/
void init(void)
{
lcdRW=0; //一直是写命令、写数据
write_com(0x38); //显示模式设置
delayms(5);
write_com(0x0c); //显示开关、光标的设置
delayms(5);
write_com(0x06); //地址指针设置
delayms(5);
write_com(0x01); //显示清屏
}
/*************************************************
**名 称:写命令子函数
**入口参数:状态字 (相关时序)
**返 回 值:无
*************************************************/
void write_com(uchar com)
{
lcdEN=0;
lcdRS=1;
delayms(10);
lcdRS=0;
P0=com;
delayms(5);
lcdEN=1;
delayms(5);
lcdEN=0;
}
/*************************************************
**名 称:写数据子函数
**入口参数:显示的字符 (相关时序)
**返 回 值:无
*************************************************/
void write_dat(uchar dat)
{
lcdEN=0;
lcdRS=0;
delayms(10);
lcdRS=1;
P0=dat;
delayms(5);
lcdEN=1;
delayms(5);
lcdEN=0;
}
void delayms(uchar t)
{
uchar x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验三 IIC总线24C02读写实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/********************************
**名称:IIC 总线24C01读写实验
**功能:把流水灯的8个数据存储到24C01中
**时间:2017.3.13
*********************************/
#include<reg52.h>

#define uchar unsigned char

sbit SCL=P1^4;
sbit SDA=P1^5;

uchar code tab[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void init(void);
void start(void);
void stop(void);
void respons(void);
void writebyte(uchar date);
uchar readbyte(void);
void writeadd(uchar address,uchar info);
uchar readadd(uchar address);
void delay(void);
void delayms(uchar);

void main(void)
{
uchar i;
init();
for(i=0;i<8;i++)
{
writeadd(i+1,tab[i]);
delayms(100);
}
while(1)
{
for(i=0;i<8;i++)
{
P0=readadd(i+1);
delayms(250); delayms(250); delayms(250);
}
}

}

void init(void)
{
SDA=1; //总线初始化,此时任何从器件都不占用总线
delay();
SCL=1;
delay();
}
void start(void)
{
SDA=1;
delay();
SCL=1;
delay();
SDA=0;
delay();
}
void stop(void)
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
}
void respons(void)
{
uchar i;
SCL=1;
delay();
while((SDA==1)&&(i<250)) i++;
SCL=0;
delay();
}
void writebyte(uchar date) // 写一个字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delay();
SDA=CY;
delay();
SCL=1;
delay();
}
SCL=0;
delay();
SDA=1; //释放总线 ,以便respons应答
delay();
}
uchar readbyte(void)
{
uchar i,result;
SCL=0;
delay();
SDA=1;
delay();
for(i=0;i<8;i++)
{
SCL=1;
delay();
result=(result<<1)|SDA;
SCL=0;
delay();
}
return result;
}
void writeadd(uchar address,uchar info)
{
start();
writebyte(0xa0);
respons();
writebyte(address);
respons();
writebyte(info);
respons();
stop();
}
uchar readadd(uchar address)
{
uchar date;
start();
writebyte(0xa0);
respons();
writebyte(address);
respons();
start();
writebyte(0xa1);
respons();
date=readbyte();
stop();
return date;

}
void delay(void)
{
;;
}
void delayms(uchar t)
{
uchar i,j;
for(i=t;i>0;i--)
for(j=110;j>0;j--);
}

实验四 单片机与PC机的RS232串行通信实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/******************************************************************************
**名称:单片机与PC机的RS232串行通信实验
**功能:用STC_ISP_V6.85.exe的串口助手 发送数据,然后再数码管上会显示发送的数0——f
**时间:2017.3.13
********************************************************************************/
#include<reg52.h>

unsigned char temp;

unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
//共阳数码管段码0-9,a-f,灰
void init(void);
void display(unsigned char dat);
void delayms(unsigned char t);

void main()
{
init();
while(1)
{
display(temp);
}
}

void init(void)
{
TMOD=0x20; //T1工作模式2
TH1=0xfd; //波特率9600
TL1=0xfd;
SCON=0x40; //串口模式1
PCON=0x00; //波特率不倍增
REN=1;
EA=1;
ES=1;
ET1=0;
TR1=1;
}
void ser() interrupt 4
{
//if(RI==0) return;
ES=0;
RI=0;
temp=SBUF; //接收
ES=1;
}
void display(unsigned char dat)
{
P2=0x01;
P0=tab[dat];
delayms(5);
P0=0xff;
}
void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验五 DAC0832数模转换实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/********************************************************
**名称:DAC0832数模转换实验
**功能:发光二极管有灭逐渐到亮,再由亮逐渐到灭.
**时间:2017.3.14
*********************************************************/
#include<reg52.h>
#include<intrins.h>
sbit CS=P2^7;
sbit WR1=P3^6;

void delayms(unsigned char t);
void main(void)
{
unsigned char i;
CS=0;
WR1=0;
while(1)
{
for(i=0;i<50;i++)
{
WR1=1;
P0=i;
_nop_();
WR1=0;
delayms(250); //为了使发光二极管具有逐渐亮起来的感觉
delayms(250); //就延时长点
delayms(250);
}
WR1=0;
for(i=50;i>0;i--)
{
WR1=1;
P0=i;
_nop_();
WR1=0;
delayms(250);
delayms(250);
delayms(250);
}
}
}

void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验六 动态扫描显示实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/********************************
**名称:动态扫描显示实验
**功能:在共阳数码管上动态显示“01234567”
**时间:2017.3.10
*********************************/
#include<reg52.h>
#include<intrins.h> //内部函数 头文件
//将第一个参数循环左(右)移n(第二个参数)位
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
//共阳数码管段码0-9,a-f,灰
unsigned char dat[]={0,1,2,3,4,5,6,7};//需要显示的数据
void display(unsigned char *pl,tem);
void delayms(unsigned char t);
void main(void)
{
while(1)
{
display(dat,8);
}
}

/********************************************************
**名称:显示子函数
**功能:动态扫描P2口做为位选,P0口送段码
**输入:pl指向要显示数据的地址,tem要显示的位数
**返回:无
*******************************************************/
void display(unsigned char *pl,tem)
{
unsigned char i,dt;
P2=0x01;
dt=0x01;
for(i=0;i<tem;i++)
{
P0=tab[*(pl+i)];
delayms(10); //延时太长,会出现闪烁
dt=_crol_ (dt,1);
P2=dt;
P0=0xff;
}
}
void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验七 串行数转换并行数实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*************************************************
**名称:串行数转换并行数实验
**功能:串行输入并行输出,就是用串口扩展8个IO口
**时间:2017.3.13
*************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char

sbit CLE=P1^0; //164的清零位

void delayms(uchar t);
void main(void)
{
uchar temp;
temp=0x01;
ES=0; //串口工作在方式0,扩展并行IO口,不需要进入中断
SCON=0x00; //设置串行口控制寄存器
while(1)
{
CLE=1;
SBUF=temp;
while(!TI); //发送完8位数据中断标志位置1,由软件清0
TI=0;
delayms(250);
delayms(250);
temp=_cror_(temp,1);
}
}

void delayms(uchar t)
{
uchar x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验八 并行口转换串行口实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*************************************************
**名称:并行口转换串行口实验
**功能:利用165并行输入,串口输出
**时间:2017.3.14
*************************************************/
#include<reg52.h>

sbit sh=P1^0;
void init();
void delayms(unsigned char t);
void main()
{
init();
while(1)
{
sh=0; //置数(load), 读入并行输入口的8 位数据
sh=1; //移位(shift),并口输入被封锁,串行转换开始
while(!RI);
RI=0;
P2=SBUF;
delayms(0);
}
}

void init()
{
SCON=0x10; //设串口方式0,允许接受
ES=0; //不进入中断
}
void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验九 8255输入、输出实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*********************************************
**名称:8255输入、输出实验
**编者:裴秀辉
**功能:拨动数据开关为1,相应的发光二极管会亮
目的是用8255扩展IO输入输出口,用简单
的数据开关和发光二极管来感观的确认。
**时间:2010.11.11
********************************************/
#include<reg52.h>
#include<absacc.h> //绝对地址访问 头文件
//如果要访问外部数据存储器区的0x1000处的内容,
//可使用val=XBYTE[0x1000];

#define PA_add XBYTE[0x7cff] //宏定义PA_add就相当于
#define PB_add XBYTE[0x7dff] //绝对地址中的内容
#define PC_add XBYTE[0x7eff]
#define CON_add XBYTE[0x7fff] //8255中PA是输出PB为输入
//工作方式是0。
void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
void main(void)
{
while(1)
{
CON_add=0x82;
PA_add=PB_add;
delayms(50); //貌似二极管能增加些亮度
}
}

实验十 ADC0809模数转换实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/********************************************************
**名称:ADC0809模数转换实验
**功能:0809采集电压并在数码管上精确的显示
**时间:2017.3.15
*********************************************************/
#include<reg52.h>
#include<intrins.h>

/***********ad0809与单片机的接口定义**********************/
sbit OE=P3^5;
sbit EOC=P3^6;
sbit START=P3^4;
sbit CLK=P3^3;
sbit P30=P3^0;

unsigned int key;
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
unsigned char temdat[]={0,0,0}; //低-高

void init();
void display(unsigned char *pl);
void delayms(unsigned char t);

void main(void)
{

init();

while(1)
{
P1=0xf8; // 选择IN0通道输入
START=0;
START=1;
START=0; //启动AD转换
while(EOC==0) display(temdat); //等待转换结束,如果这里用空语句,显示会很闪
OE=1; //所以等待的时候,就让它显示转换前的值
key=P1;
OE=0; //OE是将锁存器中的数据送出
key=1.96*key; //将AD转换回来的数(0—255) 化为相应的电压y=(5/255)*x
temdat[2]=key/100; // x∈(0,255) y∈(0,5)
temdat[1]=key/10%10;
temdat[0]=key%10;
display(temdat);
}
}

void init()
{
TMOD=0x02;
TH0=0x14;
TL0=0x14;
TR0=1;
ET0=1;
EA=1;
}

void time0() interrupt 1
{
CLK=~CLK;
}

/********************************************************
**名称:显示子函数
**功能:动态扫描P2口做为位选,P0口送段码
**输入:pl指向要显示数据的地址,最后3位
**返回:无
*******************************************************/
void display(unsigned char *pl)
{
P2=0x04;
P0=tab[*pl]; //低
delayms(3);
P0=0xff;

P2=0x02;
P0=tab[*(pl+1)]; //中
delayms(3);
P0=0xff;

P2=0x01;
P0=tab[*(pl+2)]&0x7f; //高 //高位数码管总是带小数,因为电压的范围:0—5V
delayms(3);
P0=0xff;
}

void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验十一 串行AD(ADC0831)转换实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 /********************************************************
**名称:ADC0831模数转换实验
**功能:0831采集电压并在数码管上精确的显示
**时间:2017.3.15
*********************************************************/
#include<reg52.h>
#include<intrins.h>

/***********ad0832与单片机的接口定义**********************/
sbit CS =P1^0;
sbit CLK=P1^1;
sbit OUT=P1^2;

unsigned int key;
unsigned char code tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
unsigned char temdat[]={0,0,0}; //低-高

unsigned char adc0832(void);
void display(unsigned char *pl);
void delayms(unsigned char t);
void main(void)
{
unsigned int i,tep;
while(1)
{
tep=1.96*adc0832();
key=key+tep;
i++;
if(i==30) //平均值虑波,去除因每次采样值不同而跳动
{
key=key/30;
temdat[2]=key/100;
temdat[1]=key/10%10;
temdat[0]=key%10;
// display(temdat);
i=0;
key=0;
}
display(temdat);
}
}
/*********************************************
**函数描述:AD采样函数
**写入参数:无
**返回参数:电压0-5V对应的8位二进制数即0—255
************************************************/
unsigned char adc0832(void)
{
unsigned char i,l_key;
OUT=1;
CS=0;
_nop_();_nop_();
CLK=0;
_nop_();_nop_();
CLK=1;
_nop_();_nop_();
CLK=0;
_nop_();_nop_();
CLK=1;
_nop_();_nop_();
CLK=0;
_nop_();_nop_(); //ad0831是同步型模数转换器,根据时序写代码
for(i=0;i<8;i++)
{
l_key<<=1;
if(OUT)
l_key++;
CLK=1;
_nop_();_nop_();
CLK=0;
_nop_();_nop_(); //两个时钟下降延后就输出第一个数据,是一个同步串行通信协议
}
CS=1;
return l_key;
}
/********************************************************
**名称:显示子函数
**功能:动态扫描P2口做为位选,P0口送段码
**输入:pl指向要显示数据的地址,最后3位
**返回:无
*******************************************************/
void display(unsigned char *pl)
{
P2=0x04;
P0=tab[*pl]; //低
delayms(3);
P0=0xff;

P2=0x02;
P0=tab[*(pl+1)]; //中
delayms(3);
P0=0xff;

P2=0x01;
P0=tab[*(pl+2)]&0x7f; //高 //高位数码管总是带小数,因为电压的范围:0—5V
delayms(3);
P0=0xff;
}

void delayms(unsigned char t)
{
unsigned char x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}

实验十二 DS18B20温度采集实验(lcd1602)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*-----------------------------------------*/
#include<REG52.H>
#include"LCD1602_8.H"
#include"DS18B20_A.H"




/*-----------------------------------------*/
void main(void)
{
lcd_init();
lcd_pos(0,0);
prints("DS18B20-ZJQS");
lcd_pos(0,1);
prints("T:");
while(1)
{
Temp_To_String();
lcd_pos(7,1);
prints(TempBuffer);
delay(244,7,29);
}
}

实验十三 红外发射与接收

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/***************************************************************************
标题: 红外发射实验,模拟NEC红外线编码波形
效果: 运行程序,按独立按键1,将发射一组4字节数据,可由另外一块板子写入例21接收数据,
如果你实验处有NEC制的遥控电视,可以先使用接收程序,获得遥控地址码和控制码,
然后使用此程序进行发射相应地址码和控制码控制电视。
时间:2017.4.24
******************************************************************************/
#include "reg51.h"
#include <intrins.h>
/********IO引脚定义***********************************************************/
sbit bhwx=P3^7; //红外发射引脚

/********数据定义*************************************************************/
unsigned char l_tmp[4]={0x11,0x22,0x33,0x44}; //发送一组数据,四个字节
bit bzt=0; //定时器1用此变量判断是启动定时器0还是关闭定时器0
bit bzt1=1; //判断是否已执行了中断

sbit SW1=P0^4; //四个独立按键定义
sbit SW2=P0^5;
sbit SW3=P0^6;
sbit SW4=P0^7;
/********函数声明*************************************************************/


/***********主函数开始********************************************************/
void main()
{
unsigned char i,ia,tmp;
EA=1; //开总中断
TMOD=0x12; //设定时器0和定时器1为工作方式1

// TH0=255-(52/256); //定时器0初始,发生38K频率
// TL0=255-(52%256);
TH0=244; //重设初值
TL0=244;
ET0=1; //开定时器0 中断
ET1=1; //开定时器1 中断


while(1){ //循环
if(SW1==0){ //1键按下,发射一组数据,四个字节,模仿NEC制编码进行发射
//请先看下NEC制波形再来理解以下程序就容易些,
//原理是用定时器0来发送38K载波频率,由定时器1来控制发射时间

TR0=1;
bzt=0; //定时器1用此变量判断是启动定时器0还是关闭定时器0
TH1=(65536-9000)/256;
TL1=(65536-9000)%256;
TR1=1; //控制发射9MS,引导码
while(bzt1); //判断是否已执行了中断
bzt1=1;

bzt=1;
TH1=(65536-4500)/256;
TL1=(65536-4500)%256;
TR1=1; //控制4.5MS。引导码
while(bzt1);
bzt1=1;
for(i=0;i<4;i++){
tmp=l_tmp[i];
for(ia=0;ia<8;ia++){
bzt=0;
TH1=(65536-560)/256;
TL1=(65536-560)%256;
TR1=1; //控制0.56MS
while(bzt1);
bzt1=1;

bzt=1;
if(tmp&0x01){ //由数据来判断发射1.69MS还是0.56MS
TH1=(65536-1690)/256;
TL1=(65536-1690)%256;
}
else{
TH1=(65536-560)/256;
TL1=(65536-560)%256;
}
TR1=1;
while(bzt1);
bzt1=1;

tmp>>=1;
}
}
bzt=0;
TH1=(65536-60000)/256;
TL1=(65536-60000)%256;
TR1=1; //结束正常控制在180MS,这里我们使用60MS结束
while(bzt1);
bzt1=1;

bhwx=1; //复位发射引脚
}
//if(SW2==0) //2键按下
// ;
//if(SW3==0) //3键接下
// ;
//if(SW4==0) //4键接下
// ;
}
}

/**********定时器0入口函数**************************************************/
void time0(void) interrupt 1 //用来产生载波频率
{
// TH0=(65536-1)/256; //重设初值
// TL0=(65536-1)%256;

bhwx=!bhwx;
}

/**********定时器1入口函数**************************************************/
void time1(void) interrupt 3
{
TR0=0;
TF0=0; //必免不必要的中断

TR1=0;
if(bzt){ //判断是启动定时器0还是关闭定时器0
// TH0=(65535-52)/256; //重设初值
// TL0=(65536-52)%256;
TH0=244; //重设初值
TL0=244;

TR0=1;
}
else{
TR0=0;
bhwx=1;
}
bzt1=0; //已执行完中断
}

实验十四 PCF8563时钟日历实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/********************************************主程序************************************************************************/
#include"reg51.h"
#include"1602.h"
#include"PCF856311.h"

/**调试的过程中发现,读数据之后我们要释放总线,不然只能正确读取第一个数据,就是其他的就会出现读取的数据错位*/
/*发送数据之后,时钟要拉低,便于ask请求的读取。*/
/*能写入时间,也能读取时间,就是时钟不走动,控制状态寄存器1也就是0x00设置成0x00就可以了,是一个时钟启动指令*/
/*读出时钟数值后要将不用的为屏蔽掉,方能读出正确的时间*/

unsigned char BCD_CHAR(unsigned char p)//将BCD码转换成十进制数
{ unsigned char k;
k=p-(p>>4)*6;
return k;
}

void main(void)
{unsigned char hh[7];
unsigned char day[5]={'d','a','t','e','0'};
unsigned char time[5]={'t','i','m','e','0'};
init();
setup();
clear();
while(1)
{
get_charbuff_time(Second_register,7,hh); //读取时间和日期
xianshi_zu(0,0,day);
desplay_wordchar(8,0,BCD_CHAR(hh[3]&0x3f));//显示日
desplay_char(10,0,'/');
desplay_wordchar(11,0,BCD_CHAR(hh[5]&0x1f)); //显示月,并将月不用的位屏蔽掉
desplay_char(13,0,'/');
desplay_wordchar(14,0,BCD_CHAR(hh[6]));//显示年,

xianshi_zu(0,1,time); //换行显示time
desplay_wordchar(8,1,BCD_CHAR(hh[2]&0x3f));//显示时,并将时不用的位屏蔽掉
desplay_char(10,1,':');
desplay_wordchar(11,1,BCD_CHAR(hh[1]&0x7f));//显示分,并将分不用的位屏蔽掉
desplay_char(13,1,':');
desplay_wordchar(14,1,BCD_CHAR(hh[0]&0x7f));//显示秒。并将秒不用的位屏蔽掉

}
}

实验十五 串行DA(TLC5615)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<reg52.h>

sbit CS =P1^0;
sbit SCK=P1^1;
sbit DIN=P1^2;

void TLC5615(unsigned int dat)
{
unsigned char i;
CS=1;
SCK=0;
DIN=0;
CS=0;
dat=dat<<6;
for(i=0;i<12;i++)
{
DIN=dat&0x8000;
SCK=1;
dat=dat<<1;
SCK=0;
}
CS=1;
}

void main(void)
{
unsigned int V_dat=0;
unsigned char i;
while(1)
{
if(V_dat<0x201)
V_dat+=1;
else
V_dat=0;
TLC5615(V_dat);
i=100;
while(i--);
}
}