[新手园地] HOT大叔NUC120助学板第十贴----SPI(查询方式)

[复制链接]
 楼主| Swallow_0322 发表于 2011-5-7 17:19 | 显示全部楼层 |阅读模式
本帖最后由 Swallow_0322 于 2011-5-7 17:51 编辑

      菜鸟玩SPI查询方式完成对W25Q16BV的读写操作,望各位高手多多指教!

源代码如下:
  1. /**************************************************
  2. ** 文件名称:NUC120_HOT_SPI.c
  3. ** 文件说明:NUC120助学板练习程序
  4. ** 创建日期:2011-05-07
  5. ** 修改日期:
  6. ** 备 注:SPI读写W25Q16BV
  7. **************************************************/
  8. #include <stdio.h>
  9. #include "NUC1xx.h"
  10. #include "Driver\DrvGPIO.h"
  11. #include "Driver\DrvSYS.h"
  12. #include "Driver\DrvUART.h"
  13. #include "Driver\DrvSPI.h"

  14. #define Run_Led 2 //2----LED1 3----LED2 4----LED3 5----LED4
  15. #define SPI_CS_PORT E_GPA
  16. #define SPI_CS_PORT_NUM 14
  17. #define Enable_SPI_CS DrvGPIO_ClrBit(SPI_CS_PORT,SPI_CS_PORT_NUM)
  18. #define DISABLE_SPI_CS DrvGPIO_SetBit(SPI_CS_PORT,SPI_CS_PORT_NUM)

  19. volatile uint8_t IsStart = FALSE;
  20. volatile uint8_t Receive_Data = 0;



  21. /***************
  22. ** 函数声明 **
  23. ***************/
  24. void Init_System (void);
  25. void Init_Uart (void);
  26. void UART_INT_HANDLE(uint32_t u32IntStatus);

  27. uint32_t SPI_ReadMidDid(void);
  28. uint32_t SPI_ReadStatusReg1(void);
  29. void SPI_WaitReady(void);
  30. void SPI_ChipErase(void);
  31. void SPI_ReadData(uint8_t *DataBuffer0, uint32_t StartAddress, uint32_t ByteCount);
  32. void SPI_PageProgram(uint8_t *DataBuffer, uint32_t StartAddress, uint32_t ByteCount);
  33. void SPI_SectorErase(uint32_t StartAddress);




  34. /*****************************
  35. ** Name: UART_INT_HANDLE
  36. ** Function: UART Callback function
  37. ** Input: u32IntStatus
  38. ** OutPut: None
  39. ** Data: 2011-03-17
  40. ** Note:
  41. ****************************/
  42. void UART_INT_HANDLE(uint32_t u32IntStatus)
  43. {

  44. uint8_t bInChar[1]={0xFF};

  45. if(u32IntStatus & DRVUART_RDAINT)
  46. {
  47. /* Get all the input characters */
  48. while(UART0->ISR.RDA_IF==1)
  49. {
  50. /* Get the character from UART Buffer */
  51. DrvUART_Read(UART_PORT0,bInChar,1);
  52. if (IsStart!=TRUE)
  53. {
  54. IsStart = TRUE;
  55. Receive_Data = bInChar[0];
  56. }
  57. }
  58. }
  59. }

  60. /*****************************
  61. ** Name: Init_System
  62. ** Function: 系统初始化函数
  63. ** Input: None
  64. ** OutPut: None
  65. ** Data: 2011-03-17
  66. ** Note:
  67. ****************************/
  68. void Init_System(void)
  69. {
  70. /* Unlock the locked registers before access */
  71. UNLOCKREG(x); //寄存器锁定键地址寄存器(RegLockAddr) :有些系统控制寄存器需要被保护起来,以防止误操作而影响芯片运行,
  72. //这些寄存器在上电复位到用户解锁定之前是锁定的。用户可以连续依次写入“59h”, “16h” “88h”到0x5000_0100解锁定.
  73. /* Enable the 12MHz oscillator oscillation */
  74. DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1); //SYSCLK->WRCON.XTL12M_EN = 1;

  75. /* Waiting for 12M Xtal stable */
  76. //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1); //SYSCLK->CLKSTATUS.XTL12M_STB
  77. /*eClkSrc - [in] E_SYS_XTL12M / E_SYS_XTL32K / E_SYS_OSC22M / E_SYS_OSC10K / E_SYS_PLL */
  78. // Note: Only some of NuMicro NUC100 Series support this function.

  79. DrvSYS_Delay(5000);
  80. LOCKREG(x);
  81. //向“0x5000_0100”写入任何值,就可以重锁保护寄存器
  82. }

  83. /*****************************
  84. ** Name: Init_Uart
  85. ** Function: UART初始化函数
  86. ** Input: None
  87. ** OutPut: None
  88. ** Data: 2011-03-17
  89. ** Note:
  90. ****************************/
  91. void Init_Uart(void)
  92. {
  93. STR_UART_T param;
  94. /*
  95. 声明 UART设置的结构体 位于DRVUART.H
  96. 结构体如下
  97. typedef struct DRVUART_STRUCT
  98. {
  99. uint32_t u32BaudRate;
  100. E_DATABITS_SETTINS u8cDataBits;
  101. E_STOPBITS_SETTINS u8cStopBits;
  102. E_PARITY_SETTINS u8cParity;
  103. E_FIFO_SETTINGS u8cRxTriggerLevel;
  104. uint8_t u8TimeOut ;
  105. }STR_UART_T;
  106. */
  107. DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0); //使能UART时钟
  108. //SYSCLK->CLKSEL1.UART_S = 0; //UART时钟源选择. 00 =外部12MHz 晶振 01 = PLL 1x =内部 22MHz 振荡器

  109. DrvGPIO_InitFunction(E_FUNC_UART0); //GPB_MFP0-1-2-3置位 GPIO使能UART功能
  110. //outpw(&SYS->GPBMFP, inpw(&SYS->GPBMFP) | (0xF<<0));

  111. param.u32BaudRate = 115200; // 波特率
  112. param.u8cDataBits = DRVUART_DATABITS_8; // 数据位
  113. param.u8cStopBits = DRVUART_STOPBITS_1; // 停止位
  114. param.u8cParity = DRVUART_PARITY_NONE; // 校验位
  115. param.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES; // FIFO存储深度 1 字节
  116. param.u8TimeOut = 0; // FIFO超时设定
  117. /* Set UART Configuration */
  118. if(DrvUART_Open(UART_PORT0,¶m) != E_SUCCESS) // 串口开启、结构体整体赋值
  119. printf("UART0 open failed\n");
  120. /* u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 /UART_PORT2 */
  121. /* sParam -[in] the struct parameter to configure UART */

  122. /* Enable Interrupt and install the call back function */
  123. DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);
  124. /*u32Port -[in] UART Channel: UART_PORT0 / UART_PORT1 / UART_PORT2 */
  125. /*u32InterruptFlag -[in] DRVUART_LININT/DRVUART_WAKEUPINT/DRVUART_BUFERRINT/DRVUART_RLSINT */
  126. /* DRVUART_MOSINT/DRVUART_THREINT/DRVUART_RDAINT/DRVUART_TOUTINT */
  127. /*pfncallback -[in] A function pointer for callback function */
  128. }

  129. /*****************************
  130. ** Name: Init_SPI
  131. ** Function: SPI初始化函数
  132. ** Input: None
  133. ** OutPut: None
  134. ** Data: 2011-05-07
  135. ** Note:
  136. ****************************/
  137. void Init_SPI(void)
  138. {
  139. DrvSPI_Open(eDRVSPI_PORT1, eDRVSPI_MASTER, eDRVSPI_TYPE1, 32,FALSE);
  140. //配置SPI1为主模式 TYPE1波形 32位传输

  141. DrvSPI_SetEndian(eDRVSPI_PORT1, eDRVSPI_MSB_FIRST);
  142. //配置传输比特的顺序:优先发送/接收MSB

  143. DrvSPI_DisableAutoSS(eDRVSPI_PORT1);
  144. //禁止自动片选功能

  145. DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT1, eDRVSPI_ACTIVE_LOW_FALLING);
  146. //设定从选择线的激活级别:低电平或者下降沿

  147. DrvSPI_Set2BitTransferMode(eDRVSPI_PORT1, TRUE);
  148. //设置2 比特串行数据I/O 模式

  149. DrvSPI_SetClockFreq(eDRVSPI_PORT1, 1000000, 0);
  150. //设置SPI的时钟频率为1MHz

  151. DrvGPIO_Open(SPI_CS_PORT,SPI_CS_PORT_NUM, E_IO_OUTPUT); //SPI_FLAH_CS
  152. DISABLE_SPI_CS;

  153. }

  154. int main (void)
  155. {
  156. uint8_t test = 250;
  157. uint32_t Tmp = 0;
  158. uint8_t DataBuffer[256];


  159. Init_System();

  160. Init_Uart();

  161. Init_SPI();

  162. DrvGPIO_Open(E_GPA,Run_Led, E_IO_OUTPUT); //程序运行指示
  163. DrvGPIO_ClrBit(E_GPA,Run_Led);

  164. printf("\n");
  165. printf("/*==========================\n");
  166. printf("======菜农 %d 助学计划======\n",test);
  167. printf("========NUC120助学板========\n");
  168. printf("======程序参考新唐例程======\n");
  169. printf("=======2011年05月07日=======\n");
  170. printf("======SPI实验(查询方式)=====\n");
  171. SPI_WaitReady();
  172. Tmp = SPI_ReadMidDid();
  173. printf("W25Q16BV制造商ID及设备ID为:0x%X\n",Tmp);

  174. //W25Q16BV Page 0 初始化
  175. SPI_WaitReady();
  176. SPI_ReadData(DataBuffer,0x1000,1);
  177. if (DataBuffer[0]!=0xAA)
  178. {
  179. DataBuffer[0] = 0xAA;
  180. SPI_WaitReady();
  181. SPI_ChipErase();
  182. SPI_WaitReady();
  183. SPI_PageProgram(DataBuffer,0x1000,1);
  184. for (Tmp=0;Tmp<256;Tmp++)
  185. DataBuffer[Tmp] = Tmp;
  186. SPI_WaitReady();
  187. SPI_PageProgram(DataBuffer,0,256);
  188. }

  189. //W25Q16BV Page 0 读取
  190. printf("Read Flash (Page 0) ...\n");
  191. SPI_WaitReady();
  192. SPI_ReadData(DataBuffer,0,256);
  193. for (Tmp=0;Tmp<256;Tmp++)
  194. {
  195. printf("0x%X ",DataBuffer[Tmp]);
  196. if ((Tmp%16)==15)printf("\n");
  197. }
  198. printf("Read Flash (Page 0) done!\n");

  199. printf("'R/r'为读指令、'U/u'为Page 0加1并存储指令、'D/d'为Page 0减1并存储指令\n");
  200. printf("====请输入字符开始测试!===\n");
  201. printf("==========================*/\n");

  202. while(1)
  203. {
  204. if (IsStart)
  205. {
  206. switch (Receive_Data)
  207. {
  208. case 'R':
  209. case 'r':
  210. printf("Read Flash (Page 0) ...\n");
  211. SPI_WaitReady();
  212. SPI_ReadData(DataBuffer,0,256);
  213. for (Tmp=0;Tmp<256;Tmp++)
  214. {
  215. printf("0x%X ",DataBuffer[Tmp]);
  216. if ((Tmp%16)==15)printf("\n");
  217. }
  218. printf("Read Flash (Page 0) done!\n");
  219. break;
  220. case 'U':
  221. case 'u':
  222. printf("rogram Flash (Page 0)[Add 1] ...\n");
  223. SPI_WaitReady();
  224. SPI_ReadData(DataBuffer,0,256);
  225. for (Tmp=0;Tmp<256;Tmp++)
  226. {
  227. DataBuffer[Tmp] += 1;
  228. }
  229. SPI_WaitReady();
  230. SPI_SectorErase(0x0000);
  231. SPI_WaitReady();
  232. SPI_PageProgram(DataBuffer,0,256);
  233. printf("rogram Flash (Page 0)[Add 1] done!\n");
  234. break;
  235. case 'D':
  236. case 'd':
  237. printf("rogram Flash (Page 0)[Minus 1] ...\n");
  238. SPI_WaitReady();
  239. SPI_ReadData(DataBuffer,0,256);
  240. for (Tmp=0;Tmp<256;Tmp++)
  241. {
  242. DataBuffer[Tmp] -= 1;
  243. }
  244. SPI_WaitReady();
  245. SPI_SectorErase(0x0000);
  246. SPI_WaitReady();
  247. SPI_PageProgram(DataBuffer,0,256);
  248. printf("rogram Flash (Page 0)[Minus 1] done!\n");
  249. break;
  250. default:
  251. printf("请确认您输入的指令是否合法!\n");

  252. }
  253. IsStart = FALSE;
  254. }
  255. }
  256. }

  257. /*****************************
  258. ** Name: SPI_ReadMidDid
  259. ** Function: W25Q16BV读制造商ID及设备ID函数
  260. ** Input: None
  261. ** OutPut: MID & DID
  262. ** Data: 2011-05-07
  263. ** Note:
  264. ****************************/
  265. uint32_t SPI_ReadMidDid(void)
  266. {
  267. uint32_t au32SourceData;
  268. uint32_t au32DestinationData;

  269. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  270. //配置SPI传输的比特长度:8 bits

  271. Enable_SPI_CS;
  272. //激活/配置从设备片选信号

  273. au32SourceData = 0x90;
  274. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  275. //发送数据到 SPI 总线: 0x90 (Read Manufacturer/Device ID)

  276. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  277. //等待SPI端口空闲

  278. DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
  279. //配置SPI传输的比特长度:24 bits

  280. au32SourceData = 0x0;
  281. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  282. //发送数据到 SPI 总线: 0x00 (24-bit Address)

  283. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  284. //等待SPI端口空闲

  285. DrvSPI_SetBitLength(eDRVSPI_PORT1, 16);
  286. //配置SPI传输的比特长度:16 bits


  287. au32SourceData = 0x0;
  288. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  289. //接收数据

  290. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  291. //等待SPI端口空闲

  292. DISABLE_SPI_CS;
  293. //从设备片选信号取消激活

  294. DrvSPI_DumpRxRegister(eDRVSPI_PORT1, &au32DestinationData, 1);
  295. //从接收寄存器读数据. 但是不触发下一次数据传输.

  296. return (au32DestinationData & 0xffff);
  297. }

  298. /*****************************
  299. ** Name: SPI_ReadStatusReg1
  300. ** Function: W25Q16BV读状态寄存器1函数
  301. ** Input: None
  302. ** OutPut: ReadStatusReg1
  303. ** Data: 2011-05-07
  304. ** Note:
  305. ****************************/
  306. uint32_t SPI_ReadStatusReg1(void)
  307. {
  308. uint32_t au32SourceData;
  309. uint32_t au32DestinationData;

  310. DrvSPI_SetBitLength(eDRVSPI_PORT1, 16);
  311. //配置SPI传输的比特长度:16 bits

  312. Enable_SPI_CS;
  313. //激活/配置从设备片选信号

  314. au32SourceData = 0x0500;
  315. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  316. //发送数据到 SPI 总线: 0x0500 (Read status register 1)

  317. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  318. //等待SPI端口空闲

  319. DISABLE_SPI_CS;
  320. //从设备片选信号取消激活

  321. DrvSPI_DumpRxRegister(eDRVSPI_PORT1, &au32DestinationData, 1);
  322. //从接收寄存器读数据. 但是不触发下一次数据传输.

  323. return (au32DestinationData & 0xFF);
  324. }

  325. /*****************************
  326. ** Name: SPI_WaitReady
  327. ** Function: W25Q16BV忙状态检查函数
  328. ** Input: None
  329. ** OutPut: None
  330. ** Data: 2011-05-07
  331. ** Note:
  332. ****************************/
  333. void SPI_WaitReady(void)
  334. {
  335. uint32_t ReturnValue;

  336. do{
  337. ReturnValue = SPI_ReadStatusReg1();
  338. ReturnValue = ReturnValue & 1;
  339. }while(ReturnValue!=0);
  340. //检查从设备状态寄存器1的BUSY位 等待其为0
  341. }

  342. /*****************************
  343. ** Name: SPI_ChipErase
  344. ** Function: W25Q16BV片擦除函数
  345. ** Input: None
  346. ** OutPut: None
  347. ** Data: 2011-05-07
  348. ** Note:
  349. ****************************/
  350. void SPI_ChipErase(void)
  351. {

  352. uint32_t au32SourceData;

  353. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  354. //配置SPI传输的比特长度:8 bits

  355. Enable_SPI_CS;
  356. //激活/配置从设备片选信号

  357. au32SourceData = 0x06;
  358. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  359. //发送数据到 SPI 总线: 0x06 (Write enable)

  360. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  361. //等待SPI端口空闲

  362. DISABLE_SPI_CS;
  363. //从设备片选信号取消激活

  364. Enable_SPI_CS;
  365. //激活/配置从设备片选信号

  366. au32SourceData = 0xC7;
  367. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  368. //发送数据到 SPI 总线: 0xC7 (Chip Erase)

  369. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  370. //等待SPI端口空闲

  371. DISABLE_SPI_CS;
  372. //从设备片选信号取消激活
  373. }

  374. /*****************************
  375. ** Name: SPI_ReadData
  376. ** Function: W25Q16BV读数据函数
  377. ** Input: DataBuffer0,StartAddressByteCount
  378. ** OutPut: None
  379. ** Data: 2011-05-07
  380. ** Note:
  381. ****************************/
  382. void SPI_ReadData(uint8_t *DataBuffer, uint32_t StartAddress, uint32_t ByteCount)
  383. {
  384. uint32_t au32SourceData;
  385. uint32_t au32DestinationData;
  386. uint32_t Counter;

  387. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  388. //配置SPI传输的比特长度:8 bits

  389. Enable_SPI_CS;
  390. //激活/配置从设备片选信号

  391. au32SourceData = 0x03;
  392. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  393. //发送数据到 SPI 总线: 0x03 (Read data)

  394. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  395. //等待SPI端口空闲

  396. DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
  397. //配置SPI传输的比特长度:24 bits

  398. au32SourceData = StartAddress;
  399. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  400. //发送数据到 SPI 总线: StartAddress

  401. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  402. //等待SPI端口空闲

  403. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  404. //配置SPI传输的比特长度:8 bits

  405. for(Counter=0; Counter<ByteCount; Counter++)
  406. {
  407. au32SourceData = 0x0;
  408. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  409. //接收数据;

  410. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  411. //等待SPI端口空闲

  412. DrvSPI_DumpRxRegister(eDRVSPI_PORT1, &au32DestinationData, 1);
  413. //从接收寄存器读数据. 但是不触发下一次数据传输.
  414. DataBuffer[Counter] = (uint8_t) au32DestinationData;
  415. }

  416. DISABLE_SPI_CS;
  417. //从设备片选信号取消激活
  418. }

  419. /*****************************
  420. ** Name: SPI_PageProgram
  421. ** Function: W25Q16BV按页编程函数
  422. ** Input: DataBuffer,StartAddressByteCount
  423. ** OutPut: None
  424. ** Data: 2011-05-07
  425. ** Note:
  426. ****************************/
  427. void SPI_PageProgram(uint8_t *DataBuffer, uint32_t StartAddress, uint32_t ByteCount)
  428. {
  429. uint32_t au32SourceData;
  430. uint32_t Counter;

  431. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  432. //配置SPI传输的比特长度:8 bits

  433. Enable_SPI_CS;
  434. //激活/配置从设备片选信号

  435. au32SourceData = 0x06;
  436. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  437. //发送数据到 SPI 总线: 0x06 (Write enable)

  438. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  439. //等待SPI端口空闲

  440. DISABLE_SPI_CS;
  441. //从设备片选信号取消激活

  442. Enable_SPI_CS;
  443. //激活/配置从设备片选信号

  444. au32SourceData = 0x02;
  445. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  446. //发送数据到 SPI 总线: 0x02 (Page program)

  447. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  448. //等待SPI端口空闲

  449. DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
  450. //配置SPI传输的比特长度:24 bits

  451. au32SourceData = StartAddress;
  452. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  453. //发送数据到 SPI 总线: StartAddress

  454. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  455. //等待SPI端口空闲

  456. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  457. //配置SPI传输的比特长度:8 bits

  458. for(Counter=0; Counter<ByteCount; Counter++)
  459. {
  460. au32SourceData = DataBuffer[Counter];
  461. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  462. //发送数据到 SPI 总线

  463. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  464. //等待SPI端口空闲
  465. }

  466. DISABLE_SPI_CS;
  467. //从设备片选信号取消激活
  468. }

  469. /*****************************
  470. ** Name: SPI_SectorErase
  471. ** Function: W25Q16BV扇区擦除函数
  472. ** Input: StartAddress
  473. ** OutPut: None
  474. ** Data: 2011-05-07
  475. ** Note:
  476. ****************************/
  477. void SPI_SectorErase(uint32_t StartAddress)
  478. {

  479. uint32_t au32SourceData;

  480. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  481. //配置SPI传输的比特长度:8 bits

  482. Enable_SPI_CS;
  483. //激活/配置从设备片选信号

  484. au32SourceData = 0x06;
  485. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  486. //发送数据到 SPI 总线: 0x06 (Write enable)

  487. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  488. //等待SPI端口空闲

  489. DISABLE_SPI_CS;
  490. //从设备片选信号取消激活

  491. DrvSPI_SetBitLength(eDRVSPI_PORT1, 8);
  492. //配置SPI传输的比特长度:8 bits

  493. Enable_SPI_CS;
  494. //激活/配置从设备片选信号

  495. au32SourceData = 0x20;
  496. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  497. //发送数据到 SPI 总线: 0x20 (Sector Erase)

  498. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  499. //等待SPI端口空闲

  500. DrvSPI_SetBitLength(eDRVSPI_PORT1, 24);
  501. //配置SPI传输的比特长度:24 bits

  502. au32SourceData = StartAddress&0xFFF000;
  503. DrvSPI_SingleWrite(eDRVSPI_PORT1, &au32SourceData);
  504. //发送数据到 SPI 总线: StartAddress

  505. while (DrvSPI_IsBusy(eDRVSPI_PORT1)) {}
  506. //等待SPI端口空闲

  507. DISABLE_SPI_CS;
  508. //从设备片选信号取消激活
  509. }


