CH579-SPI0 & SPI1

Posted kingboy100

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH579-SPI0 & SPI1相关的知识,希望对你有一定的参考价值。

SPI0_MASTER&SLAVE

 1 /********************************** (C) COPYRIGHT *******************************
 2 * File Name          : Main.c
 3 * Author             : WCH
 4 * Version            : V1.0
 5 * Date               : 2018/12/15
 6 * Description          : SPI0演示 Master/Slave 模式数据收发
 7 *******************************************************************************/
 8 
 9 #include "CH57x_common.h"
10 
11 
12 __align(4) UINT8 spiBuff[]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
13 __align(4) UINT8 spiBuffrev[16];
14 
15 void DebugInit(void)        
16 {
17     GPIOA_SetBits(GPIO_Pin_9);
18     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
19     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
20     UART1_DefInit();
21 }
22 
23 int main()
24 {
25     UINT8 i;
26     
27 /* 配置串口调试 */   
28     DebugInit();
29     PRINT( "Start @ChipID=%02X
", R8_CHIP_ID );
30 
31 #if 1        
32 /* 主机模式 */ 
33     PRINT( "1.spi0 mul master mode send data ...
");   
34     DelayMs( 100 );
35     
36     GPIOA_SetBits( GPIO_Pin_12 );
37     GPIOA_ModeCfg(GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
38     SPI0_MasterDefInit( );
39     
40 // 单字节发送
41     GPIOA_ResetBits( GPIO_Pin_12 );    
42     SPI0_MasterSendByte(0x55);
43     GPIOA_SetBits( GPIO_Pin_12 );
44     DelayMs( 1 );
45     GPIOA_ResetBits( GPIO_Pin_12 );
46     i = SPI0_MasterRecvByte();
47     GPIOA_SetBits( GPIO_Pin_12 );
48     DelayMs( 2 );
49     
50 // FIFO 连续发送 
51     GPIOA_ResetBits( GPIO_Pin_12 ); 
52     SPI0_MasterTrans( spiBuff, 9 );
53     GPIOA_SetBits( GPIO_Pin_12 );
54     DelayMs( 1 );
55     GPIOA_ResetBits( GPIO_Pin_12 ); 
56     SPI0_MasterRecv( spiBuffrev, 12 );
57     GPIOA_SetBits( GPIO_Pin_12 );
58     DelayMs( 1 );
59     
60 // DMA 连续发送 
61     GPIOA_ResetBits( GPIO_Pin_12 ); 
62     SPI0_MasterDMATrans(spiBuff, 12);
63     GPIOA_SetBits( GPIO_Pin_12 );
64     DelayMs( 1 );
65     GPIOA_ResetBits( GPIO_Pin_12 ); 
66     SPI0_MasterDMARecv(spiBuffrev, 12);
67     GPIOA_SetBits( GPIO_Pin_12 );
68 
69     PRINT( "END ...
");
70     while(1);
71 #endif
72 
73 #if 0
74 /* 设备模式 */ 
75     PRINT( "1.spi0 mul slave mode 
");
76     SPI0_SlaveInit(); 
77     i = SPI0_SlaveRecvByte();
78     SPI0_SlaveSendByte( ~i );
79   
80     SPI0_SlaveRecv( spiBuffrev, 9 );
81     SPI0_SlaveTrans( spiBuffrev, 12 );  
82 
83     while(1); 
84 #endif
85     
86     while(1);    
87      
88 }

 

SPI1_FLASH

main.c

 1 /********************************** (C) COPYRIGHT ****
 2 * File Name          : Main.c
 3 * Author             : WCH
 4 * Version            : V1.0
 5 * Date               : 2019/4/29
 6 * Description          : SPI1 Flash读写操作演示
 7 ******************************************************/
 8 
 9 #include "CH57x_common.h"
10 #include "SPIFlash.H"
11 
12 
13 void DebugInit(void)        
14 {
15     GPIOA_SetBits(GPIO_Pin_9);
16     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
17     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
18     UART1_DefInit();
19 }
20 
21 
22 UINT8  buf[512];
23 
24 int main( )
25 {
26     UINT16    i;
27     
28     DelayMs(20);
29     DebugInit( );   // 调试接口 UART1
30     printf("SPI1 Flash demo start ...
");
31     
32     
33     for(i=0; i!=512; i++)
34     {
35         buf[i] = i;
36     }
37     
38     SPIFlash_Init();
39     EraseExternal4KFlash_SPI(0);
40     BlukWriteExternalFlash_SPI(3,512,buf);
41     BlukReadExternalFlash_SPI( 0,512,buf );
42     
43     for(i=0; i!=512; i++)
44     {
45         printf("%02x ",(UINT16)buf[i]);
46     }
47     printf("done
");    
48     while(1);
49 }

SPIFlash.H

 1 #ifndef __SPIFLASH_H__
 2 #define __SPIFLASH_H__
 3 
 4 #ifdef __cplusplus
 5  extern "C" {
 6 #endif
 7 
 8 #define  CMD_STATUS1         0x05
 9 #define  CMD_WR_ENABLE       0x06
10 #define  CMD_ERASE_4KBYTE    0x20
11 #define  CMD_ERASE_32KBYTE   0x52
12 #define  CMD_READ_DATA       0x03
13 #define  CMD_PAGE_PROG       0x02
14 #define  CMD_FAST_READ       0x0B
15 #define  CMD_DEVICE_ID       0x90
16      
17 /* 擦除函数 */
18 extern void EraseExternal4KFlash_SPI( UINT32 Dst_Addr );                                       //擦除4K
19 extern void EraseExternal32KFlash_SPI( UINT32 Dst_Addr );                                      //擦除32K
20 /* 写函数 */
21 extern void BlukWriteExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 SendBuffer);          //写SPI Flash函数,无限制
22 /* 读函数 */
23 extern void ReadExternalFlash_SPI( UINT32 StarAddr,UINT16 Len,PUINT8 RcvBuffer );              //读SPI Flash函数,无限制
24 extern void BlukReadExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 RcvBuffer);            //读取长度必须为16整数倍,好处是读取速度更快
25 /* 初始化相关 */
26 extern UINT16 SPIFlash_ReadID(void);
27 extern void   SPIFlash_Init(void);
28 
29 #ifdef __cplusplus
30 }
31 #endif
32 
33 #endif

 

SPIFlash.C

  1 /********************************** (C) COPYRIGHT *******************************
  2 * File Name          : SPIFlash.C
  3 * Author             : WCH
  4 * Version            : V1.0
  5 * Date               : 2019/4/29
  6 * Description        : SPI Flash操作接口函数(W25QXX)
  7 *******************************************************************************/
  8 
  9 #include "CH57x_common.h"
 10 #include "SPIFlash.H"
 11 
 12 /********************************* 引脚定义 ************************************
 13 *    PA3  <===========>  SCS
 14 *    PA0  <===========>  SCK
 15 *    PA1  <===========>  DI/MOSI
 16 *    PA2  <===========>  DO/MISO
 17 *******************************************************************************/
 18 
 19 #define  SPI1_CS_LOW()        GPIOA_ResetBits( GPIO_Pin_3 )
 20 #define  SPI1_CS_HIGH()       GPIOA_SetBits( GPIO_Pin_3 )
 21 
 22 /*******************************************************************************
 23 * Function Name  : ReadExternalFlashStatusReg_SPI
 24 * Description    : 用来读取状态寄存器,并返回状态寄存器的值
 25 * Input          : None
 26 * Output         : None
 27 * Return         : ExFlashRegStatus
 28 *******************************************************************************/
 29 UINT8 ReadExternalFlashStatusReg_SPI( void )
 30 {
 31     UINT8 ExFlashRegStatus;
 32     
 33     
 34     SPI1_CS_LOW();
 35     SPI1_MasterSendByte( CMD_STATUS1 );   //发送读状态寄存器的命令
 36     ExFlashRegStatus = SPI1_MasterRecvByte();//读取状态寄存器
 37     SPI1_CS_HIGH();
 38     
 39     return ExFlashRegStatus;
 40 }
 41 
 42 /*******************************************************************************
 43 * Function Name  : WaitExternalFlashIfBusy
 44 * Description    : 等待芯片空闲(在执行Byte-Program, Sector-Erase, Block-Erase, Chip-Erase操作后)
 45 * Input          : None
 46 * Output         : None
 47 * Return         : None
 48 *******************************************************************************/
 49 void WaitExternalFlashIfBusy( void )
 50 {
 51     while ((ReadExternalFlashStatusReg_SPI())&0x01 == 0x01 )
 52     {
 53         ;    //等待直到Flash空闲
 54     }
 55 }
 56 /*******************************************************************************
 57 * Function Name  : WriteExternalFlashEnable_SPI
 58 * Description    : 写使能,同样可以用于使能写状态寄存器
 59 * Input          : None
 60 * Output         : None
 61 * Return         : None
 62 *******************************************************************************/
 63 void WriteExternalFlashEnable_SPI( void )
 64 {
 65     SPI1_CS_LOW();
 66     SPI1_MasterSendByte( CMD_WR_ENABLE );//发送写使能命令
 67     SPI1_CS_HIGH();
 68 }
 69 /*******************************************************************************
 70 * Function Name  : EraseExternal4KFlash_SPI
 71 * Description    : 擦除4K Flash  擦除一个扇区
 72 * Input          : Dst_Addr 0-1 ffff ffff ,清除任意地址所在的扇区。
 73 * Output         : None
 74 * Return         : None
 75 *******************************************************************************/
 76 void EraseExternal4KFlash_SPI( UINT32 Dst_Addr )
 77 {
 78     WriteExternalFlashEnable_SPI();
 79     WaitExternalFlashIfBusy();
 80     
 81     SPI1_CS_LOW();
 82     SPI1_MasterSendByte(CMD_ERASE_4KBYTE); //扇区擦除命令
 83     SPI1_MasterSendByte(((Dst_Addr & 0xFFFFFF) >> 16));//发送3字节地址
 84     SPI1_MasterSendByte(((Dst_Addr & 0xFFFF) >> 8));
 85     SPI1_MasterSendByte(Dst_Addr & 0xFF);
 86     SPI1_CS_HIGH();
 87     
 88     WaitExternalFlashIfBusy();
 89 }
 90 /*******************************************************************************
 91 * Function Name  : EraseExternalFlash_SPI
 92 * Description    : 擦除32K Flash  擦除一个扇区
 93 * Input          : Dst_Addr 0-1 ffff ffff ,清除任意地址所在的扇区。
 94 * Output         : None
 95 * Return         : None
 96 *******************************************************************************/
 97 void EraseExternal32KFlash_SPI( UINT32 Dst_Addr )
 98 {
 99     WriteExternalFlashEnable_SPI();
100     WaitExternalFlashIfBusy();
101     
102     SPI1_CS_LOW();
103     SPI1_MasterSendByte(CMD_ERASE_32KBYTE);  //32K擦除命令
104     SPI1_MasterSendByte(((Dst_Addr & 0xFFFFFF) >> 16));//发送3字节地址
105     SPI1_MasterSendByte(((Dst_Addr & 0xFFFF) >> 8));
106     SPI1_MasterSendByte(Dst_Addr & 0xFF);
107     SPI1_CS_HIGH();
108     
109     WaitExternalFlashIfBusy();
110 }
111 /*******************************************************************************
112 * Function Name  : PageWriteExternalFlash_SPI
113 * Description    : 页写;SPI在一页(0~65535)内写入少于256个字节的数据
114 * Input          : RcvBuffer:数据存储区
115 *                  StarAddr:开始写入的地址
116 *                  Len:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
117 * Output         : None
118 * Return         : None
119 *******************************************************************************/
120 void PageWriteExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 RcvBuffer)
121 {
122     UINT16 i;
123     
124     WriteExternalFlashEnable_SPI(); //SET WEL
125     
126     SPI1_CS_LOW();                                                            
127     SPI1_MasterSendByte(CMD_PAGE_PROG);  //发送写页命令
128     SPI1_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16)); //发送24bit地址
129     SPI1_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
130     SPI1_MasterSendByte(StarAddr & 0xFF);
131     for(i=0; i!=Len; i++)
132     {
133         SPI1_MasterSendByte(RcvBuffer[i]);//循环写数
134     }
135     SPI1_CS_HIGH();
136     
137     WaitExternalFlashIfBusy(); //等待写入结束
138 }
139 /*******************************************************************************
140 * Function Name  : BlukWriteExternalFlash_SPI
141 * Description    : 无检验写SPI FLASH
142 *                  必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
143 *                  具有自动换页功能
144 *                  在指定地址开始写入指定长度的数据,但是要确保地址不越界!
145 * Input          : SendBuffer:数据存储区
146 *                  StarAddr:开始写入的地址
147 *                  Len:要写入的字节数(最大65535)
148 * Output         : None
149 * Return         : None
150 *******************************************************************************/
151 void BlukWriteExternalFlash_SPI(UINT32 StarAddr,UINT16 Len,PUINT8 SendBuffer)
152 {
153     UINT16  pageremain;
154     
155     pageremain = 256-StarAddr%256;//单页剩余的字节数
156     if(Len<=pageremain)
157     {
158         pageremain=Len;//不大于256个字节
159     }
160     while(1)
161     {
162         PageWriteExternalFlash_SPI(StarAddr,pageremain,SendBuffer);
163         if(Len==pageremain)
164         {
165             break;    //写入结束了
166         }
167         else
168         {
169             SendBuffer+=pageremain;
170             StarAddr+=pageremain;
171             Len-=pageremain;  //减去已经写入了的字节数
172             if(Len>256)
173             {
174                 pageremain=256;//一次可以写入256个字节
175             }
176             else
177             {
178                 pageremain=Len;//不够256个字节了
179             }
180         }
181     }
182 }
183 /*******************************************************************************
184 * Function Name  : ReadExternalFlash_SPI
185 * Description    : 读取地址的数据.
186 *******************************************************************************/
187 void ReadExternalFlash_SPI( UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer )
188 {    
189     SPI1_CS_LOW();                                                      
190     SPI1_MasterSendByte(CMD_READ_DATA);                 //读命令
191     SPI1_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16));//发送3字节地址
192     SPI1_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
193     SPI1_MasterSendByte(StarAddr & 0xFF);
194     SPI1_MasterRecv( RcvBuffer, Len );
195     SPI1_CS_HIGH();
196 }
197 /*******************************************************************************
198 * Function Name  : BlukReadExternalFlash_SPI
199 * Description    : 读取起始地址(StarAddr)内多个字节(Len)的数据.存入缓冲区RcvBuffer中
200 * Input          : StarAddr -Destination Address 000000H - 1FFFFFH
201                    Len 读取数据长度
202                    RcvBuffer 接收缓冲区起始地址
203 * Output         : None
204 * Return         : None
205 *******************************************************************************/
206 void BlukReadExternalFlash_SPI( UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer )
207 {    
208     SPI1_CS_LOW();
209     SPI1_MasterSendByte(CMD_FAST_READ);                //高速度
210     SPI1_MasterSendByte(((StarAddr & 0xFFFFFF) >> 16));//发送3字节地址
211     SPI1_MasterSendByte(((StarAddr & 0xFFFF) >> 8));
212     SPI1_MasterSendByte(StarAddr & 0xFF);
213     SPI1_MasterSendByte(0x00);    
214     SPI1_MasterRecv( RcvBuffer, Len );
215     SPI1_CS_HIGH();
216 }
217 /*******************************************************************************
218 * Function Name  : SPIFlash_ReadID
219 * Description    : SPI Flash读取芯片ID
220 * Input          : None
221 * Output         : None
222 * Return         : 0XEF13,表示芯片型号为W25Q80
223 *                  0XEF14,表示芯片型号为W25Q16
224 *                  0XEF15,表示芯片型号为W25Q32
225 *                  0XEF16,表示芯片型号为W25Q64
226 *                  0XEF17,表示芯片型号为W25Q128
227 *******************************************************************************/
228 UINT16 SPIFlash_ReadID(void)
229 {
230     UINT16  temp = 0;
231     
232     SPI1_CS_LOW();
233     SPI1_MasterSendByte(CMD_DEVICE_ID); //读取ID命令
234     SPI1_MasterSendByte(0x00);
235     SPI1_MasterSendByte(0x00);
236     SPI1_MasterSendByte(0x00);
237     temp = SPI1_MasterRecvByte();
238     temp = temp<<8;
239     temp |= SPI1_MasterRecvByte();
240     SPI1_CS_HIGH();
241     
242     return temp;
243 }
244 /*******************************************************************************
245 * Function Name  : SPI1Flash_Init
246 * Description    : SPI Flash初始化
247 * Input          : None
248 * Output         : None
249 * Return         : None
250 *******************************************************************************/
251 void SPIFlash_Init(void)
252 {
253     GPIOA_SetBits( GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3 );
254     GPIOA_ModeCfg( GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3, GPIO_ModeOut_PP_5mA );//MOSI/SCK/CS
255     GPIOA_SetBits( GPIO_Pin_2 );
256     GPIOA_ModeCfg( GPIO_Pin_2, GPIO_ModeIN_PU );//MISO    
257     
258     SPI1_MasterDefInit();
259     SPI1_DataMode( Mode3_HighBitINFront );
260     SPI1_CLKCfg( 4 );
261     printf("id:0x%04x
", SPIFlash_ReadID() );
262 }

 

SPI1_MASTER

 1 /********************************** (C) COPYRIGHT *******************************
 2 * File Name          : Main.c
 3 * Author             : WCH
 4 * Version            : V1.0
 5 * Date               : 2019/4/29
 6 * Description          : SPI1演示 Master 模式数据收发
 7 *******************************************************************************/
 8 
 9 #include "CH57x_common.h"
10 
11 /*  
12 引脚定义:
13 
14 PA0  <->    SCK1
15 PA1  <->    MOSI1
16 PA2  <->    MISO1
17 PA4  <->    SCS1
18 
19 */
20 
21 
22 __align(4) UINT8 spiBuff[]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
23 __align(4) UINT8 spiBuffrev[16];
24 
25 void DebugInit(void)        
26 {
27     GPIOA_SetBits(GPIO_Pin_9);
28     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
29     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
30     UART1_DefInit();
31 }
32 
33 int main()
34 {
35     UINT8 i;
36     
37 /* 配置串口调试 */   
38     DebugInit();
39     PRINT( "Start @ChipID=%02X
", R8_CHIP_ID );
40 
41 #if 1        
42 /* 主机模式 */ 
43     PRINT( "1.spi1 mul master mode send data ...
");   
44     DelayMs( 100 );
45     
46     GPIOA_SetBits( GPIO_Pin_4 );
47     GPIOA_ModeCfg(GPIO_Pin_4|GPIO_Pin_0|GPIO_Pin_1, GPIO_ModeOut_PP_5mA);
48     GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);
49     SPI1_MasterDefInit( );
50     
51 // 单字节发送/接收
52     GPIOA_ResetBits( GPIO_Pin_4 );    
53     SPI1_MasterSendByte(0x55);
54     GPIOA_SetBits( GPIO_Pin_4 );
55     DelayMs( 1 );
56     GPIOA_ResetBits( GPIO_Pin_4 );
57     i = SPI1_MasterRecvByte();
58     GPIOA_SetBits( GPIO_Pin_4 );
59     DelayMs( 2 );
60     
61 // FIFO 连续发送/接收 
62     GPIOA_ResetBits( GPIO_Pin_4 ); 
63     SPI1_MasterTrans( spiBuff, 9 );
64     GPIOA_SetBits( GPIO_Pin_4 );
65     DelayMs( 1 );
66     GPIOA_ResetBits( GPIO_Pin_4 ); 
67     SPI1_MasterRecv( spiBuffrev, 12 );
68     GPIOA_SetBits( GPIO_Pin_4 );
69     DelayMs( 1 );
70  
71     PRINT( "END ...
");
72     while(1);
73 #endif
74 
75 
76     while(1);    
77      
78 }

 

以上是关于CH579-SPI0 & SPI1的主要内容,如果未能解决你的问题,请参考以下文章

读入优化 && 输出优化

STM32F4 SPI1 工作,SPI5 不工作?

字符串转数字简单代码实现

对这个带有 & 不带 = 的代码片段返回类型感到非常困惑

求助STM32关于SPI问题!!状态寄存器BSY位永远为1

Sphinx - 在代码块片段中使用省略号 (...)