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的主要内容,如果未能解决你的问题,请参考以下文章