工程文件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| Swallow_0322 发表于 2011-5-7 17:23 | 显示全部楼层
本帖最后由 Swallow_0322 于 2011-5-7 17:50 编辑

工程结构:


串口调试截图:
①上电截图:



② 发送'U'指令截图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| Swallow_0322 发表于 2011-5-7 17:49 | 显示全部楼层
③ 发送'R'指令截图:


④ 发送'D'指令截图:


⑤ 发送'R'指令截图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
john_lee 发表于 2011-5-7 18:19 | 显示全部楼层
支持,支持。
hotpower 发表于 2011-5-7 20:06 | 显示全部楼层
很好,再将其改为PDMA方式!

很给力!!!!!!!
 楼主| Swallow_0322 发表于 2011-5-8 07:38 | 显示全部楼层
4# john_lee

多谢老师捧场!
下一贴SPI(PDMA方式)之后准备搁置SD卡及I2S的音频驱动,熟悉老师的LooK+HOT大叔的红杏!
hotpower 发表于 2011-5-8 08:26 | 显示全部楼层
俺做菜鸟时做过spi+pdma,实际是usb转spi,与dsp通讯
weshiluwei6 发表于 2011-5-8 18:45 | 显示全部楼层
SPI 总线连的什么呢  大哥:loveliness:
 楼主| Swallow_0322 发表于 2011-5-8 19:48 | 显示全部楼层
