【CAN】STM32F103VE单片机使用CAN Loopback模式收发数据测试(完全用寄存器实现)

版权声明:本文为博主原创文章,欢迎转载 https://blog.csdn.net/ZLK1214/article/details/84724294

【说明】

程序将CAN引脚重映射到了PD0和PD1引脚上。由于打开了Loopback模式,所以这两个引脚不需要接任何器件,悬空就行。

必须要设置CAN消息过滤寄存器(CAN filter registers)后CAN才可以接收数据。程序将过滤器配置为允许接收所有类型的数据(MASK设为0)。消息内容由rand函数随机产生。

【程序代码】

#include <stdio.h>
#include <stdlib.h>
#include <stm32f10x.h>

// 观察CAN对专用SRAM的改写情况
#define DISPLAY_SRAM 1

int fputc(int ch, FILE *fp)
{
  if (fp == stdout)
  {
    if (ch == '\n')
    {
      while ((USART1->SR & USART_SR_TXE) == 0);
      USART1->DR = '\r';
    }
    while ((USART1->SR & USART_SR_TXE) == 0);
    USART1->DR = ch;
  }
  return ch;
}

#if DISPLAY_SRAM
// 清空专用SRAM内容
static void zero_sram(void)
{
  uint16_t i;
  
  RCC->APB1ENR |= RCC_APB1ENR_USBEN;
  for (i = 0; i < 1024; i += 4)
    *(uint32_t *)(0x40006000 + i) = 0;
  RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
}

// 显示专用SRAM内容
static void dump_sram(void)
{
  uint16_t i, val;
  
  RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN;
  RCC->APB1ENR |= RCC_APB1ENR_USBEN;
  
  printf("[Dedicated SRAM]\n");
  for (i = 0; i < 1024; i += 4)
  {
    val = *(uint16_t *)(0x40006000 + i);
    printf("%02X%02X", val & 0xff, val >> 8);
  }
  printf("\n");
  
  RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
  RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
}
#endif

// 发送CAN消息
static void send_test(void)
{
  char str[20];
  static uint16_t id = 0;
  
  if ((CAN1->TSR & CAN_TSR_TME0) == 0)
  {
    printf("mailbox 0 isn't empty!\n");
    return;
  }
  
  sprintf(str, "%08X", rand()); // 随机生成8字节数据内容
  CAN1->sTxMailBox[0].TDLR = *(uint32_t *)str;
  CAN1->sTxMailBox[0].TDHR = *((uint32_t *)str + 1);
  CAN1->sTxMailBox[0].TDTR = 8;
  CAN1->sTxMailBox[0].TIR = (id << 21) | CAN_TI0R_TXRQ;
  
  while ((CAN1->TSR & CAN_TSR_TXOK0) == 0); // 等待发送完毕
  CAN1->TSR = CAN_TSR_TXOK0; // 清除标志位
  printf("sent! id=0x%03x\n", id);
  id = (id + 1) & 0x7ff;
}

// 接收CAN消息
static void receive_test(void)
{
  char str[9];
  uint16_t id;
  
  str[8] = '\0';
  if (CAN1->RF0R & CAN_RF0R_FMP0)
  {
    id = (CAN1->sFIFOMailBox[0].RIR & CAN_RI0R_STID) >> 21;
    *(uint32_t *)str = CAN1->sFIFOMailBox[0].RDLR;
    *((uint32_t *)str + 1) = CAN1->sFIFOMailBox[0].RDHR;
    CAN1->RF0R = CAN_RF0R_RFOM0;
    
    printf("received! id=0x%03x, data=\"%s\"\n", id, str);
#if DISPLAY_SRAM
    dump_sram();
#endif
  }
}

// 允许接收所有ID的消息
// 注意: 必须要配置这些消息过滤寄存器后, CAN才能接收数据 (复位后FINIT位默认值为1)
static void set_filter(void)
{
  //CAN1->FMR |= CAN_FMR_FINIT; // enter filter init mode
  
  CAN1->FS1R |= CAN_FS1R_FSC0; // single 32-bit scale
  CAN1->sFilterRegister[0].FR1 = 0; // ID: unused because MASK is 0
  CAN1->sFilterRegister[0].FR2 = 0; // MASK: all identifier bits are "don't care"
  CAN1->FA1R |= CAN_FA1R_FACT0; // filter 0 is active
  
  CAN1->FMR &= ~CAN_FMR_FINIT; // exit filter init mode
}

