打印
[G32A]

【极海G32A1465测评】——使用CAN总线实现主从板RGB灯互相控制

[复制链接]
298|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yangyurong|  楼主 | 2024-12-28 18:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 yangyurong 于 2024-12-28 18:22 编辑

使用CAN总线实现主从板RGB灯互相控制拿到开发板,还没有进行过点灯操作,但是不想随便点灯,那种普通的亮灯灭灯没啥技术含量,也不好玩,本着将CAN总线技术
融入到RGB点呼吸灯操作,这样可以通过两个CAN 节点之间互相控制对方,实现各种绚丽的呼吸灯技术,模拟汽车车灯的控制。
好了,开始进入主题。

上面是我用到的硬件平台,一个主板,一个从板,通过2根杜邦线连接双方的CAN接口。
实验现象大家可以查看我的哔哩哔哩空间
https://www.bilibili.com/video/BV1pPCaYkEZW/?spm_id_from=333.1387.homepage.video_card.click
1板的key1可以将2板的LED灯改为红色,key2可以将2板的LED灯改为蓝色。
2板的key1可以将1板的LED灯改为黄色,key2可以将1板的LED灯改为绿色。
这就是CAN的特性,互为主从,互相切换。
核心代码如下:
#include "user_config.h"
#include "board.h"
#include <string.h>
#include <stdio.h>


static __IO uint32_t g_timingDelay;


unsigned char pwm_time=0;
unsigned char pwm_r_data=0;
unsigned char pwm_g_data=0;
unsigned char pwm_b_data=0;

unsigned char led_mode = 0;

static __IO uint32_t g_ms_delay;
void SysTick_Init(void)
{
    /* Update System Core Clock info */
    SystemCoreClockUpdate();

    /* SystemFrequency / 1000 = 1ms */
    if (SysTick_Config(SystemCoreClock / 100000))
    {
        /* Capture error */
        while (1);
    }
}


void SysTick_Delay_ms(__IO uint32_t nTime)
{
    g_timingDelay = nTime;
    while(g_timingDelay != 0);
}

void TimingDelay_Decrement(void)
{
    if(g_timingDelay != 0)
    {
        g_timingDelay--;
    }
               

        pwm_time++;
        g_ms_delay++;
        
        if(pwm_time>=255)   
        {
                pwm_time=0;
        }

        if(pwm_time<=pwm_r_data)   
        {
                LED_On(LED_RED);
        }
        else
        {
                LED_Off(LED_RED);
        }

        if(pwm_time<=pwm_g_data)   
        {
                LED_On(LED_GREEN);
        }
        else
        {
                LED_Off(LED_GREEN);
        }

        if(pwm_time<=pwm_b_data)   
        {
                LED_On(LED_BLUE);
        }
        else
        {
                LED_Off(LED_BLUE);
        }
        
        if(g_ms_delay >= 500)
        {
          g_ms_delay = 0;
        }
}


uint8_t can_send_msg(uint32_t id, uint8_t *msg, uint8_t len);


void LED_PWM(unsigned char a,unsigned char b,unsigned char c)      //三路PWM,R/G/B
{
        pwm_r_data=a;
        pwm_g_data=b;
        pwm_b_data=c;
}



void breath_fresh_Red(void);
void breath_fresh_Green(void);
void breath_fresh_Blue(void);
void breath_fresh_Yellow(void);
void breath_fresh_Pink(void);
void breath_fresh_Teal(void);
void breath_fresh_White(void);

void breath_fresh_BreathingWithCorlorChanging(void);
void ChasingEffect_Red(void);

void ChasingEffect_Wait(void);

void Call_Effect(void);
void Drop_effect_Red(void);

void ledPulse(uint8_t r, uint8_t g, uint8_t b, uint8_t min_brightness,
        uint8_t max_brightness, uint16_t delay_step);
                                


void RGB_LED_CONTROL(uint8_t mode);
/** @addtogroup G32A1465_Examples
  @{
  */

/** @addtogroup CAN_ClassicFrames
  @{
  */

/** @defgroup CAN_ClassicFrames_Macros Macros
  @{
  */
/* CAN instance */
#define CAN0_INSTANCE       (0U)

/* MB0 is used to receive standard CAN frames */
#define RX_MB_0             (0U)

/* MB1 is used to receive extended CAN frames */
#define RX_MB_1             (1U)

/* The MB used to transmit CAN frames */
#define TX_MB               (2U)

