打印

STM32 实现SPI简单通信配置

[复制链接]
12468|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
绿眼孤狼|  楼主 | 2011-1-20 11:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*******************************************************
说明:
       次程序成功实现SPI简单通信配置,能实现SPI1发送
数据,SPI2接收数据简单通信功能,仅供测试使用。
*******************************************************/
#include "stm32f10x_lib.h"
#include "stm32f10x_conf.h"
#include "ili9320.h"
/****************************/
#define  LCD_X_ADDR  190
#define  LCD_Y_ADDR  100

vu16  SPI_IDx  = 0; //Reveive Data
u16   SPI_ID_Temp = 0; //接收数据备份,用于判断接收到的数据是否发生变化
u16   SPI_ID[4];   //位显示数据
/********** 函数声明 *********/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void SPI_Configuration(void);
void Sys_Init(void);
void LCD_Print_Out(void);
/********** 系统初始化 ******************/
void Sys_Init(void)
{
#ifdef DEBUG
    debug();
#endif
     //----- 模块初始化配置 -------
     RCC_Configuration();
     NVIC_Configuration();
     GPIO_Configuration();
     SPI_Configuration();
      //--------- LCD -----------
     Lcd_Configuration();
     ili9320_Initializtion();
     ili9320_Clear(0);
     ili9320_PutChar(LCD_X_ADDR,     LCD_Y_ADDR, 0x30 + 0, 65535, 0);
}
/******* 主函数 **********/
int main(void)
{
     Sys_Init();
     while(1)
     {
           LCD_Print_Out();
     }
}
/******** 用于调试LCD显示数据界面 *********/
void LCD_Print_Out(void)
{
      //如果数据发生变化,则执行数据更新
     if(SPI_ID_Temp != SPI_IDx)
     {
          if(SPI_IDx >= 1000)
          {
               SPI_ID[0] = SPI_IDx  % 10;
               SPI_ID[1] = (SPI_IDx % 100) / 10;
               SPI_ID[2] = (SPI_IDx / 100) % 10;
               SPI_ID[3] = SPI_IDx  / 1000;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 65535, 0);
          }
          else if(SPI_IDx >= 100)
          {
               SPI_ID[0] = SPI_IDx  % 10;
               SPI_ID[1] = (SPI_IDx / 10) % 10;
               SPI_ID[2] = SPI_IDx  / 100;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0,     0);
         }
         else if(SPI_IDx >= 10)
         {
               SPI_ID[0] = SPI_IDx % 10;
               SPI_ID[1] = SPI_IDx / 10;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR,  0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR,  0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 0,     0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0,     0);
        }
        else
        {
               SPI_ID[0] = SPI_IDx % 10;
               ili9320_PutChar(LCD_X_ADDR,   LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 0, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 0, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0, 0);
         }
         SPI_ID_Temp = SPI_IDx;  //数据备份,为判断数据是否发生变化
    }
}
/**************************************************************************/
/**************************************************************************/
/****** 系统时钟配置函数 ********/
void RCC_Configuration(void)
{
      ErrorStatus  HSEStartUpStatus;

      RCC_DeInit();         //RCC system reset(for debug purpose)
      RCC_HSEConfig(RCC_HSE_ON);      //Enable HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp();  //Wait till HSE is ready
      if(HSEStartUpStatus == SUCCESS)
      {
            FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
            FLASH_SetLatency(FLASH_Latency_2);      //Set 2 Latency cycles
            RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock  = SYSCLK
            RCC_PCLK2Config(RCC_HCLK_Div2);  //APB2 clock = HCLK/2
            RCC_PCLK1Config(RCC_HCLK_Div4);  //APB1 clock = HCLK/4
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz
            RCC_PLLCmd(ENABLE);          //Enable PLL
            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  //Wait till PLL is ready  
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock source
            while(RCC_GetSYSCLKSource() != 0x08);  //Wait till PLL is used as system clock source
            //-----------------------------------------------------
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
                  | RCC_APB2Periph_SPI1, ENABLE); //GPIOD clock ENABLE
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //TIM2  clock ENABLE
      }
}
/****** 中断配置函数 ********/
void NVIC_Configuration(void)
{
      NVIC_InitTypeDef NVIC_InitStructure;

      //--- 在内存中进行调试 -----   
#ifdef VECT_TAB_RAM
      NIVC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
     //--- 在FLASH中进行调试 ----
#else
      NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif

      //---- 配置TIM2中断,并使能 -----
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
      NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      
      NVIC_Init(&NVIC_InitStructure);
    //------------------------------------
    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
}

