硬件SPI(中断方式)
以STC15W408AS单片机为例
一、硬件接线
STC15系列单片机SPI使用注意事项(一)
二、程序编写
1、和SPI中断相关的寄存器
① IE寄存器
② IE2寄存器
③ IP2寄存器
2、自定义寄存器,数据类型重定义
sfr P_SW1
= 0xA2;
sfr SPSTAT
= 0xCD;
sfr SPCTL
= 0xCE;
sfr SPDAT
= 0xCF;
sfr IE2
= 0xAF;
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
typedef bit BOOL
;
#define NULL 0
#define FALSE 0
#define TRUE 1
3、寄存器相关位宏定义, CS引脚定义
#define SPI_S0 0x04
#define SPI_S1 0x08
#define SPIF 0x80
#define WCOL 0x40
#define SSIG 0x80
#define SPEN 0x40
#define DORD 0x20
#define MSTR 0x10
#define CPOL 0x08
#define CPHA 0x04
#define SPDHH 0x00
#define SPDH 0x01
#define SPDL 0x02
#define SPDLL 0x03
#define ESPI 0x02
sbit SS_1
= P1
^2;
BOOL g_fSpiBusy
;
4、SPI初始化代码
void InitSPI_1(void)
{
uchar temp
;
temp
= P_SW1
;
temp
&= ~(SPI_S0
| SPI_S1
);
P_SW1
= temp
;
SPDAT
= 0;
SPSTAT
= SPIF
| WCOL
;
SPCTL
= SPEN
| MSTR
| SSIG
| SPDLL
;
}
5、SPI中断服务程序
void spi_isr() interrupt
9 using
1
{
SPSTAT
= SPIF
| WCOL
;
g_fSpiBusy
= FALSE
;
}
6、SPI数据交换代码
uchar
SPIShift(uchar dat
)
{
g_fSpiBusy
= TRUE
;
SPDAT
= dat
;
while(g_fSpiBusy
);
return SPDAT
;
}
7、GD25Q80BSIG读写例程
#define NOP 0xFF
#define Write_Enable 0x06
#define Write_Disable 0x04
#define Read_Status_Register 0x05
#define Read_Status_Register_1 0x35
#define Read_Data 0x03
#define Page_Program 0x02
#define Chip_Erase_1 0xC7
#define Chip_Erase_2 0x60
#define Read_Identification 0x9F
sbit WP
= P1
^6;
void Write_Enable_Cmd(void)
{
SS_1
= 0;
SPIShift(Write_Enable
);
SS_1
= 1;
}
void Write_Disable_Cmd(void)
{
SS_1
= 0;
SPIShift(Write_Disable
);
SS_1
= 1;
}
uchar
Read_Status_Register_Sta(void)
{
uchar sta
;
SS_1
= 0;
SPIShift(Read_Status_Register
);
sta
= SPIShift(NOP
);
SS_1
= 1;
return sta
;
}
void Read_Data_Cmd(uchar ad1
, uchar ad2
, uchar ad3
, uchar
*dat
, uint len
)
{
uchar i
, cmd
[4];
cmd
[0] = Read_Data
;
cmd
[1] = ad1
;
cmd
[2] = ad2
;
cmd
[3] = ad3
;
SS_1
= 0;
for(i
= 0; i
< 4; i
++){
SPIShift(cmd
[i
]);
}
for(i
= 0; i
< len
; i
++){
*dat
++ = SPIShift(NOP
);
}
SS_1
= 1;
}
void Page_Program_Cmd(uchar ad1
, uchar ad2
, uchar ad3
, uchar
*dat
, uint len
)
{
uchar i
, cmd
[4];
uint count
= 0, temp
= 0;
long address
= 0;
address
= (ad1
<< 16) | (ad2
<< 8) | ad3
;
cmd
[0] = Page_Program
;
cmd
[1] = ad1
;
cmd
[2] = ad2
;
cmd
[3] = ad3
;
temp
= 256 - ad3
;
Write_Enable_Cmd();
SS_1
= 0;
for(i
= 0; i
< 4; i
++){
SPIShift(cmd
[i
]);
}
for(i
= 0; i
< temp
; i
++){
SPIShift(*dat
++);
}
SS_1
= 1;
while(Read_Status_Register_Sta() & 0x01);
if(len
> temp
){
cmd
[0] = Page_Program
;
cmd
[1] = ad1
;
cmd
[2] = ad2
+ 1;
cmd
[3] = 0;
temp
= len
- temp
;
Write_Enable_Cmd();
SS_1
= 0;
for(i
= 0; i
< 4; i
++){
SPIShift(cmd
[i
]);
}
for(i
= 0; i
< temp
; i
++){
SPIShift(*dat
++);
}
SS_1
= 1;
while(Read_Status_Register_Sta() & 0x01);
}
}
void Chip_Erase_1_Cmd(void)
{
Write_Enable_Cmd();
SS_1
= 0;
SPIShift(Chip_Erase_2
);
SS_1
= 1;
while(Read_Status_Register_Sta() & 0x01);
}
void Read_Identification_Sta(uchar
*rdid
)
{
uchar i
;
SS_1
= 0;
SPIShift(Read_Identification
);
for(i
= 0; i
< 3; i
++){
*rdid
++ = SPIShift(NOP
);
}
SS_1
= 1;
}
void HexToAscii(uchar
*pHex
, uchar
*pAscii
, uchar nLen
)
{
uchar Nibble
[2];
uint i
,j
;
for (i
= 0; i
< nLen
; i
++){
Nibble
[0] = (pHex
[i
] & 0xF0) >> 4;
Nibble
[1] = pHex
[i
] & 0x0F;
for (j
= 0; j
< 2; j
++){
if (Nibble
[j
] < 10){
Nibble
[j
] += 0x30;
}
else{
if (Nibble
[j
] < 16)
Nibble
[j
] = Nibble
[j
] - 10 + 'A';
}
*pAscii
++ = Nibble
[j
];
}
}
*pAscii
++ = '\0';
}
void main(void)
{
uchar sta
, dis
[2], rdid
[3];
uchar write
[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11}, read
[10] = {0x00};
uchar play
[20] = {0x00};
Init_Uart();
InitSPI_1();
IE2
|= ESPI
;
EA
= 1;
g_fSpiBusy
= FALSE
;
Read_Identification_Sta(rdid
);
Read_Identification_Sta(rdid
);
Read_Identification_Sta(rdid
);
HexToAscii(&rdid
[0], dis
, 1);
SendString("Manufacturer ID: 0x");
SendString(dis
);
SendString("\r\n");
HexToAscii(&rdid
[1], dis
, 1);
SendString("Memory Type: 0x");
SendString(dis
);
SendString("\r\n");
HexToAscii(&rdid
[2], dis
, 1);
SendString("Capacity: 0x");
SendString(dis
);
SendString("\r\n");
sta
= Read_Status_Register_Sta();
HexToAscii(&sta
, dis
, 1);
SendString("GD25Q80BSIG Status Register: 0x");
SendString(dis
);
SendString("\r\n");
Chip_Erase_1_Cmd();
Page_Program_Cmd(0x00, 0x01, 0xFA, write
, 10);
Read_Data_Cmd(0x00, 0x01, 0xFA, read
, 10);
HexToAscii(read
, play
, 10);
SendString("Read Address 0x0001FA: ");
SendString(play
);
SendString("\r\n");
while(1);
}
8、串口代码
STC15系列单片机SPI使用注意事项(一)
转载请注明原文地址:https://blackberry.8miu.com/read-1416.html