/* CAN message IDs */
#define RX_CAN_MESSAGE_ID   (0x111U)
#define RX_CAN_MESSAGE_ID1  (0x111U)
#define TX_CAN_MESSAGE_ID_2 (0x222U)


CAN_MSG_BUF_T rxFrame0;
CAN_MSG_BUF_T rxFrame1;


/**@} end of group CAN_ClassicFrames_Macros*/
/** @defgroup CAN_ClassicFrames_Variables Variables
  @{
  */
/* Indicate MB0 receive is completed */
volatile uint8_t g_mb0ReceiveCompleted = 0;

/* Indicate MB1 receive is completed */
volatile uint8_t g_mb1ReceiveCompleted = 0;


volatile uint8_t payload1[64];
volatile uint8_t CAN_DAT;
/**@} end of group CAN_ClassicFrames_Variables*/

/** @defgroup CAN_ClassicFrames_Functions Functions
  @{
  */

/*!
* @brief This function is called when a CAN event occurred
*/
void CanEventCallback(
    uint8_t instance,
    CAN_EVENT_TYPE_T eventType,
    uint32_t mbIndex,
    CAN_STATE_T *driverState)
{
    CAN_DATA_INFO_T rxDataInfo;
        uint8_t i;
    /* A frame was received in the configured Rx MB */
    if (eventType == CAN_EVENT_RX_COMPLETE)
    {
        /* Set the receive complete flags */
        if (mbIndex == RX_MB_0)
        {
                        
//                                memcpy(payload1, rxFrame0.data, rxFrame0.dataLen);
                if(rxFrame0.messageId == RX_CAN_MESSAGE_ID1)
                                        {
                                                if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==1))
                                                {
                                                        g_mb0ReceiveCompleted = 1;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==2))
                                                {
                                                        g_mb0ReceiveCompleted = 2;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==3))
                                                {
                                                        g_mb0ReceiveCompleted = 3;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==4))
                                                {
                                                        g_mb0ReceiveCompleted = 4;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==5))
                                                {
                                                        g_mb0ReceiveCompleted = 5;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==6))
                                                {
                                                        g_mb0ReceiveCompleted = 6;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==7))
                                                {
                                                        g_mb0ReceiveCompleted = 7;
                                                }
                                                else if((rxFrame0.data[0]==0x30)&&(rxFrame0.data[1]==8))
                                                {
                                                        g_mb0ReceiveCompleted = 8;
                                                }
                                                
                                        }
                                        rxDataInfo.msgIdType  = CAN_ID_STANDARD;
                                        rxDataInfo.dataLen    = rxFrame0.dataLen;
                                        rxDataInfo.fdEnable   = false;
                                        rxDataInfo.isRemote   = false;
                                        CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_0, &rxFrame0);
        }
        if (mbIndex == RX_MB_1)
        {
                if(rxFrame1.messageId == RX_CAN_MESSAGE_ID1)
                        {
                                memcpy(payload1, rxFrame1.data, rxFrame1.dataLen);
                                g_mb1ReceiveCompleted = true;
                        }
                        rxDataInfo.msgIdType  = CAN_ID_STANDARD;
                        rxDataInfo.dataLen    = rxFrame1.dataLen;
                        rxDataInfo.fdEnable   = false;
                        rxDataInfo.isRemote   = false;
                        CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_1, &rxFrame1);
        }
    }
}

/*!
* @brief This function is called when the KEY1 button is pressed
*/
void Key1Handler(void)
{
    /* Send standard CAN frame */
    uint8_t payload[8] = {0x30, 2, 0, 0, 0, 0, 0, 0};        
    can_send_msg(TX_CAN_MESSAGE_ID_2, payload, 8);
}

/*!
* @brief This function is called when the KEY2 button is pressed
*/
void Key2Handler(void)
{
    /* Send extended CAN frame */
    uint8_t payload[8] = {0x30, 3, 0, 0, 0, 0, 0, 0};        
    can_send_msg(TX_CAN_MESSAGE_ID_2, payload, 8);
}

