netlhx 发表于 2015-7-28 21:19:54

RGB三色灯小程序

本帖最后由 netlhx 于 2015-7-28 21:29 编辑

收到GOKIT有段时间了,最近终于可以仔细的玩一玩。

GOKIT本身是一个完整的解决方案,内容挺多,决定先从最基本的玩起。

我申请的STM32的底板,编译了官方的代码,下载到开发板上。谁知道出问题了,死活不能下载,好吧,到官网上爬答案。原来要切换开关,切换就切换,下载好了,但是没有运行,再看,还要切换开关。问题是开关藏在里面,只好拿棍子去拔。头疼啊!!也不知道新版会不会解决这个问题。

打开配套的APP,嗯,里面不错,基本的功能演示都有,看完了,基本功能了解。下面开始动手,先点个灯看看。

考虑到原底板调试有点麻烦,刚好上面的功能板兼容ARDUINO接口,所以底板就用手头的一个NUCLEO F411RE来代替。这样的话,官方的APP是没法用了,不过慢慢来,先点灯再说。



是不是也很威猛!(只是不知道官方会不会伤心!)

下面看代码,至于逻辑连接图及P8913的资料,大家自己看,下面直接上代码:

RGB.C文件的内容,主要是驱动LED部分

#include "stm32f4xx_hal.h"
#include "rgb.h"
#include "utility.h"

#define SCL_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET)
#define SCL_HIGH HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET)

#define SDA_LOW HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET)
#define SDA_HIGH HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET)


void RGB_Init(void)
{
      GPIO_InitTypeDef gpio;
      
      
      __GPIOB_CLK_ENABLE();
      
      //configure GPIO for SCL & SDA
      gpio.Pin = GPIO_PIN_8 | GPIO_PIN_9;
      gpio.Mode = GPIO_MODE_OUTPUT_PP;
      gpio.Pull = GPIO_NOPULL;
      gpio.Speed = GPIO_SPEED_LOW;
      
      HAL_GPIO_Init(GPIOB, &gpio);
      

      
      
      
}

void RGB_Setup(uint8_t RValue, uint8_t GValue, uint8_t BValue)
{
      uint8_t i;
      static volatile uint32_t data = 0;
      
      //sending leading 32 zeros
      for(i = 0; i < 32; i ++)
      {
                SDA_LOW;
                Delay_us(4);
                SCL_LOW;
                Delay_us(4);
                SCL_HIGH;
                Delay_us(4);
               
      }      
      
      //sending flag & RGB complementary codes
      data |= 0xC0000000;
      
      data |= (((~BValue) & 0xC0) >> 6) << 28;
      data |= (((~GValue) & 0xC0) >> 6) << 26;
      data |= (((~RValue) & 0xC0) >> 6) << 24;
      
      data |= BValue << 16;
      data |= GValue << 8;
      data |= RValue << 0;
      
      for(i = 0; i < 32; i ++)
      {
                if(data & (1 << (31 - i)))
                        SDA_HIGH;
                else
                        SDA_LOW;
               
                Delay_us(4);
               
                SCL_LOW;
                Delay_us(4);
                SCL_HIGH;
                Delay_us(4);
               
               
      }
      
      SCL_LOW;
      
      
      
      
      
}



在工程里使用了FREERTOS,所以将RGB部分独立组成一个任务,下面是任务相关代码

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

/* USER CODE BEGIN Includes */   
#include "queue.h"
#include "rgb.h"
/* USER CODE END Includes */

/* Variables -----------------------------------------------------------------*/
osThreadId defaultTaskHandle;

/* USER CODE BEGIN Variables */
osThreadId rgbLEDHandle;

osMessageQId rgbMessageHandle;

/* USER CODE END Variables */

/* Function prototypes -------------------------------------------------------*/
void StartDefaultTask(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* USER CODE BEGIN FunctionPrototypes */
void StartRgbLEDTask(void const *argument);

/* USER CODE END FunctionPrototypes */

/* Hook prototypes */

/* Init FreeRTOS */

void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
      
/* USER CODE END Init */

/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */

/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */

/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */

/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
      
      osThreadDef(rgbLEDTask, StartRgbLEDTask, osPriorityNormal, 0, 128);
      rgbLEDHandle = osThreadCreate(osThread(rgbLEDTask), NULL);

/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */

/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
      osMessageQDef(rgbMessage, 5, uint32_t);
      rgbMessageHandle = osMessageCreate(osMessageQ(rgbMessage), NULL);
/* USER CODE END RTOS_QUEUES */
}

/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{

/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
    osDelay(1);
}
/* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Application */
void StartRgbLEDTask(void const *argument)
{
      
      osEvent event;
      
      RGB_Init();
      
      for(;;)
      {
      
                event = osMessagePeek(rgbMessageHandle, 0);
               
                if(event.status == osEventMessage)
                {
                        event = osMessageGet(rgbMessageHandle, 0);
                        RGB_Setup(event.value.v >> 24, (event.value.v & 0x00FF0000) >> 16, (event.value.v & 0xFF));
                }
                else
                {
                        RGB_Setup(1, 1, 1);
                        
                }
               
                osDelay(10);
}
      
}
   
/* USER CODE END Application */
注意,这里添加了一个消息队列,提供了一个接口,使得可以在其它任务里面改变RGB的值,在下个程序里准备添加红外遥控来控制RGB分量的值。
如果队列的值为空,则使用默认值,RGB分别为1,1, 1。可别说,这个LED灯真是亮瞎眼!!!

先玩这么多,下个例程再见。

效果



最后说一下,官方的例程里面每一步都延迟40MS,反应不知得多慢,这里全部改成了1US,快多了。

BlueTaro 发表于 2015-7-28 21:50:33

期待后续…

Tom·机智云 发表于 2015-7-28 22:28:29

期待更新。:victory:

麦东东 发表于 2015-7-29 10:01:00

楼主好厉害啊

QH_飞蓬 发表于 2015-7-31 16:27:40

基于STM32的,我也是用STM32的,谢谢分享!

jhxhss 发表于 2015-7-31 17:47:03

支持楼主,期待下个例程:)

vicky 发表于 2015-7-31 18:35:16

哇哦~赞一个

xnmc 发表于 2015-8-2 22:03:14

呵呵,我也打算有时间时把它移植到Nucleo-F303,再用12864屏显示~~~~~~~
页: [1]
查看完整版本: RGB三色灯小程序