OpenEdv-开源电子网

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

SPI 模拟失败,似乎世界末日到了

[复制链接]

24

主题

89

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2012-8-29
在线时间
3 小时
发表于 2012-12-22 19:23:10 | 显示全部楼层 |阅读模式
由于适配的无线模块是采用三线制SPI通信(片选信号SCS,时钟SCK,数据输入输出SDIO),跟平常在stm32下标准的SPI有显著差异。


模拟三线制SPI管脚定义:
A.4 输出    =NSS=SCS  (片选信号)
A.5 输出    =SCK      (时钟信号)   
A.6 输出输入=SDIO  (数据收发)

其它关联管脚定义:
A.7 上拉输入=1主,=0从(工作模式)
A.3 输入=GIO2   (无线模块反馈给MCU数据是否处理完毕)

数据收发管脚的相关函数:
SDIO_A6_Out_1()    复用推挽输出高电平
SDIO_A6_Out_0()    复用推挽输出低电平
SDIO_A6_Input()    上拉输入




GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  

// PA.3 ????????SPI??GIO2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
GPIO_Init(GPIOA, &GPIO_InitStructure);

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;    
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(GPIOA, &GPIO_InitStructure);

         GPIO_SetBits(GPIOA,GPIO_Pin_4);
         GPIO_SetBits(GPIOA,GPIO_Pin_5);  
         GPIO_SetBits(GPIOA,GPIO_Pin_6);





        void SDIO_A6_Input(void)
        {
         GPIO_InitTypeDef  GPIO_InitStructure;
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
         GPIO_Init(GPIOA, &GPIO_InitStructure);
        }


 
        void SDIO_A6_Out_1(void)
        {
                 GPIO_InitTypeDef  GPIO_InitStructure;
                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  
    
                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;    
                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                 GPIO_Init(GPIOA, &GPIO_InitStructure);

 
                 GPIO_SetBits(GPIOA,GPIO_Pin_6);
        }


        void SDIO_A6_Out_0(void)
        {
                 GPIO_InitTypeDef  GPIO_InitStructure;
                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
   
                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;    
                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                 GPIO_Init(GPIOA, &GPIO_InitStructure);

 
                 GPIO_ResetBits(GPIOA,GPIO_Pin_6);
        }
 



有四个核心函数:
        发送1个字节
        接收1个字节

        读无线模块的寄存器
        写无线模块的寄存器


问题现象: 1  发送出去的字节与原来的字节不一致;
               2  写入无线模块寄存器中的值与读出来的值不一致。


这四个函数的代码如下:
(里面注释掉的是原来8位单片机用的,据说测试通过了的)


整个工程的代码详见附件。

请求大仙指点迷津。不甚感激至于,送我手上还没用的诺亚方舟船票一张,哈哈,留着以后备用啊!!!



















/************************************************************************
**  ByteSend  发送1个字节
************************************************************************/
void ByteSend(u8 src)
{
    u8 i;

    for(i = 0; i < 8; i++)
    {
        if(src & 0x80) // 0x80 = 1000 0000
            //SDIO = 1; // #define SDIO   P3_1 //spi SDIO
            //SDIO = 1;//bit=1
SDIO_A6_Out_1();       
else
            //SDIO = 0;//bit=0
SDIO_A6_Out_0();  

        //_nop_();
Delay1ms(1);
        //SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_();
Delay1ms(1);
        //SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        src = src << 1;
    }
}

/************************************************************************
**  ByteRead 读1个字节
************************************************************************/
u8 ByteRead(void)
{
u8 i,tmp;

    //read data code
    //SDIO = 1;//sdio pull high // #define SDIO  3_1  //spi SDIO
    //SDIO = 1;//bit=1
GPIO_SetBits(GPIOA,GPIO_Pin_6);
    for(i = 0; i < 8; i++)
    {
        //if(SDIO)
SDIO_A6_Input();   //更改为输入
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6))

            tmp = (tmp << 1) | 0x01;
        else
            tmp = tmp << 1;

        //SCK = 1; // #define SCK   P3_0  //spi SCK
//SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_(); // 指令功能:不执行任何操作,常用于产生一个机器周期的时间延迟。  
Delay1ms(1);
//SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
    }
    return tmp;
}




/************************************************************************
**  A7108_WriteReg 写入寄存器
************************************************************************/
void A7108_WriteReg(u8 address, u16 dataWord)
{
    u8 i;

//SCS = 0; //使能读写
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
    address |= CMD_CTRLW; //#define CMD_CTRLW 0x00 //000x,xxxx control register write
    
// 写入地址 address:
for(i = 0; i < 8; i++)
    {
        if(address & 0x80)
            //SDIO = 1;//bit=1
//GPIO_SetBits(GPIOA,GPIO_Pin_6);
SDIO_A6_Out_1();
        else
            //SDIO = 0;//bit=0
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
SDIO_A6_Out_0();        
//SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_();
Delay1ms(1);
        //SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        address = address << 1;
    }
    //_nop_();
Delay1ms(1);

    //send data word
    for(i = 0; i < 16; i++)
    {
        if(dataWord & 0x8000)
            //SDIO = 1;//bit=1
//GPIO_SetBits(GPIOA,GPIO_Pin_6);
SDIO_A6_Out_1();
        else
            //SDIO = 0;//bit=0
//GPIO_ResetBits(GPIOA,GPIO_Pin_6); 
SDIO_A6_Out_0(); 

        //SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_();
Delay1ms(1);
        //SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        dataWord = dataWord<< 1;
    }
//SCS = 1; //失能读写
GPIO_SetBits(GPIOA,GPIO_Pin_4);
}



/************************************************************************
**  A7108_ReadReg   读寄存器
************************************************************************/
u16 A7108_ReadReg(u8 address)
{
    u8 i;
    u16 tmp;

//SCS = 0; //使能读写
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
    address |= CMD_CTRLR; // #define CMD_CTRLR 0x80 //100x,xxxx control register read
    
// 读取地址 address:
for(i = 0; i < 8; i++)
    {
        if(address & 0x80)
            //SDIO = 1;//bit=1
//GPIO_SetBits(GPIOA,GPIO_Pin_6);
//SDIO_A6_Input();
SDIO_A6_Out_1(); 

        else
            //SDIO = 0;//bit=0
//GPIO_ResetBits(GPIOA,GPIO_Pin_6); 
//SDIO_A6_Input(); 
SDIO_A6_Out_0(); 

        //_nop_();
Delay1ms(1);
        //SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_();
Delay1ms(1);
        //SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);

        address = address << 1;
    }
    //_nop_();
Delay1ms(1);
    //SDIO = 1;//bit=1
GPIO_SetBits(GPIOA,GPIO_Pin_6);
    //read data code
    for(i = 0; i < 16; i++)
    {
        //if(SDIO)
SDIO_A6_Input(); // 更改为输入状态
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6))
            tmp = (tmp << 1) | 0x01;
        else
            tmp = tmp << 1;

        //SCK = 1;
GPIO_SetBits(GPIOA,GPIO_Pin_5);
        //_nop_();
Delay1ms(1);
        //SCK = 0;
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
    }
//SCS = 1; //失能读写
GPIO_SetBits(GPIOA,GPIO_Pin_4);
return tmp;
}








厂家给的参考代码.pdf

513.84 KB, 下载次数: 274

Mini_RF_V002.rar

6.87 MB, 下载次数: 113

8位机 参考工程__A7108双向测试.rar

67.01 KB, 下载次数: 263

A7108_Datasheet_v0.7_SimpleChinese.pdf

865.54 KB, 下载次数: 281

我白天是个程序员,晚上就是个有抱负的演员。住在天朝的魔都,有条同名的狗......
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-19 14:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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