9# weshiluwei6

呵呵!SPI查询方式完成对W25Q16BV的读写操作!
hotpower 发表于 2011-5-9 01:25 | 显示全部楼层
估计水王没玩过spi
ichuangj 发表于 2011-5-17 15:05 | 显示全部楼层
好!
weshiluwei6 发表于 2011-5-26 13:06 | 显示全部楼层
本帖最后由 weshiluwei6 于 2011-5-26 13:08 编辑

10# Swallow_0322

我找找看 没听说过这个 我以为事什么呢
weshiluwei6 发表于 2011-5-26 13:07 | 显示全部楼层
11# hotpower

哈哈 俺玩过74HC595 好像是SPI的么?
新好男孩 发表于 2011-8-10 17:29 | 显示全部楼层
      菜鸟玩SPI查询方式完成对W25Q16BV的读写操作,望各位高手多多指教!

源代码如下:/**************************************************
** 文件名称:NUC120_HOT_SPI.c
** 文件说明:NUC120助学板练习程序
* ...
Swallow_0322 发表于 2011-5-7 17:19


没有看到这句
DrvGPIO_InitFunction(E_FUNC_SPI1);
怎么在KEIL中就可以使用SPI功能呢?
我在IAR中,少了这句就不行。
?????
电子write_cai 发表于 2011-8-15 10:07 | 显示全部楼层
没有看到这句
DrvGPIO_InitFunction(E_FUNC_SPI1);
怎么在KEIL中就可以使用SPI功能呢?
我在IAR中,少了这句就不行。
?????
新好男孩 发表于 2011-8-10 17:29
这个GPIO端口使能SPI1功能.
 楼主| Swallow_0322 发表于 2011-8-15 10:53 | 显示全部楼层
To :电子write_cai
DrvSPI_Open(eDRVSPI_PORT1, eDRVSPI_MASTER, eDRVSPI_TYPE1, 32,FALSE);
//配置SPI1为主模式 TYPE1波形 32位传输

这个函数内有对SPI引脚功能的设置!

  1. else if(eSpiPort == eDRVSPI_PORT1)
  2. {
  3.   SYSCLK->APBCLK.SPI1_EN     =1;
  4.   SYS->IPRSTC2.SPI1_RST      =1;
  5.   SYS->IPRSTC2.SPI1_RST      =0;
  6.   SYS->GPCMFP.SPI1_SS0_MCLK  =1;
  7.   SYS->GPCMFP.SPI1_CLK     =1;
  8.   SYS->GPCMFP.SPI1_MISO0    =1;
  9.   SYS->GPCMFP.SPI1_MOSI0     =1;
  10.   SYS->GPBMFP.TM1_SS11       =1;
  11.   SYS->ALTMFP.PB9_S11        =1;
  12. }
hotpower 发表于 2011-8-15 10:56 | 显示全部楼层
学习某个外设模块的重点就是其初始化的设置过程及次序。
huzaizai007 发表于 2012-3-6 14:37 | 显示全部楼层
菜鸟求解
代码305行,读取设备ID函数SPI_ReadMidDid(void)中,在发送完24位的地址0x000000后,为什么还要发送16位的数据0x0000?
我注释掉后发送的设备ID不正确,W25Q16BV手册里没要求这步啊……
qdsubacnc 发表于 2012-3-6 14:57 | 显示全部楼层
帮楼主顶顶,有高手的帮忙解决一下啊
 楼主| Swallow_0322 发表于 2012-3-7 13:45 | 显示全部楼层
菜鸟求解
代码305行,读取设备ID函数SPI_ReadMidDid(void)中,在发送完24位的地址0x000000后,为什么还要发送16位的数据0x0000?
我注释掉后发送的设备ID不正确,W25Q16BV手册里没要求这步啊…… ...
huzaizai007 发表于 2012-3-6 14:37


发送16位的数据0x00是让SPI主设备发出16个脉冲,从而使主设备接收8位的Manufacturer ID和 Deveice ID!然后再通过库函数DrvSPI_DumpRxRegister读SPI总线接收数据。【个人理解,仅供参考】
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:播种一种行为,收获一种习惯;播种一种习惯,收获一种性格;播种一种性格,收获一种人生!

121

主题

1393

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:播种一种行为,收获一种习惯;播种一种习惯,收获一种性格;播种一种性格,收获一种人生!

121

主题

1393

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部