STM32 Canbus Problemi - MCP2551

Başlatan baran123, 01 Mart 2017, 15:36:47

baran123

Merhaba,
2 tane PIC18F46K80'i CANBus ile haberleştirdim fakat STM32F103C8 ile PIC18F46K80 bir türlü haberleşmeyi sağlayamadım.
ikiside 200 kBit/s ayarlı fakat stm32 den sonraki MCP2551'e baktığımda fiziksel hatta hiç bir veri göremiyorum (Salea Logic Analyzer)
Fakat stm32 loopback modu yaptım çalışıyor normal moda alınca hiç bir şey yapamıyorum. MCP2551'i 5V ile besliyorum. İlk denemem bozuk olacağını pek sanmıyorum ama bu da bir ihtimal.
Sizce ben nerede hata yapıyorum ?

#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);
}


Interrupt rutini
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);
}


Veri yollama
void SysTick_Handler(void)
{
    static volatile uint32_t sysTickCounter = 0;

    uint8_t canTxStatus;

    if (sysTickCounter == 1000)
    {
        sysTickCounter = 0;
        canTxStatus = CAN_Transmit(CAN1, &TxMessage);

        if (canTxStatus == CAN_TxStatus_Ok)
            LED_ON();
    }
    else
        sysTickCounter++;
}

skara1214

10k pull up at pinlere ilk olarak. 200 k ayarlaman birşey ifade etmez 4-5 tane alan var 1 bitin içinde onlarıda düzgün ayarlaman gerekiyor
Herkes ölür ama herkes gerçekten yaşamaz

baran123

Hocam 2 tarafıdna hızı aynı olması yeterlimi yoksa örnekleme noktalarını da eşit yapmak gerekiyor mu ?

Hocam şuan da CAN_RX ve CAN_TX 10k pull-up(+5V)
hatta sadece stm32 takılı alıcıyı takmadım
120 ohm direnç de ekli
Fakat logicde bir şey göremiyorum.

skara1214

10k takmayınca canbus init olmuyordu, onu hatırlıyorum(surekli hatta hata var olarak algılıyordu.) Debug yaparak hataları inceleyebilirmisiniz? yuksek ihtimal hızla alakalı olmadan hataların birisi yüzünden datayı basmıyordur.
Herkes ölür ama herkes gerçekten yaşamaz

baran123

#4
Hocam periyodik olarak gönderdiğim veriye bakıyorum debug ile transmit fonksiyonu sürekli olarak "CAN_TxStatus_NoMailBox" değerine ulaşıyor.
Bit alanını yeniden düzenledim fakat hız aynı değerde.
BS1 = 4
BS2 = 4
SJW = 1
Prescaler = 20

magnetron

"USB_LP_CAN1_RX0_IRQHandler"

hocam beni 3 gün tırmalattı bu

"USB_LP_CAN_RX0_IRQHandler" yaptım düzeldi

baran123

@magnetron  hocam NVIC kısmına şunu yazınca hata veriyor. "USB_LP_CAN_RX0_IRQn"
Emin misiniz böyle olduğuna ? Ben STM32F103C8T6 ile çalışıyorum sizin işlemciniz farklı ise interrupt handlerı farklı olabilir

magnetron

#7
baran hocam NVIC kısmını _CAN_ yapınca hata veriyor doğru

ben sadece interrupt handlerin fonksiyon ismini dediğim gibi değiştirdim
o zaman çalıştı

benim işlemci F103RC

baran123

@magnetron yaptım fakat yine aynı  zaten benim şuan uğraştığım problem veri yollamada daha alma ile ilgili bir şey yapmadım.