搜索
bottom↓
回复: 24

不同电平类型单片机之间的SPI通信

[复制链接]

出0入0汤圆

发表于 2012-10-2 20:41:08 | 显示全部楼层 |阅读模式
本帖最后由 xxguo 于 2012-10-2 20:50 编辑

现有STC12C5616和CC2530两个单片机。需要两个单片机SPI通信(5616为master,2530为slaver),请问现在有哪些需要注意的问题呢?
我已经实现5616和5616之间的SPI以及2530与2530之间的SPI通信。但是交叉之后就是没有反应,不知道可能是哪里的问题呢?
/*******************************************************************************
date   : 2010/08/29
writer :on the way..

Port   :P0_2,P0_3,P0_4,P0_5    这四个端口是用于UART0外设配置
         P1_0,P1_1            这两个端口是LED1和LED2
         P1_4,P1_5,P1_6,P1_7    这四个端口用于SPI通信
fuction:SPI_DMA中断方式通信
         从模式:配置好DMA的参数,使能DMA中断之后,开启DMA,如
      果串口1有接收到数据,这是会触发DMA,传输数据到指定的数组
      rxBufferSlave中,这里是可以将整个字符串直接传送过来的,最
      后在串口调试助手中显示on the way..
        
*******************************************************************************/
/*--------------------------------------------------------------------------------
    Master                 Slave
-------------          -------------
|           |          |           |
|P1_4   SSN |--------->|SSN    P1_4|
|           |          |           |
|P1_5   SCK |--------->|SCK    P1_5|
|           |          |           |
|P1_6   MOSI|--------->|MOSI   P1_6|
|           |          |           |
|P1_7   MISO|<---------|MISO   P1_7|
|           |          |           |
-------------          -------------
--------------------------------------------------------------------------------*/
// Slave Mode

#include <iocc2530.h>
#include "hal_cc8051.h"

#define LED1          P1_0
#define LED2          P1_1

#define LED_OFF 1
#define LED_ON  0

#define SSN       P1_4
#define N         13   // Length byte
char rxBufferSlave[13];//接收到的数据放到这个数组中
BOOL sDataReceived;    //接收数据标志位
/******************************************************************************
* @fn  init_port
*
* @brief
*     Initializes components IO port application example.
*
* Parameters:
*
* @param  void
*
* @return void
*
******************************************************************************/
void init_port(void)
{
   IO_FUNC_PORT_PIN(1, 0, IO_FUNC_GIO);    //将P1_0设置为普通的IO口
   IO_DIR_PORT_PIN(1, 0, IO_OUT);          //设置为输出
   
   IO_FUNC_PORT_PIN(1, 1, IO_FUNC_GIO);    //将P1_1设置为普通的IO口
   IO_DIR_PORT_PIN(1, 1, IO_OUT);          //设置为输出
   
   PERCFG |= 0x02;        // PERCFG.U1CFG = 1
   P1SEL |= 0xF0;         // P1_7, P1_6, P1_5, and P1_4 are peripherals
   
}

