[求助] stm8l151C6 RC522 物理SPI没有SCK时钟

lmy11224433   2018-3-2 15:04 楼主
调试好几天了,在网上试了好多方法还是不通,希望有大神给看下到底代码写的对不对,大家往下看: 硬件连接: 使用的单片机为stm8l151C6,物理SPI和一个RC522芯片进行连接 PB4:NSS片选 PB5:SCK PB6:MOSI PB7:MISO PC4:RST(复位) PD6:pwr(电源,自己为低功耗设计) 问题: 物理SPI初始化使能之后一直写数据,用示波器检测SCK引脚时钟,发现没有时钟信号 程序一直卡在while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET) 模拟SPI通信没有问题 代码如下:
  1. void main(void)
  2. {
  3. hardware_init();
  4. //enableInterrupts();
  5. while (1)
  6. {
  7. // ReadRawRC(0x05);
  8. SPIWritebyte(0xAA);
  9. // BSP_RFID_WriteRegister(CommandReg,0xAA);
  10. // gpio_set_low(PORTB, PIN5);
  11. // gpio_set_high(PORTB, PIN5);
  12. }
  13. }
  14. void hardware_init(void)
  15. {
  16. u8 rv = 0;
  17. u8 ctrl_reg = 0, ver_reg = 0;
  18. // gpio_set_high(PORTD, PIN7);
  19. // system clock init
  20. sysclk_init_hsi(CLK_SYSCLKDiv_1);
  21. //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
  22. /* Select HSE as system clock source */
  23. // CLK_SYSCLKSourceSwitchCmd(ENABLE);
  24. // CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSE);
  25. /*High speed external clock prescaler: 1*/
  26. // CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
  27. // com load configuration & init
  28. com_load_config(com_cfg, 1);
  29. com_init(COM1, 2400, USART_WordLength_9b, USART_StopBits_1, USART_Parity_Even, USART_Mode_All, ENABLE, 0);
  30. com_recv_init(COM1);
  31. /* Check if the system has resumed from IWDG reset */
  32. if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)
  33. {
  34. /* Clear IWDGF Flag */
  35. RST_ClearFlag(RST_FLAG_IWDGF);
  36. printf("RST_FLAG_IWDGF\r\n");
  37. }
  38. // rtc init
  39. rtc_init();
  40. BSP1_RFID_LoadConfig(&rfid_config); //加载管脚配置
  41. CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);
  42. GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_High_Fast); //NSS片选
  43. GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast); //SCK
  44. GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast); //MOSI
  45. //主机模式,配置为输入
  46. GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT); //MISO
  47. BSP1_RFID_PowerOn(); //给RC522芯片上电
  48. //BSP1_RFID_PowerOff();
  49. SPI_DeInit(SPI1);
  50. SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_8, SPI_Mode_Master,SPI_CPOL_Low, SPI_CPHA_1Edge,SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);
  51. //SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,SPI_CPOL_High, SPI_CPHA_2Edge,SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);
  52. SPI_Cmd(SPI1, ENABLE); /* 使能SPI */
  53. rv = BSP1_RFID_Reset(&ctrl_reg, &ver_reg); //和PcdReset库函数一模一样
  54. printf("ctrl_reg:%02X, ver_reg:%02X\r\n", ctrl_reg, ver_reg);
  55. if (rv != 0)
  56. {
  57. printf("rfid init error\r\n");
  58. }
  59. BSP_RFID_AntennaOff();
  60. delay_ms(1);
  61. BSP_RFID_AntennaOn();
  62. BSP_RFID_ConfigISOType('A'); //针对ISO14443A型卡进行初始化
  63. return;
  64. }
  65. /*! \brief
  66. * rc522 reset
  67. * \return
  68. * MI_OK - success
  69. * MI_ERR - failure
  70. */
  71. char BSP1_RFID_Reset(u8 *ctrl_reg, u8 *version)
  72. {
  73. unsigned char val = 0;
  74. /* set rc522 rst to push pull output state , and set it to 0 */
  75. BSP_GPIO_Init(rfid_config_handler->rst.port, rfid_config_handler->rst.pin, GPIO_Mode_Out_PP_Low_Fast);
  76. // /* set rs522 nss to push pull output state, and set it to 1, disable sck,mosi,miso pin */
  77. // BSP_GPIO_Init(rfid_config_handler->nss.port, rfid_config_handler->nss.pin, GPIO_Mode_Out_PP_High_Fast);
  78. // /* set rc522 sck to push pull output state, and set it to 1 */
  79. // BSP_GPIO_Init(rfid_config_handler->sck.port, rfid_config_handler->sck.pin, GPIO_Mode_Out_PP_High_Fast);
  80. // /* set rc522 miso to push up input state*/
  81. // BSP_GPIO_Init(rfid_config_handler->miso.port, rfid_config_handler->miso.pin, GPIO_Mode_In_PU_No_IT);
  82. // //BSP_GPIO_Init(rfid_config_handler->miso.port, rfid_config_handler->miso.pin, GPIO_Mode_Out_PP_High_Fast);
  83. // /* set rc522 mosi to push pull output state, and set it to 1 */
  84. // BSP_GPIO_Init(rfid_config_handler->mosi.port, rfid_config_handler->mosi.pin, GPIO_Mode_Out_PP_High_Fast);
  85. delay_us(10);
  86. /* rs522 will be reset by setting rst to execute 1-0-1 sequence. */
  87. BSP_GPIO_SetHigh(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
  88. delay_us(10);
  89. BSP_GPIO_SetLow(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
  90. delay_us(10);
  91. BSP_GPIO_SetHigh(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
  92. delay_us(10);
  93. // RC522_RST_H();
  94. // delay_us(10);
  95. // RC522_RST_L();
  96. // delay_us(10);
  97. // RC522_RST_H();
  98. // delay_us(10);
  99. WriteRawRC(CommandReg,PCD_RESETPHASE);
  100. delay_us(10);
  101. WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363
  102. WriteRawRC(TReloadRegL,30);
  103. WriteRawRC(TReloadRegH,0);
  104. WriteRawRC(TModeReg,0x8D);
  105. WriteRawRC(TPrescalerReg,0x3E);
  106. WriteRawRC(TxAutoReg,0x40);//必须要
  107. val = ReadRawRC(ControlReg);
  108. if (val == 0xFF)
  109. {
  110. //printf("CtlReg:%02X\r\n", val);
  111. return MI_ERR;
  112. }
  113. *ctrl_reg = val;
  114. val = ReadRawRC(VersionReg);
  115. if (val == 0xFF)
  116. {
  117. //printf("Ver:%02X\r\n", val);
  118. return MI_ERR;
  119. }
  120. *version = val;
  121. //
  122. // BSP_RFID_AntennaOff();
  123. // BSP_RFID_ConfigISOType('A');
  124. // delay_ms(1);
  125. // BSP_RFID_AntennaOn();
  126. return MI_OK;
  127. }
  128. void SPIWritebyte(u8 Byte)
  129. {
  130. u16 retry=0;
  131. // u8 rv = 0;
  132. while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET)
  133. {
  134. retry++;
  135. if(retry>200)
  136. {
  137. return;
  138. }
  139. }
  140. SPI_SendData(SPI1, Byte);
  141. retry=0;
  142. //while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET)
  143. while (SPI_GetFlagStatus(SPI1, SPI_FLAG_BSY) == SET)
  144. {
  145. retry++;
  146. if(retry>400)return;
  147. }
  148. while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET)
  149. {
  150. retry++;
  151. if(retry>400)return;
  152. }
  153. SPI_ReceiveData(SPI1);
  154. }
希望大家踊跃参与! 本帖最后由 lmy11224433 于 2018-3-2 15:04 编辑

回复评论 (5)

stm8没有玩过,我想跟stm32差不多吧。

1、SPI_CPOL_Low, SPI_CPHA_1Edge这个一个是设置时钟极性,一个是设置时钟相位 这个一定要看RC522的datasheet中的时序图。
2、同理,还有SPI_FirstBit_MSB,这个也需要看所需要驱动的外设的datasheet;
点赞  2018-3-2 17:19
引用: huaiqiao 发表于 2018-3-2 17:19
stm8没有玩过,我想跟stm32差不多吧。

1、SPI_CPOL_Low, SPI_CPHA_1Edge这个一个是设置时钟极性,一个是 ...

这些我也看过了,是这样配置的
点赞  2018-3-2 17:59
引用: lmy11224433 发表于 2018-3-2 17:59
这些我也看过了,是这样配置的

CLK对应的IO的配置有检查过吗
你排除了硬件问题了没有?不要搞半天,硬件部分有问题了。。。。。。
我举个例子,有极个别的情况,硬件方面有IO就是输出不正常。我们一般将其设置成普通IO,然后输出高低电平来测试IO是否正常。
另外,硬件部分的设计 ,说不定也会影响IO哦,这个没有看过你的电路,只能说是有可能
点赞  2018-3-5 11:36
引用: huaiqiao 发表于 2018-3-5 11:36
CLK对应的IO的配置有检查过吗
你排除了硬件问题了没有?不要搞半天,硬件部分有问题了。。。。。。
我 ...

SCK引脚我用GPIO拉高和拉低函数试验过,是能控制该引脚的高低电平的
点赞  2018-3-7 09:36
引用: lmy11224433 发表于 2018-3-7 09:36
SCK引脚我用GPIO拉高和拉低函数试验过,是能控制该引脚的高低电平的

那就很奇怪啊。难道是CPU本身的问题?能放出来你的硬件电路图的截图么
点赞  2018-3-7 09:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复