-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathSPI_Analog.c
More file actions
203 lines (195 loc) · 5.47 KB
/
SPI_Analog.c
File metadata and controls
203 lines (195 loc) · 5.47 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*//////////////////////////GPL开源许可证////////////////////////////////////////////////
Copyright (C) <2015> <Xianglong He>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
文件名:SPI_Analog.c
作者:何相龙
邮箱:qwgg9654@gmail.com
admin@hxlxz.com
功能描述:SPI通信的IO口模拟实现
备注:如使用的单片机自带SPI通信相关硬件功能(如STC15W系列),推荐直接使用其硬件模块。
使用该模块,请在config.h中定义SPI_CPOL_SET常量为SPI通信的CPOL模式。
如 #define SPI_CPOL_SET 1
使用该模块,请在config.h中定义SPI_CPOL_SET常量为SPI通信的CPHA模式。
建议:如果要用SPI做多机通信,建议设置CPHA为1,这样可以提高本程序的稳定性。
如 #define SPI_CPHA_SET 1
使用该模块,请在config.h中定义SPI_CS_SET常量为SPI总线的CS使能接口。
如 #define SPI_CS_SET P0^0
使用该模块,请在config.h中定义SPI_SCLK_SET常量为SPI总线的SCLK时钟信号接口。
如 #define SPI_SCLK_SET P0^1
使用该模块,请在config.h中定义SPI_MOSI_SET常量为SPI总线的MOSI信号接口。
如 #define SPI_MOSI_SET P0^2
使用该模块,请在config.h中定义SPI_MISO_SET常量为SPI总线的MISO信号接口。
如 #define SPI_MISO_SET P0^3
*////////////////////////////////////////////////////////////////////////////////////////
#include<reg52.h>
#include<SPI_Analog.h>
#define Dealy(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //SPI通信的小延时
#define CPOL SPI_CPOL_SET
#define CPHA SPI_CPHA_SET
//设置SPI通信的参数
sbit CS = SPI_CS_SET; //定义SPI通信的四个IO口
sbit SCLK = SPI_SCLK_SET;
sbit MOSI = SPI_MOSI_SET;
sbit MISO = SPI_MISO_SET;
/*///////////////////////////////////////////////////////////////////////////////////
*函数名:SPI_Master_Init
*函数功能:SPI初始化(仅主模式使用)
*参数列表:
* 无
*返回值:无
*版本:1.0
*作者:何相龙
*日期:2015年1月8日
*////////////////////////////////////////////////////////////////////////////////////
void SPI_Master_Init()
{
SCLK = CPOL;
CS = 1;
}
/*///////////////////////////////////////////////////////////////////////////////////
*函数名:SPI_Write
*函数功能:SPI从模式:发送一位unsigned char 型的数据
*参数列表:
* dat
* 参数类型:unsigned char型数据
* 参数描述:要发送的数据
*返回值:无
*版本:1.0
*作者:何相龙
*日期:2015年1月8日
*////////////////////////////////////////////////////////////////////////////////////
void SPI_Write(unsigned char dat)
{
unsigned char mask;
CS = 0;
#if CPHA
for(mask = 0x80; mask != 0; mask >>= 1)
{
SCLK = ~ SCLK;
MOSI = dat & mask;
Dealy();
SCLK = ~ SCLK;
Dealy();
}
#else
for(mask = 0x80; mask != 0;)
{
MOSI = dat&mask;
SCLK = ~ SCLK;
Dealy();
mask >>= 1;
SCLK = ~ SCLK;
Dealy();
}
#endif
CS = 1;
}
/*///////////////////////////////////////////////////////////////////////////////////
*函数名:SPI_Read
*函数功能:SPI主模式:读取一位unsigned char 型的数据
*参数列表:
* 无
*返回值:一个unsigned char型数据,读取到的数据。
*版本:1.0
*作者:何相龙
*日期:2015年1月8日
*////////////////////////////////////////////////////////////////////////////////////
unsigned char SPI_Read()
{
unsigned char dat = 0,mask = 0x80;
CS = 0;
#if CPHA
for(;mask != 0;mask >>= 1)
{
SCLK = ~ SCLK;
Dealy();
if(MISO)dat |= mask;
SCLK = ~ SCLK;
Dealy();
}
#else
for(;mask != 0;mask >>= 1)
{
Dealy();
if(MISO)dat |= mask;
SCLK = ~ SCLK;
Dealy();
SCLK = ~ SCLK;
Dealy();
}
#endif
CS = 1;
return dat;
}
/*///////////////////////////////////////////////////////////////////////////////////
*函数名:SPI_Slave_Send
*函数功能:SPI从模式:回应一位unsigned char 型的数据
*参数列表:
* dat
* 参数类型:unsigned char型数据
* 参数描述:要回复的数据
*返回值:无
*版本:1.0
*作者:何相龙
*日期:2015年1月8日
*////////////////////////////////////////////////////////////////////////////////////
void SPI_Slave_Send(unsigned char dat)
{
unsigned char mask=0x80;
while(CS);
#if CPHA
for( ; mask != 0; mask >>= 1)
{
while(SCLK == CPOL);
MISO = dat & mask;
while(SCLK != CPOL);
}
#else
for( ; mask != 0; mask >>= 1)
{
MISO = dat & mask;
while(SCLK == CPOL);
while(SCLK != CPOL);
}
#endif
}
/*///////////////////////////////////////////////////////////////////////////////////
*函数名:SPI_Slave_Resive
*函数功能:SPI从模式:接收一位unsigned char 型的数据
*参数列表:
* 无
*返回值:一个unsigned char型数据,接收到的数据。
*版本:1.0
*作者:何相龙
*日期:2015年1月8日
*////////////////////////////////////////////////////////////////////////////////////
unsigned char SPI_Slave_Resive()
{
unsigned char mask = 0x80,dat = 0;
while(CS); //等待SPI使能信号
#if CPHA
for(;mask != 0;mask >>= 1)
{
while(SCLK == CPOL);
while(SCLK != CPOL);
if(MOSI)dat |= mask;
}
#else
for(;mask != 0;mask >>= 1)
{
while(SCLK == CPOL);
if(MOSI)dat |= mask;
while(SCLK != CPOL);
}
#endif
return dat;
}