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

2020-01-18 18:44发布

本帖最后由 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
}
//-------------------------------------------------------------------------------
  
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
24条回答
mdj-fish
1楼-- · 2020-01-20 16:55
标记,有需要再瞧瞧
tscyds
2楼-- · 2020-01-20 22:55
额,还是没有完全理解
xiaxquan
3楼-- · 2020-01-21 03:44
我勒个去,CC2530约定输入电压不得大于3.9V,这样直接连没有问题?
花是主人
4楼-- · 2020-01-21 08:01
学习一下!!
dianzixiehui
5楼-- · 2020-01-21 13:38
 精彩回答 2  元偷偷看……
chwe1112
6楼-- · 2020-01-21 14:46
赞一个,正在学习这方面的知识

一周热门 更多>