最近在调试光立方的显示,发送过去的数值总是不能正确的显示在我想要的位置。非常脑怒~~于是就发了些时间,专门编写了本测试程序。
本测试程序的实现结果为:通过串口通讯(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);
}
}
回复可见工程文件下载地址:
——回复可见内容——
我要赚赏金
