OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5856|回复: 2

模拟SPI 遇到一些问题. 哪位路过又写过模拟SPI的大虾帮我看看?

[复制链接]

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2015-12-7
在线时间
59 小时
发表于 2015-12-11 23:03:28 | 显示全部楼层 |阅读模式
5金钱
学完了原子的SPI例程.   也通过NRF收到了我从51上发送的消息后.

我试着把51的模拟SPI搬过来试试,遇到了问题,请高人看看哪里出了问题..在这里仅贴出我认为可能存在错误的地方.   NRF地址那些都是ok的

/*模拟SPI端口输出输入定义*/
#define CE_H GPIOG->BSRRL = GPIO_Pin_2
#define CE_L GPIOG->BSRRH = GPIO_Pin_2
  
#define CSN_H GPIOG->BSRRL = GPIO_Pin_3
#define CSN_L GPIOG->BSRRH = GPIO_Pin_3

#define SCK_H GPIOG->BSRRL = GPIO_Pin_4
#define SCK_L GPIOG->BSRRH = GPIO_Pin_4

#define MOSI_H GPIOG->BSRRL = GPIO_Pin_5
#define MOSI_L GPIOG->BSRRH = GPIO_Pin_5

#define MISO_H GPIOG->BSRRL = GPIO_Pin_6
#define MISO_L GPIOG->BSRRH = GPIO_Pin_6

#define IRQ_H GPIOG->BSRRL = GPIO_Pin_7
#define IRQ_L GPIOG->BSRRH = GPIO_Pin_7

#define MOSI_read GPIOG->IDR  & GPIO_Pin_5
#define MISO_read GPIOG->IDR  & GPIO_Pin_6

/****************************************************************************************
  NRF24L01引脚口初始化
***************************************************************************************/
void NRF_GPIO_Config(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
 
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP; 
  GPIO_Init(GPIOG, &GPIO_InitStructure);
 
}
/****************************************************************************************
  NRF24L01初始化
***************************************************************************************/
void init_NRF24L01(void)
{
  CE_L;    // chip enable
  CSN_H;   // Spi  disable
  SCK_L;   //
 SPI_Write_Buf(NRF_WRITE_REG + TX_ADDR, (u8*)TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址 
 SPI_Write_Buf(NRF_WRITE_REG + RX_ADDR_P0, (u8*)RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
 SPI_RW_Reg(NRF_WRITE_REG + EN_AA, 0x01);      //  频道0自动 ACK应答允许 
 SPI_RW_Reg(NRF_WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21 
 SPI_RW_Reg(NRF_WRITE_REG + RF_CH, 0x6e);        //   设置信道工作为2.4GHZ,收发必须一致
 SPI_RW_Reg(NRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
 SPI_RW_Reg(NRF_WRITE_REG + RF_SETUP, 0x27);     //设置发射速率为1MB/S,发射功率为最大值+7dB,由于有X2401L功放,实际+21dbm输出
}
/****************************************************************************************************
函数:void SetRX_Mode(void)
功能:数据接收配置
****************************************************************************************************/
void SetRX_Mode(void)
{
 CE_L;
 SPI_RW_Reg(NRF_WRITE_REG + CONFIG2, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
 CE_H;
}
/****************************************************************************************************
  函数:uint SPI_RW(uint uchar)
  功能:NRF24L01的SPI写时序
***************************************************************************************************/
unsigned char SPI_RW(unsigned char ucharb)
{
 unsigned char bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)     // output 8-bit                 输出8位数据
    {
   if(ucharb & 0x80)                       // output 'uchar', MSB to MOSI  主机输出从机输入
   {
     MOSI_H;
   }
   else
   {
     MOSI_L;
   }
   ucharb = (ucharb << 1);               // shift next bit into MSB..     数据移动左移
   SCK_H;                             // Set SCK high..
   
   delay_us(12);
   
   if(MISO_read)
   {
    ucharb |= 0x01;               // capture current MISO bit      读MISO到 dat 最低位
   }
   else
   {    
    ucharb |= 0x00;
   }
    delay_us(12);
   
   SCK_L;                                  // ..then set SCK low again
    }
    return(ucharb);                       // return read uchar
}


我弄了没反应后,加了原子的
u8 NRF24L01_Check(void)
{
 u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
 u8 i;
 SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为10.5Mhz(24L01的最大SPI时钟为10Mhz)    
 NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. 
 NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 
 for(i=0;i<5;i++)if(buf!=0XA5)break;           
 if(i!=5)return 1;//检测24L01错误 
 return 0;   //检测到24L01



在usart输出上,这个一直都是输出1  检测错误.......    我感觉是不是MISO或者是SPI_RW哪里弄错了,感觉——》IDR那个也是可以的...求大神帮看看

最佳答案

查看完整内容[请看2#楼]

好吧,一直觉得SPI的程序没什么错误.   明明SPI的道理很简单... 搞了两天,日了狗...   一个是MISO要设置成输入嗯,#define MISO_Read GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8) 第二个,要设置成推挽输出!!!!!!开漏真是底裤都漏了..... void NRF_GPIO_Config(void) { GPIO_InitTypeDef  GPIO_InitStructure;   RCC_AHB1PeriphClockCmd(RCC_AHB ...
< 主啊,请你温柔的笑吧 >
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

26

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2015-12-7
在线时间
59 小时
 楼主| 发表于 2015-12-11 23:03:29 | 显示全部楼层
好吧,一直觉得SPI的程序没什么错误.   明明SPI的道理很简单... 搞了两天,日了狗...   一个是MISO要设置成输入嗯,#define MISO_Read GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)

第二个,要设置成推挽输出!!!!!!开漏真是底裤都漏了.....

void NRF_GPIO_Config(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN; 
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

// GPIO_ResetBits(GPIOB,GPIO_Pin_8);

}
< 主啊,请你温柔的笑吧 >
回复

使用道具 举报

8

主题

125

帖子

0

精华

高级会员

Rank: 4

积分
844
金钱
844
注册时间
2013-4-27
在线时间
120 小时
发表于 2015-12-12 09:41:13 | 显示全部楼层
1.读IDR要右移对应位数的吧
2.SPI两个数据线一发一收,为何定义了两个读管脚,看看读用到的管脚定义是否正确
3.检查SPI时序

先搞定SPI_RW_Reg函数再做下一步调试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 18:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表