SPI 数据接口使用
SPI接口是一种用于数据传输的接口,通常用于多设备之间的数据传输。对于STC8G系列单片机,SPI接口可以配置为主机模式或从机模式,并且支持全双工或半双工数据传输。一般情况下,SPI会使用主机模式的全双工数据传输方式。
1.SPI引脚
| SPI引脚 | 功能 | 备注 |
|---|---|---|
| SCK | 时钟信号 | P32 |
| MISO | 主入从出 | P33 |
| MOSI | 主出从入 | P54 |
| SS | 从设备选择 | P55 |
2.SPI(主机模式)初始化
c
// SPI初始化(主模式)
void SPI_Init(void) {
// 配置SPI引脚模式
P3M0 = (P3M0 & ~0x08) | 0x04;
P3M1 = (P3M1 & ~0x04) | 0x08;
P5M0 |= 0x30;
P5M1 &= ~0x30;
// SPI控制寄存器配置
SPCTL = 0xDC; // 二进制 1101 1100
/*
bit7: SPEN=1 使能SPI
bit6: SSIG=1 忽略SS引脚(使用GPIO控制片选)
bit5: CPOL=1 时钟空闲高电平
bit4: CPHA=1 数据在时钟第二个跳变沿采样
bit3: MSTR=1 主模式
bit2: DORD=0 MSB先传输
bit1-0: SPR=00 时钟=Fsys/4 (12MHz@48MHz主频)
*/
SPSTAT = 0xC0; // 清除传输完成标志
}3.SPI(主模式)发送数据
c
// SPI发送并接收1字节
unsigned char SPI_TransferByte(unsigned char dat) {
SPDAT = dat; // 写入发送数据
while (!(SPSTAT & 0x80)); // 等待SPIF标志置位
SPSTAT = 0x80; // 清除SPIF标志
return SPDAT; // 返回接收数据
}4.SPI(主模式)完整代码
c
#include <STC8G.h>
#include <intrins.h>
// 引脚定义 (8pin封装)
#define CS P55 // 片选引脚
#define SCK P32 // 时钟引脚
#define MOSI P54 // 主出从入
#define MISO P33 // 主入从出
#define LIS3DH_WHO_AM_I 0x0F
// SPI初始化(主模式)
void SPI_Init(void) {
// 配置SPI引脚模式
P3M0 = (P3M0 & ~0x08) | 0x04;
P3M1 = (P3M1 & ~0x04) | 0x08;
P5M0 |= 0x30;
P5M1 &= ~0x30;
// SPI控制寄存器配置
SPCTL = 0xDC; // 二进制 1101 1100
/*
bit7: SPEN=1 使能SPI
bit6: SSIG=1 忽略SS引脚(使用GPIO控制片选)
bit5: CPOL=1 时钟空闲高电平
bit4: CPHA=1 数据在时钟第二个跳变沿采样
bit3: MSTR=1 主模式
bit2: DORD=0 MSB先传输
bit1-0: SPR=00 时钟=Fsys/4 (12MHz@48MHz主频)
*/
SPSTAT = 0xC0; // 清除传输完成标志
}
void Uart1_Init(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xE0; //设置定时初始值
TH1 = 0xFE; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
}
void UartSendByte(unsigned char dat) {
SBUF = dat; // 发送当前数据
while(!(TI)); // 等待数据发送完成
TI = 0; // 清除发送完成标志
}
// SPI发送并接收1字节
unsigned char SPI_TransferByte(unsigned char dat) {
SPDAT = dat; // 写入发送数据
while (!(SPSTAT & 0x80)); // 等待SPIF标志置位
SPSTAT = 0x80; // 清除SPIF标志
return SPDAT; // 返回接收数据
}
void Delay1000ms(void) //@11.0592MHz
{
// 声明三个无符号字符型变量i、j、k
//在 unsigned char data i, j, k; 这种变量定义方式中,
//data 是 Keil C 编译器中用于指定变量存储类型的修饰符,
//用于告诉编译器该变量应存放在 内部 RAM 的低 128 字节(即 data 区域) 中。
unsigned char data i, j, k;
_nop_(); // 空操作,延时1个机器周期
_nop_(); // 空操作,延时1个机器周期
i = 43; // 将变量i赋值为43
j = 6; // 将变量j赋值为6
k = 203; // 将变量k赋值为203
do
{
do
{
while (--k); // 当k大于0时,循环执行k减1操作
} while (--j); // 当j大于0时,循环执行j减1操作
} while (--i); // 当i大于0时,循环执行i减1操作
}
// 主函数
void main() {
unsigned char rx;
// 系统时钟初始化(48MHz)
Uart1_Init();
SPI_Init(); // 初始化SPI
CS = 1; // 初始片选高电平
while(1) {
CS = 0; // 片选使能
SPI_TransferByte(LIS3DH_WHO_AM_I | 0x80); // 发送并接收
rx = SPI_TransferByte(0x00);
UartSendByte(rx); // 发送接收到的数据到串口
CS = 1; // 片选禁止
// 此处可添加数据处理逻辑
Delay1000ms();
}
}