最近在调试光立方的显示,发送过去的数值总是不能正确的显示在我想要的位置。非常脑怒~~于是就发了些时间,专门编写了本测试程序。
本测试程序的实现结果为:通过串口通讯(115200波特率,Hex模式)将数据发送到光立方内,光立方即显示出对应的图案。
发送的数据为一帧图案,即64个字节。光立方在接收到小于等于64个字节后即显示出其图案。
例如:发送0x01至光立方则只有第一层第1个排,第1个灯亮。其余大家可以直接通过串口助手发送数据来尝试。
光测试程序的实现方法:通过串口通讯接收数据,然后将接收的数据直接发送至显示缓冲区,然后通过周期调用显示函数在光立方中显示。判断一帧数据的方法为:1、接收满64字节;2、字节间发送间隔大于4ms。
附源代码:
main.c
/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "bsp.h" #include "drv_rs485.h" #define INTERVAL (500) uint16_t gSecond= 0; bool gShareMemoryBusy; uint8_t gDisp = 0; uint16_t gCount = 0; uint8_t gGraphBuffer[64] = {0xFF,}; uint8_t gFrameTimeOut = 0; uint8_t gRcvCnt = 0; bool gFrameEnable = false; /** @defgroup LEDCUBE_Private_FunctionPrototypes * @{ */ void AutoReFresh(uint8_t *BufferPtr, bool gShareMemoryBusy); /** * @} */ /** @defgroup LEDCUBE_Private_Functions * @{ */ /** * @brief main function * @param * @retval * @date 2014-03-24 * @note */ void main(void) { gShareMemoryBusy = true; uint8_t i = 0; for(i = 0; i < 64; i++) { gGraphBuffer[i] = 0xFF; } gShareMemoryBusy = false; #ifndef SIMULATE Bsp_Init(); /*!< 底层外设模块初始化 */ #endif if (SysTick_Config(72000)) /*!< 1000Hz(1ms)中断间隔 */ { while (1); } UART1_init(115200); while(true) { if(gRcvCnt == 64 || gFrameTimeOut == 4) { gFrameEnable = false; gShareMemoryBusy = true; gRcvCnt = 0; gFrameTimeOut = 0; for(i = 0; i < 64; i++) { gGraphBuffer[i] = ~RcvBuf[i]; RcvBuf[i] = 0x00; } gShareMemoryBusy = false; } } } /** * @brief 定时刷新光立方显示 * @param uint8_t *BufferPtr: 显示图形缓存 bool MemBusy: 检查显示图形缓存是否可用, true:正在更新缓存,此时不显示; false:已经完成数据更新,不断刷新 * @retval * @date 2014-08-17 * @note 1000Hz显示每一层 */ void AutoReFresh(uint8_t *BufferPtr, bool MemBusy) { if(MemBusy == true) { // to do something return; } else { Bsp_LayerOff(gDisp); //关闭当前层的显示 H595Disable(); gDisp++; if(gDisp > 7) { gDisp = 0; } DispFlush(BufferPtr + gDisp * 8); H595Enable(); Bsp_LayerOn(gDisp); //打开当前层的显示 } } /** * @brief 使用systick中断产生1000Hz, 1ms中断 * @param * @retval * @date 2014-08-17 * @note 500Hz会出现闪烁 */ void SysTick_Handler(void) { AutoReFresh((uint8_t *)gGraphBuffer, gShareMemoryBusy); if(gFrameEnable == true) { if(gFrameTimeOut > 3) { gFrameTimeOut = 4; } else { gFrameTimeOut++; } } if(gSecond < INTERVAL) { gSecond++; } else { gSecond = INTERVAL; } }
drv_rs485.c
Rs485Buf_t SendBuf[RS485_BUFFER_SIZE]; Rs485Buf_t RcvBuf[RS485_BUFFER_SIZE]; extern uint8_t gRcvCnt; extern uint8_t gFrameTimeOut; extern bool gFrameEnable; /** * @} */ /** @defgroup drv_rs485_Private_FunctionPrototypes * @{ */ /** * @} */ /** @defgroup drv_rs485_Private_Functions * @{ */ /** * @brief 初始化串口1, 发送DMA方式,接收中断,RS232,预留RS485 * @param uint32_t band: 串口波特率 * @retval none */ void UART1_init(uint32_t band) { GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(ELOG_COM1_TX_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE); /* Enable UART clock */ RCC_APB2PeriphClockCmd(ELOG_COM1_CLK, ENABLE); /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); #ifdef UART1RS485 /* Enable RS485 DirCtrl PB0 */ RCC_APB2PeriphClockCmd(ELOG_COM1_DRV_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(ELOG_COM1_DRV_GPIO_PORT, &GPIO_InitStructure); #endif /* Configure USART Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = ELOG_COM1_TX_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(ELOG_COM1_TX_GPIO_PORT, &GPIO_InitStructure); /* Configure USART Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = ELOG_COM1_RX_PIN; GPIO_Init(ELOG_COM1_RX_GPIO_PORT, &GPIO_InitStructure); /* Configure DMA channel 4 for USART1 TX */ DMA_DeInit(ELOG_COM1_DMA_CH); DMA_InitStructure.DMA_PeripheralBaseAddr = RS485_USART1_DR_BASE_ADDR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&SendBuf[0]); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = RS485_BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(ELOG_COM1_DMA_CH, &DMA_InitStructure); /* USART configuration */ USART_InitStructure.USART_BaudRate = band; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(ELOG_COM1, &USART_InitStructure); /* Configure and enable USART1 DMA TX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = ELOG_COM1_DMA_IRQch; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = ELOG_COM1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(ELOG_COM1_DMA_CH, DMA_IT_TC, ENABLE); /* enable USART1 TX DMA */ USART_DMACmd(ELOG_COM1, USART_DMAReq_Tx, ENABLE); /* enalbe USART1 RXNE interrupt */ USART_ITConfig(ELOG_COM1, USART_IT_RXNE, ENABLE); /* Enable USART */ USART_Cmd(ELOG_COM1, ENABLE); // gSemaphore = SEND_IDLE; } /** * @brief DMA1_channel4中断 * @param none * @retval none * @date 2014-04-24 * @note 发送完成中断,使能USART1发送完成中断,关闭DMA TC中断,清除DMA TC中断 */ void DMA1_Channel4_IRQHandler (void) { ITStatus uart1iscomplete; uart1iscomplete = DMA_GetITStatus(DMA1_IT_TC4); if (uart1iscomplete == SET) { USART_ITConfig(ELOG_COM1, USART_IT_TC, ENABLE); DMA_ClearITPendingBit(DMA1_IT_TC4); } } /** * @brief USART1中断函数入口 * @param * @retval * @date 2014-04-23 * @note 以RS232的方式接收数据 */ void USART1_IRQHandler(void) { if(USART_GetITStatus(ELOG_COM1, USART_IT_RXNE) == SET) { /* 处理接收数据 */ USART_ClearITPendingBit(ELOG_COM1, USART_IT_RXNE); gRcvCnt++; gFrameTimeOut = 0; gFrameEnable = true; if(gRcvCnt > 64) { gRcvCnt = 64; } else { *(RcvBuf + gRcvCnt - 1) = USART_ReceiveData(ELOG_COM1); } } if(USART_GetITStatus(ELOG_COM1, USART_IT_TC) == SET) { USART_ITConfig(ELOG_COM1, USART_IT_TC, DISABLE); USART_ClearITPendingBit(ELOG_COM1, USART_IT_TC); } }
回复可见工程文件下载地址:
——回复可见内容——