void init_Baudrate(void)
{
  // a 32 MHz crystal,
  // max baud rate = 32 MHz / 8 = 4 MHz.  
  U1BAUD = 0x00;   // BAUD_M = 0
  U1GCR |= 0x11;   // BAUD_E = 17
}
/******************************************************************************
* @fn  initUART
*
* @brief
*      Initializes components for the UART application example.
*
* Parameters:
*
* @param  void
*
* @return void
*
******************************************************************************/
void initUART(void)
{
   // Setup for UART0
   IO_PER_LOC_UART0_AT_PORT0_PIN2345();//将端口0的2345设置为外设
                  
   //这里的串口0设置为:波特率57600,没有校验位,8位数据,1位停止位,
   UART_SETUP(0, 57600, HIGH_STOP);    //设置串口
}
/*******************************************************************************
* @fn          main
*
* @brief      
*
* @param       none
*
* @return      none
*******************************************************************************/
void main(void)
{
  uint8 i;
  halMcuInit();     //设置时钟源32MHZ
  init_port();      //初始化端口
  init_Baudrate();  //初始化波特率
  initUART();       //初始化UART
  
  // SPI Slave Mode
  U1CSR &= ~0x80;   
  U1CSR |= 0x20;
  
  // Configure phase, polarity, and bit order
  U1GCR |= 0xC0;   // CPOL = CPHA = 1
  U1GCR &=~0x20;    // ORDER = 1
  
  // 1. Clear interrupt flags
  // For pulsed or edge shaped interrupt sources one should clear the CPU interrupt
  // flag prior to clearing the module interrupt flag
  TCON &= ~0x80;
  
  // 2. Set individual interrupt enable bit in the peripherals SFR, if any
  
  // 3. Set the corresponding individual, interrupt enable bit in the IEN0, IEN1, or
  // IEN2 registers to 1
  URX1IE = 1;
  
  
  // SPI Slave
  //-------------------------------------------------------------------------------
  DMA_DESC  dmaConfigRx;
  
  SET_WORD(dmaConfigRx.SRCADDRH, dmaConfigRx.SRCADDRL, &X_U1DBUF);
  SET_WORD(dmaConfigRx.DESTADDRH, dmaConfigRx.DESTADDRL, rxBufferSlave);
  dmaConfigRx.VLEN      = 0;  // Transfer number of bytes commanded by n, + 1
  SET_WORD(dmaConfigRx.LENH, dmaConfigRx.LENL, N + 1); //LEN = nmax + 1
  dmaConfigRx.WORDSIZE  = 0;  // Each transfer is 8 bits
  dmaConfigRx.TRIG      = 17; // Use URX1 trigger 17
  dmaConfigRx.TMODE     = 0;  // One byte transferred per trigger event 0
  dmaConfigRx.SRCINC    = 1;  // Keep the same source addr. for all transfers 0
  dmaConfigRx.DESTINC   = 0;  // Increase dest. addr. by 1 between transfers 1
  dmaConfigRx.IRQMASK   = 1;  // Allow IRCON.DMAIF to be asserted when the transfer 1
  // count is reached
  dmaConfigRx.M8        = 0;  // Use all 8 bits of first byte in source data to
  // determine the transfer count
  dmaConfigRx.PRIORITY  = 2;  // DMA memory access has high priority
  
  // Save pointer to the DMA config. struct into DMA ch. 0 config. registers
  SET_WORD(DMA0CFGH, DMA0CFGL, &dmaConfigRx);
  //-------------------------------------------------------------------------------
  
  //-------------------------------------------------------------------------------
  // 1. Clear interrupt flags
  // For pulsed or edge shaped interrupt sources one should clear the CPU interrupt
  // flag prior to clearing the module interrupt flag
  DMAIF = 0;          //清除DMA中断标志位
  DMAIRQ &= ~0x01;   
  
  // 2. Set individual interrupt enable bit in the peripherals SFR, if any
  // No flag for the DMA (Set in the DMA struct (IRQMASK = 1))
  
  // 3. Set the corresponding individual, interrupt enable bit in the IEN0, IEN1, o
  // IEN2 registers to 1
  DMAIE = 1;  //使能DMA中断
  
  // 4. Enable global interrupt
  EA = 1;     //使能总中断
  //-------------------------------------------------------------------------------
  
  //-------------------------------------------------------------------------------
  DMAARM = 0x01;   //使得DMA通道0处于准备好的状态,如果有数据接收到,就会执行中断语句
  
  while (1)  
  {
    if (sDataReceived)
    {
      sDataReceived = FALSE; // All 10 bytes are received
      for(i=0;i<sizeof(rxBufferSlave)+1;i++)
      {
        U0DBUF = rxBufferSlave;
        while(UTX0IF == 0);    //等待发送完毕
        UTX0IF = 0;
      }
    }
  }  
}


#pragma vector=DMA_VECTOR
  __interrupt void dma_IRQ(void)
{
    DMAIF = 0;               // Clear the CPU DMA interrupt flag
    DMAIRQ &= ~0x01;       // DMA channel 0 module interrupt flag
    sDataReceived = TRUE;    // All 10 bytes are received
}
//-------------------------------------------------------------------------------
  

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-10-2 20:42:10 | 显示全部楼层
本帖最后由 xxguo 于 2012-10-2 20:46 编辑