/*!
* @brief   Main function
* @param   None
* @retval  Exit code
*/
int main(void)
{
    bool exit = false;
    CAN_STATE_T canState;
    CAN_TIME_SEGMENT_T canBitrate;

    /* Initialize clock */
    CLOCK_SYS_Init(&g_clockConfig);

    /* Initialize pins */
    PINS_Init(NUM_OF_CONFIGURED_PINS0, g_pinsConfig);

    /* Initialize LEDs */
    LED_Init();
    LED_On(LED_GREEN);
          LED_On(LED_RED);
//          LED_On(LED_BLUE);
        
          SysTick_Init();

    /* Initialize buttons */
    BTN_Init();
    BTN_InstallKey1Handler(Key1Handler);
    BTN_InstallKey2Handler(Key2Handler);

    /* Initialize the CAN controller, bitrate is 250K */
    CAN_Init(CAN0_INSTANCE, &canState, &g_canConfig);

    /* Get the current CAN bitrate */
    CAN_GetBitrate(CAN0_INSTANCE, &canBitrate);

    /* Configure Tx MB */
    CAN_DATA_INFO_T txMbInfo = {
        .msgIdType  = CAN_ID_STANDARD,   /* Standard CAN ID */
        .dataLen    = 8,        /* Used only to initialize the MB, will be updated when send data */
        .fdEnable   = false,    /* Disable CAN FD */
        .isRemote   = false
    };
    CAN_ConfigureTxMb(CAN0_INSTANCE, TX_MB, &txMbInfo, 0);

    /* Use individual Rx masking for the MBs */
    CAN_SetRxMaskType(CAN0_INSTANCE, CAN_RX_MASK_INDIVIDUAL);

    /* Configure Rx MB0, it will receive standard frames with ID 1 */
    CAN_DATA_INFO_T rxMb0Info = {
        .msgIdType  = CAN_ID_STANDARD,   /* Standard CAN ID */
        .dataLen    = 8,        /* Max data length for classic CAN is 8 bytes */
        .fdEnable   = false,    /* Disable CAN FD */
        .isRemote   = false
    };
    CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_0, &rxMb0Info, RX_CAN_MESSAGE_ID);
    CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_STANDARD, RX_MB_0, 0xFFFFFFFF);

    /* Configure Rx MB1, it will receive extended frames with ID 1 */
    CAN_DATA_INFO_T rxMb1Info = {
        .msgIdType  = CAN_ID_EXTENDED,   /* Extended CAN ID */
        .dataLen    = 8,        /* Max data length for classic CAN is 8 bytes */
        .fdEnable   = false,    /* Disable CAN FD */
        .isRemote   = false
    };
    CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_1, &rxMb1Info, 0x112);
    CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_EXTENDED, RX_MB_1, 0xFFFFFFFF);

    /* Set the CAN event callback handler */
    CAN_InstallEventCallback(CAN0_INSTANCE, &CanEventCallback, NULL);


               
                CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_0, &rxFrame0);
                CAN_ReceiveNonBlocking(CAN0_INSTANCE, RX_MB_1, &rxFrame1);
               
        LED_PWM(0,0,0);
               
                while (1)
                {
//                        ledPulse(0,0,0,0,255,500);
//                        Drop_effect_Red();
//                        Call_Effect();
//                          ChasingEffect_Wait();
//                        ChasingEffect_Red();
//                        breath_fresh_BreathingWithCorlorChanging();
                        
//                        LED_On(LED_RED);
//                        delay_ms(200);
//                        LED_Off(LED_RED);
//                        delay_ms(200);
                        
//                        breath_fresh_Red();
//                        breath_fresh_Green();
//      breath_fresh_Blue();
//                        breath_fresh_Yellow();
//                        breath_fresh_Pink();
//                        breath_fresh_Teal();
//                        breath_fresh_White();
//                        RGB_LED_CONTROL(led_mode);
                        
                        switch (g_mb0ReceiveCompleted)
                        {
                                case 1:
                                        breath_fresh_Red();
                                break;
                                case 2:
                                        breath_fresh_Green();
                                break;
                                case 3:
                                        breath_fresh_Blue();
                                break;
                                case 4:
                                        breath_fresh_Yellow();
                                break;
                                case 5:
                                        breath_fresh_Pink();
                                break;
                                case 6:
                                        breath_fresh_Teal();
                                break;
                                case 7:
                                        breath_fresh_White();
                                break;
                                case 8:
                                        breath_fresh_BreathingWithCorlorChanging();
                                break;
                        }


                }
               
        
    return 0;
}


/**
* @brief       CAN ·¢ˍһשʽ¾ݍ
*   @NOTE      ·¢ˍ¸

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

18

帖子

0

粉丝