调试好几天了,在网上试了好多方法还是不通,希望有大神给看下到底代码写的对不对,大家往下看:
硬件连接:
使用的单片机为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通信没有问题
代码如下:
- void main(void)
- {
- hardware_init();
- //enableInterrupts();
- while (1)
- {
- // ReadRawRC(0x05);
- SPIWritebyte(0xAA);
- // BSP_RFID_WriteRegister(CommandReg,0xAA);
- // gpio_set_low(PORTB, PIN5);
- // gpio_set_high(PORTB, PIN5);
- }
- }
- void hardware_init(void)
- {
- u8 rv = 0;
- u8 ctrl_reg = 0, ver_reg = 0;
-
- // gpio_set_high(PORTD, PIN7);
- // system clock init
- sysclk_init_hsi(CLK_SYSCLKDiv_1);
- //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
- /* Select HSE as system clock source */
- // CLK_SYSCLKSourceSwitchCmd(ENABLE);
- // CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSE);
- /*High speed external clock prescaler: 1*/
- // CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
-
- // com load configuration & init
- com_load_config(com_cfg, 1);
- com_init(COM1, 2400, USART_WordLength_9b, USART_StopBits_1, USART_Parity_Even, USART_Mode_All, ENABLE, 0);
- com_recv_init(COM1);
-
- /* Check if the system has resumed from IWDG reset */
- if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)
- {
- /* Clear IWDGF Flag */
- RST_ClearFlag(RST_FLAG_IWDGF);
- printf("RST_FLAG_IWDGF\r\n");
- }
-
- // rtc init
- rtc_init();
-
- BSP1_RFID_LoadConfig(&rfid_config); //加载管脚配置
- CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);
- GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_High_Fast); //NSS片选
- GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast); //SCK
- GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast); //MOSI
- //主机模式,配置为输入
- GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT); //MISO
-
- BSP1_RFID_PowerOn(); //给RC522芯片上电
- //BSP1_RFID_PowerOff();
-
- SPI_DeInit(SPI1);
- 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);
- //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);
- SPI_Cmd(SPI1, ENABLE); /* 使能SPI */
-
- rv = BSP1_RFID_Reset(&ctrl_reg, &ver_reg); //和PcdReset库函数一模一样
- printf("ctrl_reg:%02X, ver_reg:%02X\r\n", ctrl_reg, ver_reg);
- if (rv != 0)
- {
- printf("rfid init error\r\n");
- }
- BSP_RFID_AntennaOff();
- delay_ms(1);
- BSP_RFID_AntennaOn();
- BSP_RFID_ConfigISOType('A'); //针对ISO14443A型卡进行初始化
- return;
- }
- /*! \brief
- * rc522 reset
- * \return
- * MI_OK - success
- * MI_ERR - failure
- */
- char BSP1_RFID_Reset(u8 *ctrl_reg, u8 *version)
- {
- unsigned char val = 0;
- /* set rc522 rst to push pull output state , and set it to 0 */
- BSP_GPIO_Init(rfid_config_handler->rst.port, rfid_config_handler->rst.pin, GPIO_Mode_Out_PP_Low_Fast);
- // /* set rs522 nss to push pull output state, and set it to 1, disable sck,mosi,miso pin */
- // BSP_GPIO_Init(rfid_config_handler->nss.port, rfid_config_handler->nss.pin, GPIO_Mode_Out_PP_High_Fast);
- // /* set rc522 sck to push pull output state, and set it to 1 */
- // BSP_GPIO_Init(rfid_config_handler->sck.port, rfid_config_handler->sck.pin, GPIO_Mode_Out_PP_High_Fast);
- // /* set rc522 miso to push up input state*/
- // BSP_GPIO_Init(rfid_config_handler->miso.port, rfid_config_handler->miso.pin, GPIO_Mode_In_PU_No_IT);
- // //BSP_GPIO_Init(rfid_config_handler->miso.port, rfid_config_handler->miso.pin, GPIO_Mode_Out_PP_High_Fast);
- // /* set rc522 mosi to push pull output state, and set it to 1 */
- // BSP_GPIO_Init(rfid_config_handler->mosi.port, rfid_config_handler->mosi.pin, GPIO_Mode_Out_PP_High_Fast);
- delay_us(10);
- /* rs522 will be reset by setting rst to execute 1-0-1 sequence. */
- BSP_GPIO_SetHigh(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
- delay_us(10);
- BSP_GPIO_SetLow(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
- delay_us(10);
- BSP_GPIO_SetHigh(rfid_config_handler->rst.port, rfid_config_handler->rst.pin);
- delay_us(10);
- // RC522_RST_H();
- // delay_us(10);
- // RC522_RST_L();
- // delay_us(10);
- // RC522_RST_H();
- // delay_us(10);
- WriteRawRC(CommandReg,PCD_RESETPHASE);
- delay_us(10);
- WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363
- WriteRawRC(TReloadRegL,30);
- WriteRawRC(TReloadRegH,0);
- WriteRawRC(TModeReg,0x8D);
- WriteRawRC(TPrescalerReg,0x3E);
- WriteRawRC(TxAutoReg,0x40);//必须要
- val = ReadRawRC(ControlReg);
- if (val == 0xFF)
- {
- //printf("CtlReg:%02X\r\n", val);
- return MI_ERR;
- }
-
- *ctrl_reg = val;
- val = ReadRawRC(VersionReg);
- if (val == 0xFF)
- {
- //printf("Ver:%02X\r\n", val);
- return MI_ERR;
- }
-
- *version = val;
- //
- // BSP_RFID_AntennaOff();
- // BSP_RFID_ConfigISOType('A');
- // delay_ms(1);
- // BSP_RFID_AntennaOn();
-
- return MI_OK;
- }
- void SPIWritebyte(u8 Byte)
- {
- u16 retry=0;
- // u8 rv = 0;
-
- while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET)
- {
- retry++;
- if(retry>200)
- {
- return;
- }
- }
- SPI_SendData(SPI1, Byte);
- retry=0;
- //while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET)
- while (SPI_GetFlagStatus(SPI1, SPI_FLAG_BSY) == SET)
- {
- retry++;
- if(retry>400)return;
- }
- while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET)
- {
- retry++;
- if(retry>400)return;
- }
- SPI_ReceiveData(SPI1);
- }
复制代码
|
把外设去掉,单独用了测试函数测试一下看是否有信号
评分
查看全部评分
我其他功能全部都没有初始化,就用了SPI,这样是不是就能排除这个复用的冲突?
请参考固件库的样例程序“SPI_FLASH”
这里面的单字节发送是这样写的:
没看来跟你的程序有本质的区别。
评分
查看全部评分
是的,我也看这个固件库里面flash的例子了,但是我的程序主函数里面什么都没有初始化,只做了SPI初始化,while里面一直在写数据,但是就是没有SCK时钟,也是很郁闷,如果用模拟SPI调试的话就没问题