上面是用别人的2530的程序改的。下面的是5615的程序:
/* SPI主机程序,无中断串口接收并用SPI发送---------------------------------------
*硬件:STC12C5616,晶振12MHZ
*程序名称:main.c
*作者    :UESTC-35
*日期    :7/17/2011
连接方式 :三线连接
        主单片机 I/O 口         I/O 口 从单片机
;
; +--------------+ MISO <-- 位流方向 MISO +--------------+
; | SPI             |<<-----------------|      SPI       |
; |8 位移位寄存器   |                   |8 位移位寄存器  |
; |                 |---------------->> | |              |
; +-------+------+ MOSI 位流方向 --> MOSI +-------^------+
; |                 |                   |                |
; |                 | SCLK         SCLK |                |
; +---------------------------->>------------------------+
--------------------------------------------------------------------*/
#include "reg51.h"
#define SPIF  ( SPSTAT & 0x80 )  //查询SPIF是否置位,SPIF不能进行位操作
/*通信端口设置-------------------------------------------------------*/

/**********************************************************************
定义寄存器
************************************************************************/
sfr       AUXR    =   0x8e;           //Auxiliary register

sfr       SPSTAT  =   0x84;           //SPI status register  1000 0100
//#define   SPIF        0x80            //SPSTAT.7
#define   WCOL        0x40            //SPSTAT.6

sfr       SPCTL   =   0x85;           //SPI control register 1000 0101  master  SPI禁止 MSB先发 主模式  。。。16分频
#define   SSIG        0x80            //SPCTL.7
#define   SPEN        0x40            //SPCTL.6
#define   DORD        0x20            //SPCTL.5
#define   MSTR        0x10            //SPCTL.4
#define   CPOL        0x08            //SPCTL.3
#define   CPHA        0x04            //SPCTL.2
#define   SPDHH       0x00            //CPU_CLK/4
#define   SPDH        0x01            //CPU_CLK/16
#define   SPDL        0x02            //CPU_CLK/64
#define   SPDLL       0x03            //CPU_CLK/128

sfr       SPDAT   =   0x86;           //SPI data register
/////////////////////////////////////////////////////////////////////
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS   = P1^4;
unsigned char UART_SendData=0;
unsigned char UART_RecData=0;
unsigned char SPI_RecData=0;
void Init_System();
void Init_UART();
void Init_SPI();
unsigned char SPI_SendByte(unsigned char SPI_SendData);
void UART_SendByte(unsigned char UART_Send);
/*---------------------------------------------------------
*函数名:main
*函数功能:系统初始化
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void main()
{
        Init_System();
        while(1)           
        {
                /*  查询UART接收信号 ----------------------------------*/
                while(!RI);     //查看串口是否接收到数据
                {
                        RI=0;               //当接收到数据后,清除接收中断标志
                        UART_RecData=SBUF;   //读入数据
                        UART_SendData=SPI_SendByte(UART_RecData);//将收到的数据由SPI发送出去,又接收回来
//                        UART_SendByte(UART_SendData);
                }
        }
}
/*---------------------------------------------------------
*函数名:Init_System
*函数功能:系统初始化
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_System()
{
        Init_UART();
        Init_SPI();
}
/*---------------------------------------------------------
*函数名:Init_UART
*函数功能:串口初始化,无中断方式
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_UART()
{
        TMOD=0x20;//设置定时器1为工作方式2
        AUXR|=0x40;//不对定时器1分频,速度是普通单片机的12倍
        TH1=0xd9; //波特率为9600,晶振为12MHz
        TL1=0xd9;
        TR1=1;   //启动T1
        REN=1;   //串行允许位
        //  PCON=0x80;  //PCON寄存器的SMOD位置一,波特率提高一倍
        SM0=0;
        SM1=1;   //串行方式1
        // ES=1;    //中断接收则开串口中断,查询接收则关闭此句
}
/*---------------------------------------------------------
*函数名:Init_SPI
*函数功能:SPI初始化,SPI的工作方式,不使用SPI中断方式
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_SPI()
{
        SPCTL = 0xfd;//CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能
        SPSTAT = 0xc0;//SPDAT.7和SPDAT.6写11,可以将中断标志清零。注意是写1才清零
}
/*---------------------------------------------------------
*函数名:SPI_SendByte
*函数功能:SPI发射接收一体程序
*输入参数:SPI_SendData,经主机发给从机的数据
*返回参数:从机发给主机的数据
----------------------------------------------------------*/
unsigned char SPI_SendByte(unsigned char SPI_SendData)
{
        SS=0;
        SPDAT= SPI_SendData; //将串口接收的数据装入SPI数据寄存器
        while(!SPIF);//等待发送完毕               
        SS=1;
        SPSTAT = 0xc0; //清除中断标志,和写冲突标志,注意是对应位写1才能清零
        SPI_RecData = SPDAT;
        return  SPI_RecData;
}
/*---------------------------------------------------------
*函数名:UART_SendByte
*函数功能:串口发送
*输入参数:UART_Send
*返回参数:无
----------------------------------------------------------*/
void UART_SendByte(unsigned char UART_Send)
{
        TI = 0;            //清除发送SBUF空标志
        SBUF =  UART_Send; //写入SBUF
        while (!TI);       //等待发送完毕
        TI = 0;            //清除发送SBUF空标志
}