// 用RTC时间产生rand随机种子
static void rand_init(void)
{
  uint32_t div;
  
  RCC->CSR |= RCC_CSR_LSION;
  while ((RCC->CSR & RCC_CSR_LSIRDY) == 0);
  
  if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0)
  {
    RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    PWR->CR |= PWR_CR_DBP;
    RCC->BDCR |= RCC_BDCR_RTCSEL_1 | RCC_BDCR_RTCEN;
    
    RTC->CRL |= RTC_CRL_CNF;
    RTC->PRLH = 0;
    RTC->PRLL = 39999;
    RTC->CRL &= ~RTC_CRL_CNF;
    while ((RTC->CRL & RTC_CRL_RTOFF) == 0);
    printf("RTC is enabled using LSI! ");
  }
  else
  {
    RTC->CRL &= ~RTC_CRL_RSF;
    while ((RTC->CRL & RTC_CRL_RSF) == 0);
    printf("RTC is running! ");
  }
  
  div = (RTC->DIVH << 16) | RTC->DIVL;
  srand(div);
  printf("srand: %u\n", div);
}

int main(void)
{
  uint32_t i = 0;
  
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_USART1EN;
  
  AFIO->MAPR = AFIO_MAPR_CAN_REMAP;
  
  GPIOA->CRH = (GPIOA->CRH & 0xfffff00f) | 0x4b0;
  GPIOD->CRL = (GPIOD->CRL & 0xffffff00) | 0xb4;
  
  USART1->BRR = SystemCoreClock / 115200;
  USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
  printf("STM32F103VE CAN1\n");
  
#if DISPLAY_SRAM
  zero_sram();
  dump_sram();
#else
  RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
#endif
  
  CAN1->MCR = (CAN1->MCR & ~CAN_MCR_SLEEP) | CAN_MCR_INRQ;
  while ((CAN1->MSR & CAN_MSR_INAK) == 0);
  set_filter();
  CAN1->BTR |= CAN_BTR_LBKM; // 回环模式
  CAN1->MCR &= ~CAN_MCR_INRQ;
  while (CAN1->MSR & CAN_MSR_INAK);
  printf("CAN1 OK!\n");
  
  rand_init();
  while (1)
  {
    if (i == 0)
      send_test();
    receive_test();
    
    i++;
    if (i == 1000000)
      i = 0;
  }
}

void HardFault_Handler(void)
{
  printf("Hard Error!\n");
  while (1);
}

【程序运行结果】

STM32F103VE CAN1
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
CAN1 OK!
RTC is enabled using LSI! srand: 39912
sent! id=0x000
received! id=0x000, data="5699A100"
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000003536393941313030010000000800000035363939413130300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x001
received! id=0x001, data="555ACC53"
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000003536393941313030010020000800000035353541434335330000000000000000000000000000000000000000000000000000000000000000000020000800000035353541434335330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x002
received! id=0x002, data="1D1C6173"
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000003536393941313030010040000800000031443143363137330000000000000000000000000000000000000000000000000000000000000000000020000800000035353541434335330000400008000000314431433631373300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x003
received! id=0x003, data="3D9BC74A"
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000080000003344394243373441010060000800000033443942433734410000000000000000000000000000000000000000000000000000000000000000000020000800000035353541434335330000400008000000314431433631373300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x004
received! id=0x004, data="1F487E9E"
[Dedicated SRAM]
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000080000003344394243373441010080000800000031463438374539450000000000000000000000000000000000000000000000000000000000000000000080000800000031463438374539450000400008000000314431433631373300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x005
received! id=0x005, data="15894C99"
[Dedicated SRAM]
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000800000033443942433734410100A0000800000031353839344339390000000000000000000000000000000000000000000000000000000000000000000080000800000031463438374539450000A00008000000313538393443393900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x006
received! id=0x006, data="18225341"
[Dedicated SRAM]
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000800000031383232353334310100C0000800000031383232353334310000000000000000000000000000000000000000000000000000000000000000000080000800000031463438374539450000A00008000000313538393443393900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x007
received! id=0x007, data="42248000"
[Dedicated SRAM]
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000800000031383232353334310100E00008000000343232343830303000000000000000000000000000000000000000000000000000000000000000000000E0000800000034323234383030300000A00008000000313538393443393900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sent! id=0x008
received! id=0x008, data="488A981C"
[Dedicated SRAM]
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000800000031383232353334310100000108000000343838413938314300000000000000000000000000000000000000000000000000000000000000000000E0000800000034323234383030300000000108000000343838413938314300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

由程序运行结果可知,CAN在运行过程中不断地在改写512字节专用内存区中的内容,所以CAN不能和USB同时使用。

猜你喜欢

转载自blog.csdn.net/ZLK1214/article/details/84724294