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,快多了。
期待后续… 期待更新。:victory: 楼主好厉害啊 基于STM32的,我也是用STM32的,谢谢分享! 支持楼主,期待下个例程:) 哇哦~赞一个 呵呵,我也打算有时间时把它移植到Nucleo-F303,再用12864屏显示~~~~~~~
页:
[1]