出0入0汤圆

 楼主| 发表于 2012-10-2 20:45:43 | 显示全部楼层
5615的作为master有部分功能是不需要的已经屏蔽。现在我的想法是电脑串口发数据到5615(master)然后5615通过SPI把数据发给CC2530,之后CC2530通过串口把数据发到电脑终端上面。但是现在的现象是,电脑可以吧数据发到5615,然后5615的SCK引脚上有时钟脉冲,MOSI上也有数据,但是后面的单片机就是没有反应。不知道是为什么呢?是不是两个单片机之间的电平类型不一致呢?

出0入0汤圆

 楼主| 发表于 2012-10-2 20:53:32 | 显示全部楼层
本帖最后由 xxguo 于 2012-10-2 20:55 编辑

CC2530数据手册~

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2012-10-2 20:59:01 | 显示全部楼层
5616的数据手册太大貌似上传不了~~~

出0入0汤圆

 楼主| 发表于 2012-10-2 22:49:53 | 显示全部楼层
bug不知道怎么搞啊~~求指教~~~

出0入0汤圆

发表于 2012-10-2 23:00:37 | 显示全部楼层
这两种单片机都没用过,但如果是电平不同的话,应该增加一个电平转换芯片啊。我以前用DSP的时候要控制12864也要加个电平转换芯片。

出0入0汤圆

 楼主| 发表于 2012-10-2 23:11:42 | 显示全部楼层
tony90 发表于 2012-10-2 23:00
这两种单片机都没用过,但如果是电平不同的话,应该增加一个电平转换芯片啊。我以前用DSP的时候要控制12864 ...

一个是5v的一个是3.3V的,非要加那个吗?

出0入0汤圆

发表于 2012-10-2 23:43:44 | 显示全部楼层
这是肯定滴,5v转3.3v的好像叫245吧

出0入0汤圆

 楼主| 发表于 2012-10-3 15:33:13 | 显示全部楼层
问题已经解决了,发上来大家瞧瞧~~~
功能   : STC12C5616 与 CC2530 单片机之间进行SPI通信,交换部分数据。
         从串口调试助手把一个八位的数据 发到Master上,Master接收到数据之后,通过SPI把数据发送给Slaver。与此同时Slaver直接又把另一组数据转发给Master,然后Master把接收到的数据发给上位机。然后Slaver把从Master那里接受来的数据发送到另一个串口调试助手!

Master : STC12C5616
Slaver : CC2530
连接:

    Master                 Slave
-----------------------------------------------------
|                  |            |                   |
|P1_4   SSN   |--------->| SSN    P1_4  |
|                  |           |                    |
|P1_7   SCK   |--------->| SCK    P1_5  |
|                  |            |                   |
|P1_5   MOSI |--------->| MOSI   P1_6 |
|                  |            |                   |
|P1_6   MISO |<---------| MISO   P1_7 |
|                  |            |                   |
-----------------------------------------------------