/********** 通用I/O配置函数 ***************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------------------
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*****************************************************
函数名称:SPI_Configuration(void)
功能说明:SPI通信模块配置,配置SPI工作模式;
输入参数:无
返回值  :无
*****************************************************/
void SPI_Configuration(void)
{
   SPI_InitTypeDef SPI_InitStructure;
   //--------------------- SPI1 configuration ------------------
   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
   SPI_InitStructure.SPI_Mode   = SPI_Mode_Master;
   SPI_InitStructure.SPI_DataSize  = SPI_DataSize_16b;
   SPI_InitStructure.SPI_CPOL   = SPI_CPOL_Low;
   SPI_InitStructure.SPI_CPHA   = SPI_CPHA_2Edge;
   SPI_InitStructure.SPI_NSS   = SPI_NSS_Soft;
   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
   SPI_InitStructure.SPI_FirstBit    = SPI_FirstBit_MSB;
   SPI_InitStructure.SPI_CRCPolynomial  = 7;
   SPI_Init(SPI1, &SPI_InitStructure);
   //--------- SPI2 configuration ------------------
   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
   SPI_Init(SPI2, &SPI_InitStructure);
   //--------- Enable SPI1 TXE interrupt ------------
   SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
   //--------- Enable SPI2 RXNE interrupt -------------
   SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
   //----- Enable SPI2 ------
   SPI_Cmd(SPI2, ENABLE);
   //----- Enable SPI1 ----
   SPI_Cmd(SPI1, ENABLE);
}
/*************************************************/
#ifdef DEBUG
void assert_failed(u8 *file, u32 line)
{
   while(1)
  {}
}
#endif


/***********************************************************/
/***********************************************************/

#include "stm32f10x_it.h"
/****************************/
extern vu16  SPI_IDx;
/*********** TX发送中断服务子程序 *********************/
void SPI1_IRQHandler(void)
{
//-------- 发送数据 ----------
SPI_I2S_SendData(SPI1, 47);
}
/*********** RX接收中断服务子程序 ****************/
void SPI2_IRQHandler(void)
{
//------------- 接收数据 ------------
SPI_IDx = SPI_I2S_ReceiveData(SPI2);
}
沙发
selina1983| | 2011-1-20 11:28 | 只看该作者
不错  学习了

使用特权

评论回复
板凳
智达| | 2011-1-23 20:10 | 只看该作者
虽然,看不明白,也没打算开。
但是,还要挺一下楼主。
因为,这些LZ的资料很有可能会帮助其他人。

使用特权

评论回复
地板
berry2006| | 2011-1-24 17:19 | 只看该作者
楼主,有没有试过16位DMA传输啊?我使用的时候发现会有丢数据现象,楼主有兴趣试一下啊

使用特权

评论回复
5
gavin_li| | 2011-1-26 13:10 | 只看该作者
打算用SPI实现无线cc1101的通信。楼主用的是SPI1接口吗?

使用特权

评论回复
6
绿眼孤狼|  楼主 | 2011-1-27 15:24 | 只看该作者
5# gavin_li

我是使用SPI1发送,SPI2接收,从硬件上,直接把SPI1和SPI2对应的口连接起来进行通讯,这是比较简单的测试方式了。

使用特权

评论回复
7
绿眼孤狼|  楼主 | 2011-1-27 15:29 | 只看该作者
楼主,有没有试过16位DMA传输啊?我使用的时候发现会有丢数据现象,楼主有兴趣试一下啊
berry2006 发表于 2011-1-24 17:19

你的SPI使用DMA传输解决了吗?把你的测试程序也共享一下啊,我调了两天,没有成功。

使用特权

评论回复
8
kinbing| | 2011-2-8 11:11 | 只看该作者
有点难用

使用特权

评论回复
9
lixiaoxu2meng| | 2011-2-9 11:33 | 只看该作者
mark

使用特权

评论回复
10
kinbing| | 2011-2-9 18:38 | 只看该作者
不错,用库写的,就是方便看

使用特权

评论回复
11
xiaoma2562| | 2011-9-30 09:15 | 只看该作者
学习。

使用特权

评论回复
12
丑奴儿atl| | 2011-10-7 10:29 | 只看该作者
mark

使用特权

评论回复
13
xxx378087736| | 2011-12-1 13:39 | 只看该作者
学习了。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

19

帖子

1

粉丝