【说明】
程序将CAN引脚重映射到了PD0和PD1引脚上。由于打开了Loopback模式,所以这两个引脚不需要接任何器件,悬空就行。
必须要设置CAN消息过滤寄存器(CAN filter registers)后CAN才可以接收数据。程序将过滤器配置为允许接收所有类型的数据(MASK设为0)。消息内容由rand函数随机产生。
【程序代码】
#include
#include
#include
// 观察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同时使用。