注意事项:虽然两种单片机之间的逻辑电平不一致,但是5V的作为主机,3.3V的作为从机,并不影响,依然可以正常通信。
          但是记得,两个单片机之间要公地!!!

出0入0汤圆

 楼主| 发表于 2012-10-3 15:34:50 | 显示全部楼层
本帖最后由 xxguo 于 2012-10-3 15:37 编辑

Master 依然不变



#include "reg51.h"
#define SPIF  ( SPSTAT & 0x80 )  //查询SPIF是否置位,SPIF不能进行位操作
/*通信端口设置-------------------------------------------------------*/

/**********************************************************************
定义寄存器
************************************************************************/
sfr       AUXR    =   0x8e;           //Auxiliary register

sfr       SPSTAT  =   0x84;           //SPI status register  1000 0100
//#define   SPIF        0x80            //SPSTAT.7
#define   WCOL        0x40            //SPSTAT.6

sfr       SPCTL   =   0x85;           //SPI control register 1000 0101  master  SPI禁止 MSB先发 主模式  。。。16分频
#define   SSIG        0x80            //SPCTL.7
#define   SPEN        0x40            //SPCTL.6
#define   DORD        0x20            //SPCTL.5
#define   MSTR        0x10            //SPCTL.4
#define   CPOL        0x08            //SPCTL.3
#define   CPHA        0x04            //SPCTL.2
#define   SPDHH       0x00            //CPU_CLK/4
#define   SPDH        0x01            //CPU_CLK/16
#define   SPDL        0x02            //CPU_CLK/64
#define   SPDLL       0x03            //CPU_CLK/128

sfr       SPDAT   =   0x86;           //SPI data register
/////////////////////////////////////////////////////////////////////
sbit SCLK = P1^7;
sbit MISO = P1^6;
sbit MOSI = P1^5;
sbit SS   = P1^4;
unsigned char UART_SendData=0;
unsigned char UART_RecData=0;
unsigned char SPI_RecData=0;
void Init_System();
void Init_UART();
void Init_SPI();
unsigned char SPI_SendByte(unsigned char SPI_SendData);
void UART_SendByte(unsigned char UART_Send);
void delay_ms(unsigned int s);
/*---------------------------------------------------------
*函数名:main
*函数功能:系统初始化
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void main()
{
        Init_System();
        while(1)           
        {
                /*  查询UART接收信号 ----------------------------------*/
                while(!RI);     //查看串口是否接收到数据
                {
                        RI=0;               //当接收到数据后,清除接收中断标志
                        UART_RecData=SBUF;   //读入数据
                        UART_SendData=SPI_SendByte(UART_RecData);//将收到的数据由SPI发送出去,又接收回来
                        UART_SendByte(UART_SendData);
                }
        }
}
/*---------------------------------------------------------
*函数名:Init_System
*函数功能:系统初始化
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_System()
{
        Init_UART();
        Init_SPI();
}
/*---------------------------------------------------------
*函数名:Init_UART
*函数功能:串口初始化,无中断方式
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_UART()
{
        TMOD=0x20;//设置定时器1为工作方式2
        AUXR|=0x40;//不对定时器1分频,速度是普通单片机的12倍
        TH1=0xd9; //波特率为9600,晶振为12MHz
        TL1=0xd9;
        TR1=1;   //启动T1
        REN=1;   //串行允许位
        //  PCON=0x80;  //PCON寄存器的SMOD位置一,波特率提高一倍
        SM0=0;
        SM1=1;   //串行方式1
        // ES=1;    //中断接收则开串口中断,查询接收则关闭此句
}
/*---------------------------------------------------------
*函数名:Init_SPI
*函数功能:SPI初始化,SPI的工作方式,不使用SPI中断方式
*输入参数:无
*返回参数:无
----------------------------------------------------------*/
void Init_SPI()
{
        SPCTL = 0xff;//CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能 1111 1111
        SPSTAT = 0xc0;//SPDAT.7和SPDAT.6写11,可以将中断标志清零。注意是写1才清零
}
/*---------------------------------------------------------
*函数名:SPI_SendByte
*函数功能:SPI发射接收一体程序
*输入参数:SPI_SendData,经主机发给从机的数据
*返回参数:从机发给主机的数据
----------------------------------------------------------*/
unsigned char SPI_SendByte(unsigned char SPI_SendData)
{
        SS=0;
        delay_ms(2);
        SPDAT= SPI_SendData; //将串口接收的数据装入SPI数据寄存器
        while(!SPIF);//等待发送完毕       
        delay_ms(2);       
        SS=1;
        SPSTAT = 0xc0; //清除中断标志,和写冲突标志,注意是对应位写1才能清零
        SPI_RecData = SPDAT;
        return  SPI_RecData;
}
/*---------------------------------------------------------
*函数名:UART_SendByte
*函数功能:串口发送
*输入参数:UART_Send
*返回参数:无
----------------------------------------------------------*/
void UART_SendByte(unsigned char UART_Send)
{
        TI = 0;            //清除发送SBUF空标志
        SBUF =  UART_Send; //写入SBUF
        while (!TI);       //等待发送完毕
        TI = 0;            //清除发送SBUF空标志
}  

