STM32 ve PIC18 CanBus Problemi (MCP2551)

Başlatan baran123, 28 Şubat 2017, 21:43:41

baran123

STM32F103C8 Minimal board  + MCP2551 ile PIC18F46K80 haberleştirmeye çalışıyorum fakat veri ne gidiyor ne geliyor.
Daha önce 2 adet PIC18'i Canbus ile haberleştirdim burada problem yok fakat STM32 ile veri gönderdiğimde Bus'da bir çıkış göremiyorum.
Salea logic analyzerdan bakıyorum.

Burada LED yanıyor veri gitmesne rağmen Can hattında bir şey göremiyorum
canTxStatus = CAN_Transmit(CAN1, &TxMessage);

        if (canTxStatus == CAN_TxStatus_Ok)
            LED_ON(); //


STM32 kodu (200 kBit/s ve MCP2551 5V bağlı, RS = GND)
#include "stm32f10x_conf.h"
#include "main.h"
#include "stm32f10x_it.h"

static void Clock_Config(void);
static void RCC_Config(void);
static void GPIO_Config(void);
static void CAN1_Config(void);
static void NVIC_Config(void);

CanTxMsg TxMessage;
CanRxMsg RxMessage;

int main(void)
{
    Clock_Config();
    RCC_Config();
    GPIO_Config();
    CAN1_Config();
    NVIC_Config();

    LED_OFF();

    TxMessage.StdId = 1;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = 8;
    TxMessage.Data[0] = 'S';
    TxMessage.Data[1] = 'T';
    TxMessage.Data[2] = 'M';
    TxMessage.Data[3] = '3';
    TxMessage.Data[4] = '2';
    TxMessage.Data[5] = 'C';
    TxMessage.Data[6] = 'A';
    TxMessage.Data[7] = 'N';

    for(;;)
    {

    }
}

static void Clock_Config(void)
{
    /* Error Status Definition */
    ErrorStatus HSEStartUpStatus;

    /* RCC system reset(for debug purpose) */
    RCC_DeInit();

    /* Enable HSE */
    RCC_HSEConfig(RCC_HSE_ON);

    /* Wait till HSE is ready */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    if(HSEStartUpStatus == SUCCESS)
    {
        /* Enable Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

        /* Flash 2 wait state */
        FLASH_SetLatency(FLASH_Latency_2);

        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1);

        /* PCLK2 = HCLK */
        RCC_PCLK2Config(RCC_HCLK_Div1);

        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config(RCC_HCLK_Div2);

        /* PLLCLK = 8MHz * 9 = 72 MHz */
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

        /* Enable PLL */
        RCC_PLLCmd(ENABLE);

        /* Wait till PLL is ready */
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

        /* Select PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        /* Wait till PLL is used as system clock source */
        while(RCC_GetSYSCLKSource() != 0x08);
    }

    /*****************************************/
    /** SystemFrequency / 1000      1ms      */
    /** SystemFrequency / 100000    10us     */
    /** SystemFrequency / 1000000   1us      */
    /*****************************************/
    while (SysTick_Config(SystemCoreClock / 1000) != 0);
}

static void RCC_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
}

static void GPIO_Config(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /** CAN1 RX **/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /** CAN1 TX **/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /**
     * GPIO_Remap1_CAN1 PINS : PB8 CanRx, PB9 CanTx
     * GPIO_Remap2_CAN1 PINS : PD0 CanRx, PD1 CanTx
     */
    GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
}

/**
  * CAN Baudrate = 200 kBit/s
  * Bit Rate = (CanBus Freq = APB1) / (Prescaler * (BS1 + BS2 + SJW))
  * SJW must be 1
  * 36 MHz / (10 * (12 + 5 + 1))
  * 200 kBit/s
  **/
static void CAN1_Config(void)
{
    CAN_InitTypeDef         CAN_InitStructure;
    CAN_FilterInitTypeDef   CAN_FilterInitStructure;

    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    CAN_InitStructure.CAN_TTCM      = DISABLE;
    CAN_InitStructure.CAN_ABOM      = DISABLE;
    CAN_InitStructure.CAN_AWUM      = DISABLE;
    CAN_InitStructure.CAN_NART      = DISABLE;
    CAN_InitStructure.CAN_RFLM      = DISABLE;
    CAN_InitStructure.CAN_TXFP      = DISABLE;
    CAN_InitStructure.CAN_Mode      = CAN_Mode_Normal;
    CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1       = CAN_BS1_12tq;
    CAN_InitStructure.CAN_BS2       = CAN_BS2_5tq;
    CAN_InitStructure.CAN_Prescaler = 10;

    CAN_Init(CAN1, &CAN_InitStructure);

    CAN_FilterInitStructure.CAN_FilterNumber            = 0;
    CAN_FilterInitStructure.CAN_FilterMode              = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale             = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh            = 0;
    CAN_FilterInitStructure.CAN_FilterIdLow             = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh        = 0;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow         = 0;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment    = CAN_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation        = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}

void NVIC_Config(void)
{
    NVIC_InitTypeDef  NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel                    = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
    if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    {
        CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

        if ((RxMessage.IDE == CAN_ID_STD) && (RxMessage.StdId == 0) && (RxMessage.DLC == 8))
        {

        }
    }
    CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
}


Muhammedd

iyi akşamlar ,hocam bu projeyi tamamladınız mı?

baran123

Evet tamamladım.
Ne ilginçtir ki başka model bir transceiver kullanınca düzeldi. (MAX3051)
MCP2551 STM32'de bir türlü çalışmadı.

Erol YILMAZ


baran123

@Allegro hocam MCP2551 5V olduğu için mi STM32'de problem oluyor ?
STM32 ile çalıştıranlar vardı. Hatta @CLR hocam çalıştırdığını söylemişti.
Ben 3.3 olsun diye MAX3051 kullandım.

Erol YILMAZ

#5
STM32 ile Vio değeri SET edilebilen 5V Transceiver kullanıyorum.

Diğer yandan MCP2551 datasheetini inceleyince 5V besleme verince, 3v3 stm32 ile çalışabilir gibi görünüyor.

Şu anda MCP2551 kullanmanın tek cazibesi piyasada kolayca bulunması olsa da bence sahtesi de bi o kadar çoktur.
Senin devrendeki problemi anlamak için orjinal olduğundan emin olunan bir MCP2551 koyup incelemek lazım.

sadogan

MCP2551 5v besleme ile, 3v3 stm32f103 le çalışıyor.

baran123

Ben 3 tane falan denedim ama nafile sahteler denk geldi herhalde.
Hiçbir değişiklik yapmadan entegreyi söküp MAX3051 taktığımda anında çalışmıştı. :)

sadogan