- void SysTick_Handler(void)
- {
- tick++;
- }<span style="background-color: rgb(255, 255, 255);"> </span>
接着我们添加MultiTimer代码
- #include "MultiTimer.h"
- #include <stdio.h>
- /* Timer handle list head. */
- static MultiTimer* timerList = NULL;
- /* Timer tick */
- static PlatformTicksFunction_t platformTicksFunction = NULL;
- int MultiTimerInstall(PlatformTicksFunction_t ticksFunc)
- {
- platformTicksFunction = ticksFunc;
- return 0;
- }
- int MultiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData)
- {
- if (!timer || !callback ) {
- return -1;
- }
- MultiTimer** nextTimer = &timerList;
- /* Remove the existing target timer. */
- for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
- if (timer == *nextTimer) {
- *nextTimer = timer->next; /* remove from list */
- break;
- }
- }
- /* Init timer. */
- timer->deadline = platformTicksFunction() + timing;
- timer->callback = callback;
- timer->userData = userData;
- /* Insert timer. */
- for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next) {
- if (!*nextTimer) {
- timer->next = NULL;
- *nextTimer = timer;
- break;
- }
- if (timer->deadline < (*nextTimer)->deadline) {
- timer->next = *nextTimer;
- *nextTimer = timer;
- break;
- }
- }
- return 0;
- }
- int MultiTimerStop(MultiTimer* timer)
- {
- MultiTimer** nextTimer = &timerList;
- /* Find and remove timer. */
- for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
- MultiTimer* entry = *nextTimer;
- if (entry == timer) {
- *nextTimer = timer->next;
- break;
- }
- }
- return 0;
- }
- int MultiTimerYield(void)
- {
- MultiTimer* entry = timerList;
- for (; entry; entry = entry->next) {
- /* Sorted list, just process with the front part. */
- if (platformTicksFunction() < entry->deadline) {
- return (int)(entry->deadline - platformTicksFunction());
- }
- /* remove expired timer from list */
- timerList = entry->next;
- /* call callback */
- if (entry->callback) {
- entry->callback(entry, entry->userData);
- }
- }
- return 0;
- }
最后我们直接开两个定时器即两个线程,一个作为按键扫描,一个作为灯光的控制
- #include "Board.h"
- #if defined (APM32E103_MINI)
- #include "Board_APM32E103_MINI.c"
- #include "RGB.h"
- #include "KEY.h"
- volatile uint64_t tick = 0;
- MultiTimer timer1;
- MultiTimer timer2;
- uint64_t PlatformTicksGetFunc(void)
- {
- return tick;
- }
- void RGBTimer1Callback(MultiTimer* timer, void *userData)
- {
- switch(RGB_Eff)
- {
- case DYN_RGB:
- {
- GradientDreamColor();
- }
- break;
- case DYN_RED:
- {
- GradientDreamSingleColor(DYN_RED);
- }
- break;
- case DYN_ORANGE:
- {
- GradientDreamSingleColor(DYN_ORANGE);
- }
- break;
- case DYN_YELLOW:
- {
- GradientDreamSingleColor(DYN_YELLOW);
- }
- break;
- case DYN_GREE:
- {
- GradientDreamSingleColor(DYN_GREE);
- }
- break;
- case DYN_CYAN:
- {
- GradientDreamSingleColor(DYN_CYAN);
- }
- break;
- case DYN_BLUE:
- {
- GradientDreamSingleColor(DYN_BLUE);
- }
- break;
- case DYN_PURPLE:
- {
- GradientDreamSingleColor(DYN_PURPLE);
- }
- break;
- case STATICK_RED:
- {
- SetRGB_PWM(0xFF,0x00,0x00);
- }
- break;
- case STATICK_ORANGE:
- {
- SetRGB_PWM(225,69,0);
- }
- break;
- case STATICK_YELLOW:
- {
- SetRGB_PWM(0xFF,0xFF,0x00);
- }
- break;
- case STATICK_GREEN:
- {
- SetRGB_PWM(0x00,0xFF,0x00);
- }
- break;
- case STATICK_CYAN:
- {
- SetRGB_PWM(0x00,0xFF,0xFF);
- }
- break;
- case STATICK_BLUE:
- {
- SetRGB_PWM(0x00,0x00,0xFF);
- }
- break;
- case STATICK_PURPLE:
- {
- SetRGB_PWM(0xFF,0x00,0xFF);
- }
- break;
- case STATICK_WHITE:
- {
- SetRGB_PWM(0xFF,0xFF,0xFF);
- }
- break;
- case STATICK_BLACK:
- {
- SetRGB_PWM(0x00,0x00,0x00);
- }
- break;
- default:
- break;
- }
- MultiTimerStart(timer, 10, RGBTimer1Callback, userData);
- }
2. KEY驱动:
- #include "KEY.h"
- #include "main.h"
- void KEY_Init(void)
- {
- GPIO_Config_T GPIO_ConfigStruct;
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
- GPIO_ConfigStruct.pin = GPIO_PIN_0|GPIO_PIN_1; //PB0--TMR3_CH3
- GPIO_ConfigStruct.mode = GPIO_MODE_IN_PU;
- GPIO_Config(GPIOA, &GPIO_ConfigStruct);
- }
- u8 KEY_Handler(void)
- {
- static u8 key1bounce=0,key2bounce=0;
- u8 key=0;
- if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_0)==BIT_RESET)
- {
- key1bounce=1;
- }else{
- if(key1bounce)
- {
- key|=0x01;
- }
- key1bounce=0;
-
- }
- if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_1)==BIT_RESET)
- {
- key2bounce=1;
- }else{
- if(key2bounce)
- {
- key|=0x02;
- }
- key2bounce=0;
-
- }
- return key;
- }
3. RGB驱动:
- /*!
- * [url=home.php?mod=space&uid=288409]@file[/url] RGB.c
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] This file provides firmware functions to manage Leds and push-buttons
- *
- * [url=home.php?mod=space&uid=895143]@version[/url] V1.0.0
- *
- * [url=home.php?mod=space&uid=212281]@date[/url] 2021-07-26
- *
- */
- #include "RGB.h"
- #include "main.h"
- //RGB
- RGB_LED_EFFECT RGB_Eff=DYN_RGB;
- void RGB_Init(void)
- {
- GPIO_Config_T GPIO_ConfigStruct;
- TMR_BaseConfig_T TMR_TimeBaseStruct;
- TMR_OCConfig_T OCcongigStruct;
- RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB));
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
- GPIO_ConfigStruct.pin = GPIO_PIN_6|GPIO_PIN_7;//PA6--TMR3_CH1
- GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP; //PA7--TMR3_CH2
- GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOA, &GPIO_ConfigStruct);
- GPIO_ConfigStruct.pin = GPIO_PIN_0; //PB0--TMR3_CH3
- GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOB, &GPIO_ConfigStruct);
- TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_TimeBaseStruct.division = 71;
- TMR_TimeBaseStruct.period = 255;
- TMR_ConfigTimeBase(TMR3, &TMR_TimeBaseStruct);
- OCcongigStruct.idleState = TMR_OC_IDLE_STATE_RESET;
- OCcongigStruct.mode = TMR_OC_MODE_PWM1;
- OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;
- OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH;
- OCcongigStruct.outputNState = TMR_OC_NSTATE_ENABLE;
- OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;
- OCcongigStruct.polarity = TMR_OC_POLARITY_HIGH;
- OCcongigStruct.pulse = 0;
- TMR_ConfigOC1(TMR3, &OCcongigStruct);
- TMR_ConfigOC2(TMR3, &OCcongigStruct);
- TMR_ConfigOC3(TMR3, &OCcongigStruct);
- TMR_ConfigOC1Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_ConfigOC2Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_ConfigOC3Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
- TMR_EnableAUTOReload(TMR3);
- TMR_Enable(TMR3);
- TMR_EnablePWMOutputs(TMR3);
- }
- void SetRGB_PWM(u16 R,u16 G,u16 B)
- {
- TMR3->CC1=R;
- TMR3->CC2=G;
- TMR3->CC3=B;
- }
- const u8 R[8]= {255,191,127,0,0,0,150,255};
- const u8 G[8]= {0,69,127,255,127,0,2,0};
- const u8 B[8]= {0,0,0,0,127,255,134,0};
- unsigned char abs0(int num)
- {
- if(num>0) return num;
- num = -num;
- return (unsigned char) num;
- }
- u8 ColorToColor(u8 r0,u8 g0,u8 b0, u8 r1,u8 g1,u8 b1,float* RedStep,float* GreenStep,float* BlueStep)
- {
- unsigned char Red0, Green0, Blue0; // 起始三原色
- unsigned char Red1, Green1, Blue1; // 结果三原色
- int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)
- u8 NStep;
- //unsigned long color; // 结果色
- // 绿 红 蓝 三原色分解
- Red0 = r0;
- Green0 = g0;
- Blue0 = b0;
- Red1 = r1;
- Green1 = g1;
- Blue1 = b1;
- // 计算需要多少步(取差值的最大值)
- RedMinus = Red1 - Red0;
- GreenMinus = Green1 - Green0;
- BlueMinus = Blue1 - Blue0;
- NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
- NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
- // 计算出各色步进值
- RedStep[0] = (float)RedMinus / NStep;
- GreenStep[0] = (float)GreenMinus / NStep;
- BlueStep[0] = (float)BlueMinus / NStep;
- // 渐变开始
- // for(i=0; i<NStep; i++)
- // {
- // Red1 = Red0 + (int)(RedStep * i);
- // Green1 = Green0 + (int)(GreenStep * i);
- // Blue1 = Blue0 + (int)(BlueStep * i);
- //
- // //color = Green1<<16 | Red1<<8 | Blue1; // 合成 绿红蓝
- // SetPWM_for_RGB(Red1,Green1,Blue1);
- //
- // DelayMs(1); // 渐变速度
- // }
- // 渐变结束
- return NStep;
- }
- void GradientDreamSingleColor(RGB_LED_EFFECT type)
- {
- unsigned char Red, Green, Blue; // 结果三原色
- static u8 first=0,tick=0,cStep=0,tp=1,rgb=0;
- static float RedStep, GreenStep, BlueStep;
- static RGB_LED_EFFECT typelast=DYN_RED;
- if(typelast!=type)
- {
- SetRGB_PWM(0,0,0);
- }
- typelast=type;
- if(first==0)
- {
- first=1;
- switch(type)
- {
- case DYN_RED:
- {
- rgb=0;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_ORANGE:
- {
- rgb=1;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_YELLOW:
- {
- rgb=2;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_GREE:
- {
- rgb=3;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_CYAN:
- {
- rgb=4;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_BLUE:
- {
- rgb=5;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- case DYN_PURPLE:
- {
- rgb=6;
- if(tp==0)
- {
- tp=1;
- cStep=ColorToColor(R[rgb],G[rgb],B[rgb],0,0,0,&RedStep,&GreenStep,&BlueStep);
- } else {
- tp=0;
- cStep=ColorToColor(0,0,0,R[rgb],G[rgb],B[rgb],&RedStep,&GreenStep,&BlueStep);
- }
- }
- break;
- default:
- break;
- }
- } else {
- if(tick<cStep)
- {
- if(tp==0)
- {
- Red =0+ (int)(RedStep * tick);
- Green = 0+ (int)(GreenStep * tick);
- Blue = 0+(int)(BlueStep *tick);
- } else {
- Red =R[rgb] + (int)(RedStep * tick);
- Green = G[rgb] + (int)(GreenStep * tick);
- Blue = B[rgb] + (int)(BlueStep *tick);
- }
- SetRGB_PWM(Red,Green,Blue);
- } else {
- tick=0;
- first=0;
- }
- tick++;
- }
- }
- void GradientDreamColor(void)
- {
- unsigned char Red, Green, Blue; // 结果三原色
- static u8 first=0,i=0,tick=0,cStep=0;
- static float RedStep, GreenStep, BlueStep;
- static u16 delaytick=0;
- if(delaytick++>5)
- {
- delaytick=0;
- if(first==0)
- {
- first=1;
- cStep=ColorToColor(R[i],G[i],B[i],R[i+1],G[i+1],B[i+1],&RedStep,&GreenStep,&BlueStep);
- } else {
- if(tick<cStep)
- {
- Red =R[i] + (int)(RedStep * tick);
- Green = G[i] + (int)(GreenStep * tick);
- Blue = B[i] + (int)(BlueStep *tick);
- SetRGB_PWM(Red,Green,Blue);
- } else {
- tick=0;
- if(++i>=7)
- {
- i=0;
- }
- first=0;
- }
- tick++;
- }
- }
- }
最后实验可以看我们的视频:
https://www.bilibili.com/video/BV1ZT411A77M/?vd_source=2bbde87de845d5220b1d8ba075c12fb0
并附上代码