void delay_ms(unsigned int s) //static
{
        unsigned int i;
        for(;s*12>0;s--)                                //STC12C5616  需要*12
                for(i=12000;i>0;i--);        //STC12C5616  需要*12
}

出0入0汤圆

 楼主| 发表于 2012-10-3 15:36:11 | 显示全部楼层
本帖最后由 xxguo 于 2012-10-3 15:41 编辑

Slaver 取消用DMA,直接用SPI收发数据就可以了~~~



// Slave Mode

#include <iocc2530.h>
#include "hal_cc8051.h"

#define LED1          P1_0
#define LED2          P1_1

#define LED_OFF 1
#define LED_ON  0

#define SSN       P1_4
/******************************************************************************
* @fn  init_port
*
* @brief
*     Initializes components IO port application example.
*
* Parameters:
*
* @param  void
*
* @return void
*
******************************************************************************/
void init_port(void)
{
   IO_FUNC_PORT_PIN(1, 0, IO_FUNC_GIO);    //将P1_0设置为普通的IO口
   IO_DIR_PORT_PIN(1, 0, IO_OUT);          //设置为输出
   
   IO_FUNC_PORT_PIN(1, 1, IO_FUNC_GIO);    //将P1_1设置为普通的IO口
   IO_DIR_PORT_PIN(1, 1, IO_OUT);          //设置为输出
   
   PERCFG |= 0x02;        // PERCFG.U1CFG = 1
   P1SEL |= 0xF0;         // P1_7, P1_6, P1_5, and P1_4 are peripherals
   
}

void init_Baudrate(void)
{
  // Set baud rate to max (system clock frequency / 8)
  // a 32 MHz crystal,
  // max baud rate = 32 MHz / 8 = 4 MHz.  
  U1BAUD = 0x00;   // BAUD_M = 0
  U1GCR |= 0x11;   // BAUD_E = 17
}
/******************************************************************************
* @fn  initUART
*
* @brief
*      Initializes components for the UART application example.
*
* Parameters:
*
* @param  void
*
* @return void
*
******************************************************************************/
void initUART(void)
{
   // Setup for UART0
   IO_PER_LOC_UART0_AT_PORT0_PIN2345();//将端口0的2345设置为外设
                  
   //这里的串口0设置为:波特率57600,没有校验位,8位数据,1位停止位,
   UART_SETUP(0, 57600, HIGH_STOP);    //设置串口
}
/*******************************************************************************
* @fn          main
*
* @brief      
*
* @param       none
*
* @return      none
*******************************************************************************/
void main(void)
{
  halMcuInit();// 选择32MHz晶体振荡器作为系统时钟源(主时钟源)//设置时钟源32MHZ
  init_port();      //初始化端口
  init_Baudrate();  //初始化波特率
  initUART();       //初始化UART

  // SPI Slave Mode
  U1CSR &= ~0x80;
  U1CSR |= 0x20;
  
  // Configure phase, polarity, and bit order
  U1GCR |= 0xC0;   // CPOL = CPHA = 1
  U1GCR &=~0x20;    // ORDER = 0 LSB First
  
  
//  LED1=LED_ON;      //灯亮表示进入接收状态
  
  
  char rxBufferSlave[1];
  char _RSSI[1];
  _RSSI[0]=0x13;
////////////////////////////////////////////////////////////////////////////////////////////////////////
//  unsigned char i;
/*  for (i = 0; i < sizeof(rxBufferSlave); i++)  
  {
    while (!U1RX_BYTE);
    U1RX_BYTE = 0;
    rxBufferSlave = U1DBUF;
    LED1=~LED1;
  }
  
   
  LED1=LED_OFF;     //灯灭表示数据已经传送完,接着在串口上显示
  
  for(i=0;i<sizeof(rxBufferSlave);i++)
  {
    U0DBUF = rxBufferSlave;
    while(UTX0IF == 0);    //等待发送完毕
    UTX0IF = 0;
  }*/
/////////////////////////////////////////////////////////////////////////////////////////////
  while(1)
  {
    while (!U1RX_BYTE);
    rxBufferSlave[0] = U1DBUF;
    U1DBUF=_RSSI[0];
//    U1RX_BYTE = 0;
    U0DBUF = rxBufferSlave[0];
    while(UTX0IF == 0);    //等待发送完毕
    UTX0IF = 0;
  }
  
}

