头文件
1 #ifndef SOFTSPI_H_
2 #define SOFTSPI_H_
3 #include "Com.h" //包含延时等函数
4 #define SPI_PORT PORTB //端口号
5 #define SPI_DDR DDRB //输入输出控制
6 #define SPI_PIN PINB //逻辑电平读取
7
8 #define CS0_BIT 4 //片选位
9 #define CS1_BIT 5 //片选位
10 #define CS2_BIT 6 //片选位
11 #define CS3_BIT 7 //片选位
12 /*关片选*/
13 #define CS_MODE0_Disable SPI_PORT|=(1<<CS0_BIT)
14 #define CS_MODE1_Disable SPI_PORT|=(1<<CS1_BIT)
15 #define CS_MODE2_Disable SPI_PORT|=(1<<CS2_BIT)
16 #define CS_MODE3_Disable SPI_PORT|=(1<<CS3_BIT)
17 /*开片选*/
18 #define CS_MODE0_Select SPI_PORT&=(~(1<<CS0_BIT))
19 #define CS_MODE1_Select SPI_PORT&=(~(1<<CS1_BIT))
20 #define CS_MODE2_Select SPI_PORT&=(~(1<<CS2_BIT))
21 #define CS_MODE3_Select SPI_PORT&=(~(1<<CS3_BIT))
22
23 #define SCK_BIT 1 //时钟位
24 #define SI_BIT 2 //从机输入位
25 #define SO_BIT 3 //从机输出位
26
27 #define SCK_H SPI_PORT|=(1<<SCK_BIT) //时钟高电平
28 #define SCK_L SPI_PORT&=~(1<<SCK_BIT) //时钟低电平
29 #define SO ((SPI_PIN&(1<<SO_BIT))>>SO_BIT)
30 #define SI_H SPI_PORT|=(1<<SI_BIT) //从机输入高电平
31 #define SI_L SPI_PORT&=~(1<<SI_BIT)//从机输入低电平
32 /*
33 模式说明
34 0 CPOL =0 CPHA=0
35 1 CPOL =0 CPHA=1
36 2 CPOL =1 CPHA=0
37 3 CPOL =1 CPHA=1
38 */
39 #define SPI_MODE 2
40
41
42 extern void SPI_delay(u8 flag); //脉冲宽度
43 extern void SPI_Init(); //初始化
44 extern u8 SPI_RW(u8 cDATA); //写入和输出
45 extern u8 SPI_Delay_flag; //脉冲宽度选择
46
47 #endif
1 源文件
2 #include "SoftSPI.h"
3 u8 SPI_Delay_flag=0;
4 void SPI_delay(u8 flag)
5 {
6 if (flag) delay_ms(1);
7 else delay_us(10);
8 }
9
10 void SPI_Init()
11 {
12 SPI_DDR|=(1<<SI_BIT)|(1<<SCK_BIT)|(1<<CS0_BIT)|(1<<CS1_BIT)|(1<<CS2_BIT)|(1<<CS3_BIT);
13 SPI_DDR&=~(1<<SO_BIT);
14 SPI_PORT=0XFF;
15 #if SPI_MODE<2
16 SCK_L;
17 #endif
18 #if SPI_MODE>1
19 SCK_H;
20 #endif
21
22 }
23
24 u8 SPI_RW(u8 cDATA)
25 {
26 #if SPI_MODE ==0
27 for (u8 i=0;i<8;i++)
28 {
29 if ((cDATA&0X80)==0X80) SI_H;
30 else SI_L;
31 cDATA<<=1;
32 SCK_H;
33 SPI_delay(SPI_Delay_flag);
34 if(SO>0) cDATA|=1;
35 SCK_L;
36 SPI_delay(SPI_Delay_flag);
37
38 }
39 #endif
40 #if SPI_MODE==1
41 for (u8 i=0;i<8;i++)
42 {
43
44 SCK_H;
45 if ((cDATA&0X80)==0X80) SI_H;
46 else SI_L;
47 cDATA<<=1;
48 SPI_delay(SPI_Delay_flag);
49 SCK_L;
50 SPI_delay(SPI_Delay_flag);
51 if(SO>0) cDATA|=1;
52 }
53 #endif
54 #if SPI_MODE==2
55 for (u8 i=0;i<8;i++)
56 {
57 if ((cDATA&0X80)==0X80) SI_H;
58 else SI_L;
59 cDATA<<=1;
60 SCK_L;SPI_delay(SPI_Delay_flag);
61 if(SO>0) cDATA|=1;
62 SCK_H;SPI_delay(SPI_Delay_flag);
63 }
64 #endif
65 #if SPI_MODE==3
66 for (u8 i=0;i<8;i++)
67 {
68 SCK_L;
69 SPI_delay(SPI_Delay_flag);
70 if ((cDATA&0X80)==0X80) SI_H;
71 else SI_L;
72 cDATA<<=1;
73 SCK_H;
74 SPI_delay(SPI_Delay_flag);
75 if(SO>0) cDATA|=1;
76 }
77 #endif
78 return cDATA;
79 }