随着时间的推移,第一批收到光立方套件的网友们已经完成了焊接工作,开始了程序的编写与硬件检测的阶段。版主为了缩短STM32芯片程序开发的过程,节省由于软件问题带来的硬件检测异常,编写光立方硬件测试代码。现将源代码分享给大家。
第一部分:底层spi驱动配置与数据显示
BSP文件头文件
#define LAYERn 8 #define LAYER0_PIN GPIO_Pin_11 #define LAYER0_GPIO_PORT GPIOB #define LAYER0_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER1_PIN GPIO_Pin_10 #define LAYER1_GPIO_PORT GPIOB #define LAYER1_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER2_PIN GPIO_Pin_1 #define LAYER2_GPIO_PORT GPIOB #define LAYER2_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER3_PIN GPIO_Pin_0 #define LAYER3_GPIO_PORT GPIOB #define LAYER3_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER4_PIN GPIO_Pin_6 #define LAYER4_GPIO_PORT GPIOB #define LAYER4_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER5_PIN GPIO_Pin_7 #define LAYER5_GPIO_PORT GPIOB #define LAYER5_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER6_PIN GPIO_Pin_8 #define LAYER6_GPIO_PORT GPIOB #define LAYER6_GPIO_CLK RCC_APB2Periph_GPIOB #define LAYER7_PIN GPIO_Pin_9 #define LAYER7_GPIO_PORT GPIOB #define LAYER7_GPIO_CLK RCC_APB2Periph_GPIOB
BSP文件
/** * @brief called from main.c * @param * @retval * @date 2014-03-24 * @note */ void Bsp_Init(void) { SysClockInit(); Bsp_LayerInit(); Uart1Init(115200); HC595_Init(); } /** * @brief initial the sysclock, * @param * @retval * @date 2014-03-24 * @note */ static void SysClockInit(void) { /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/ /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if (HSEStartUpStatus == SUCCESS) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* PLLCLK = 12MHz * 6 = 72 MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6); /* 此处需要根据外部晶振的改变而改变 */ /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while(RCC_GetSYSCLKSource() != 0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ /* Go to infinite loop */ while (1) { } } } /** * @brief 初始化板载8层LED灯 * @param none * @retval none * @date 2014-04-27 * @note */ void Bsp_LayerInit(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(LAYER0_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = LAYER0_PIN | LAYER1_PIN | LAYER2_PIN | LAYER3_PIN | LAYER4_PIN | LAYER5_PIN | LAYER6_PIN | LAYER7_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LAYER0_GPIO_PORT, &GPIO_InitStructure); } /** * @brief 给某一层LED灯通电 * @param uint8_t lay * @retval * @date 2014-06-30 * @note */ void Bsp_LayerOn(uint8_t lay) { switch(lay) { case 0: { GPIO_SetBits(LAYER0_GPIO_PORT, LAYER0_PIN); break; } case 1: { GPIO_SetBits(LAYER1_GPIO_PORT, LAYER1_PIN); break; } case 2: { GPIO_SetBits(LAYER2_GPIO_PORT, LAYER2_PIN); break; } case 3: { GPIO_SetBits(LAYER3_GPIO_PORT, LAYER3_PIN); break; } case 4: { GPIO_SetBits(LAYER4_GPIO_PORT, LAYER4_PIN); break; } case 5: { GPIO_SetBits(LAYER5_GPIO_PORT, LAYER5_PIN); break; } case 6: { GPIO_SetBits(LAYER6_GPIO_PORT, LAYER6_PIN); break; } case 7: { GPIO_SetBits(LAYER7_GPIO_PORT, LAYER7_PIN); break; } } } /** * @brief 给某一层LED灯断电 * @param uint8_t lay * @retval * @date 2014-06-30 * @note */ void Bsp_LayerOff(uint8_t lay) { switch(lay) { case 0: { GPIO_ResetBits(LAYER0_GPIO_PORT, LAYER0_PIN); break; } case 1: { GPIO_ResetBits(LAYER1_GPIO_PORT, LAYER1_PIN); break; } case 2: { GPIO_ResetBits(LAYER2_GPIO_PORT, LAYER2_PIN); break; } case 3: { GPIO_ResetBits(LAYER3_GPIO_PORT, LAYER3_PIN); break; } case 4: { GPIO_ResetBits(LAYER4_GPIO_PORT, LAYER4_PIN); break; } case 5: { GPIO_ResetBits(LAYER5_GPIO_PORT, LAYER5_PIN); break; } case 6: { GPIO_ResetBits(LAYER6_GPIO_PORT, LAYER6_PIN); break; } case 7: { GPIO_ResetBits(LAYER7_GPIO_PORT, LAYER7_PIN); break; } } } /** * @brief 初始化74HC595的驱动方式,使用spi2接口 * @param none * @retval none * @date 2014-06-15 * @note 使用SPI2的单向,仅发送,低速APB1,最大36MHz */ void HC595_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; /*!< PB13 => SPI2_SCK(LED_SCK); PB15 => SPI2_MOSI(LED_TX) Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /*!< SPI2 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /*!< Configure SPI pins: SCK */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); /*!< Configure sFLASH_SPI pins: MOSI */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_Init(GPIOB, &GPIO_InitStructure); /*!< SPI configuration */ SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); /*!< Enable the sFLASH_SPI */ SPI_Cmd(SPI2, ENABLE); /*!< Configure PB14 => ROW */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); } /** * @brief 发送一层的数据 * @param uint8_t *BufPtr:发送缓冲区,共8字节数据 * @retval * @date 2014-06-17 * @note */ void H595SendData(const uint8_t *BufPtr) { /*!< Send byte through the SPI2 peripheral */ SPI_I2S_SendData(SPI2, *BufPtr); /*!< Loop while DR register in not emplty */ while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); } /** * @brief 显示一次内容 * @param * @retval * @date 2014-07-10 * @note */ void DispLayer(const uint8_t *BufPtr) { uint8_t i; for(i = 0; i < 8; i++) { H595SendData(BufPtr + i); } while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET); }
#include #include #include #include "content.h"
main文件
#include "main.h" #include "bsp.h" /** @addtogroup STM32_EEPW * @{ */ /** @defgroup LEDCUBE * @brief * @{ */ /** @defgroup LEDCUBE_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup LEDCUBE_Private_Defines * @{ */ /** * @} */ /** @defgroup LEDCUBE_Private_Macros * @{ */ /** * @} */ /** @defgroup LEDCUBE_Private_Variables * @{ */ uint16_t gSecond= 0; uint8_t gDisp = 0; uint16_t gCount = 0; /** * @} */ /** @defgroup LEDCUBE_Private_FunctionPrototypes * @{ */ /** * @} */ /** @defgroup LEDCUBE_Private_Functions * @{ */ /** * @brief main function * @param * @retval * @date 2014-03-24 * @note */ void main(void) { Bsp_Init(); /*!< 底层外设模块初始化 */ if (SysTick_Config(72000)) /*!< 1000Hz(1ms)中断间隔 */ { while (1); } while(true) { if(gCount == 2) { gCount = 0; Bsp_LayerOff(gDisp); //关闭当前层的显示 gDisp++; if(gDisp > 7) { gDisp = 0; } GPIO_ResetBits(GPIOB, GPIO_Pin_14); DispLayer(content + gDisp * 8); GPIO_SetBits(GPIOB, GPIO_Pin_14); //发送显示开启上升沿 GPIO_ResetBits(GPIOB, GPIO_Pin_14); Bsp_LayerOn(gDisp); //打开当前层的显示 } } } void SysTick_Handler(void) { if(gCount < 2) { gCount++; } else { gCount = 2; } if(gSecond < 1000) { gCount++; } else { gCount = 1000; } }
显示内容头文件
/** * @brief 光立方显示内容,全亮 * */ const uint8_t content[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
本测试程序工程使用IAR for ARM 6.7版本编译。工程文件下载地址如下:
http://share.eepw.com.cn/share/download/id/166522