出0入0汤圆

 楼主| 发表于 2012-10-3 15:43:21 | 显示全部楼层
然后关于SPI比较有参考性的就是摩托罗拉公司的SPI 规范协议了~~~

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2012-10-3 15:57:36 | 显示全部楼层
关于SPI的话就只有几点要注意的:
第一点就是:主从机的确定
主机一般由相关寄存器位直接配置就可以了。
例如STC12C5616: SPCTL = 0xff;//CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能 1111 1111

但是从机配置就麻烦一些。本身也可以采用如上面的主机配置的那种方式直接采用某些寄存器位就可以。但是还有一个关键的就是SS(P1^4)这个脚。对于主机这个脚没有什么用,但是对于从机
就有片选以及在写数据的时候有较大的影响。
对于单一的主从机:

直接在主机上选择一个GPIO去在适当的时候(后面会说)控制SS就可以了。
对于一主,多从的情况:

需要多个GPIO来选择哪一个从机来响应主机,与主机交换数据。

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2012-10-3 16:10:19 | 显示全部楼层
第二:在配置好主从机之后,关键的就是对于写数据的理解了
在SPI中,数据传输总是由主机启动的。在SPI使能的情况下,主机对SPI数据寄存器的写数据(直接赋值)操作将启动SPI时钟发生器和数据的传输。在数据写入SPDAT之后的半个SPI位时间后,数据将出现在MOSI脚。
同时对于从机,写数据的时候,主机必须对从机的SS(P1^4)脚拉低!!!
javascript:;

本帖子中包含更多资源

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

x

出0入0汤圆

 楼主| 发表于 2012-10-3 16:14:23 | 显示全部楼层
第三:就是关于主从机的时钟配置  CPOL  CPHA  要一致
第四:就是发送数据的顺序要一致MSB在前还是LSB在前

出0入0汤圆

 楼主| 发表于 2012-10-3 16:15:03 | 显示全部楼层
基本上这些注意到之后没就没有什么问题了,还是比较简单的~~

出0入0汤圆

发表于 2012-10-4 23:24:29 | 显示全部楼层
  想学习!

出0入0汤圆

发表于 2012-10-4 23:58:07 来自手机 | 显示全部楼层
标记,有需要再瞧瞧

出0入0汤圆

发表于 2012-10-5 07:40:15 | 显示全部楼层
标记,有需要再瞧瞧

出0入0汤圆

发表于 2013-3-14 17:02:29 | 显示全部楼层
额,还是没有完全理解

出0入0汤圆

发表于 2013-3-18 11:04:21 | 显示全部楼层
我勒个去,CC2530约定输入电压不得大于3.9V,这样直接连没有问题?

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-4-15 10:17:37 | 显示全部楼层
学习一下!!

出0入0汤圆

发表于 2014-4-2 19:14:43 | 显示全部楼层
赞一个

出0入0汤圆

发表于 2016-2-16 11:14:19 | 显示全部楼层
赞一个,正在学习这方面的知识
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-15 15:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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