zoukankan      html  css  js  c++  java
  • 基于uFUN开发板的RGB调色板

    前言

    使用uFUN开发板配合Qt上位机,实现任意颜色的混合,Qt上位机下发RGB数值,范围0-255,uFUN开发板进行解析,然后输出不同占空比的PWM,从而实现通过RGB三原色调制出任意颜色。

    Qt上位机界面:

    演示视频

    优酷视频链接:演示视频

    如果上面的链接打不开的话,可以下载观看:演示视频.mp4

    RGB简介

    RGB 模型是目前常用的一种彩色信息表达方式,它使用红、绿、蓝三原色的亮度来定量表示颜色。该模型也称为加色混色模型,是以RGB三色光互相叠加来实现混色的方法,因而适合于显示器等发光体的显示。

    可以通过调整RGB三种原色的比例,来混合出任何你想要的颜色。

    uFUN开发板的硬件电路

    uFUN开发板上的RGB灯硬件电路也很简单,可以通过TIM5/TIM2的通道1、通道2、通道3来控制,通过实际验证,发现PWM_B和PWM_G两个引脚的网络标号反了,如下图:

    定时器输出PWM配置

    使用TIM5或者TIM2都可以,但是在使用TIM5软件仿真的时候,发现没有PWM波输出,而实际有输出,不知道这是不是Keil的一个BUG,我的是5.16a版本的。

    void RGB_LED_Init(void)
    {
    	GPIO_InitTypeDef IO_Init;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef OC_Init;
    		
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    	
    	IO_Init.GPIO_Mode = GPIO_Mode_AF_PP;
    	IO_Init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
    	IO_Init.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &IO_Init);
    	
    	TIM_DeInit(TIM5);
    	
    	TIM_TimeBaseStructure.TIM_Period = 256-1; 
        TIM_TimeBaseStructure.TIM_Prescaler = 71;		
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); 
    	
    	OC_Init.TIM_OCMode = TIM_OCMode_PWM2;//输出模式
    	OC_Init.TIM_OutputState = ENABLE;				//输出使能
    	OC_Init.TIM_OCPolarity = TIM_OCPolarity_High;	//输出极性
    //	OC_Init.TIM_Pulse = 50;
    	
    	TIM_OC1Init(TIM5, &OC_Init);		
    	TIM_OC2Init(TIM5, &OC_Init);		
    	TIM_OC3Init(TIM5, &OC_Init);	
    	
    	TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
    	TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);
    	TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable);
    	
    	TIM_Cmd(TIM5, ENABLE); 
    }
    

    这里的计数周期,设置成了255,即0-255对应占空比0-100,可以通过下面这个函数来设置对应通道的占空比:

    //设置LED占空比
    void SetDutyCycle(LEDtype LEDn, int dty)
    {
    	switch(LEDn)
    	{
    		case R_LED:
    			TIM_SetCompare2(TIM5, dty);
    		break;
    		case G_LED:
    			TIM_SetCompare1(TIM5, dty);
    		break;		
    		case B_LED:
    			TIM_SetCompare3(TIM5, dty);
    		break;
    		default:
    			TIM_SetCompare1(TIM5, 0);
    			TIM_SetCompare2(TIM5, 0);
    			TIM_SetCompare2(TIM5, 0);
    		break;			
    	}
    }
    

    串口命令的解析

    Qt上位机下发的数据格式如下:

    R+数值+G+数值+B+数值+*
    

    如:

    R12G123B45*
    R155G9B24*
    

    数值有1-3位,STM32接收到数据之后,可以解析出对应的数值,

    12 123 45
    155 9 24
    

    然后控制对应的PWM输出。

    串口中断函数:

    uint8_t rx_buf[100];
    uint8_t rx_len;
    void USART1_IRQHandler(void)                	//串口1中断服务程序
    {
    	uint8_t dat;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
        {
            dat = USART_ReceiveData(USART1);	//读取接收到的数据
    //		USART_SendData(USART1, dat);
    		if(dat == '*')	
    		{
    		//R123G123B213*
    //			printf("%s %d", rx_buf, rx_len);
    			ParseCmd(rx_buf, rx_len);
    			memset(rx_buf, 0, rx_len);
    			rx_len = 0;
    		}
    		else
    		{
    			rx_buf[rx_len++] = dat;
    		}	
    	}
    }
    

    串口数据解析,获取到RGB对应的数值:

    void ParseCmd(char *rx_buf, size_t len)
    {
        uint8_t R_Num, G_Num, B_Num;
        char R_Str[20], G_Str[20], B_Str[20];
        char *R, *G, *B;
    
        len = strlen(rx_buf);
        R = strstr(rx_buf, "R");
        G = strstr(rx_buf, "G");
        B = strstr(rx_buf, "B");
    
        strncpy(R_Str, R+1, G-R-1);
        R_Str[G-R-1] = '';
        strncpy(G_Str, G+1, B-G-1);
        G_Str[B-G-1] = '';
        strncpy(B_Str, B+1, len - (B - rx_buf)-1);
        B_Str[len - (B - rx_buf)-1] = '';
    //    printf("R:-%s-,
    G:-%s-,
    B:-%s-,
    ", R_Str, G_Str, B_Str);
    
        R_Num = atoi(R_Str);
        G_Num = atoi(G_Str);
        B_Num = atoi(B_Str);
    //    printf("%d %d %d", R_Num, G_Num, B_Num);
    
    	SetDutyCycle(R_LED, R_Num);
    	SetDutyCycle(G_LED, G_Num);
    	SetDutyCycle(B_LED, B_Num);
    }
    

    代码下载

    uFUN评测系列文章


    欢迎大家关注我的个人博客www.wangchaochao.top

    或微信扫码关注我的公众号

  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/whik/p/10661385.html
Copyright © 2011-2022 走看看