Files
ch32v20x-examples/EVT/EXAM/CAN/Time-triggered/User/main.c
T
2026-01-07 10:43:29 +08:00

309 lines
8.0 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.1
* Date : 2025/10/27
* Description : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*
*@Note
*CAN time triggered communication mode:
*CAN_Tx(PB9),CAN_Rx(PB8)
*In the Extended_Frame, one 32bit filter mask bit communication configuration,
*the demonstration time triggers the communication mode.
*
*/
#include "debug.h"
/* CAN Mode Definition */
#define TX_MODE 0
#define RX_MODE 1
/* CAN Communication Mode Selection */
//#define CAN_MODE TX_MODE
#define CAN_MODE RX_MODE
/* Global Variable */
u8 txbuf[8];
vu8 tx;
/*********************************************************************
* @fn CAN_Mode_Init
*
* @brief Initializes CAN communication test mode.
* Bps =Fpclk1/((tpb1+1+tbs2+1+1)*brp)
*
* @param tsjw - CAN synchronisation jump width.
* tbs2 - CAN time quantum in bit segment 1.
* tbs1 - CAN time quantum in bit segment 2.
* brp - Specifies the length of a time quantum.
* mode - Test mode.
* CAN_Mode_Normal.
* CAN_Mode_LoopBack.
* CAN_Mode_Silent.
* CAN_Mode_Silent_LoopBack.
*
* @return none
*/
void CAN_Mode_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
{
GPIO_InitTypeDef GPIO_InitSturcture = {0};
CAN_InitTypeDef CAN_InitSturcture = {0};
CAN_FilterInitTypeDef CAN_FilterInitSturcture = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_9;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitSturcture);
GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitSturcture);
CAN_InitSturcture.CAN_TTCM = ENABLE;
CAN_InitSturcture.CAN_ABOM = DISABLE;
CAN_InitSturcture.CAN_AWUM = DISABLE;
CAN_InitSturcture.CAN_NART = ENABLE;
CAN_InitSturcture.CAN_RFLM = DISABLE;
CAN_InitSturcture.CAN_TXFP = DISABLE;
CAN_InitSturcture.CAN_Mode = mode;
CAN_InitSturcture.CAN_SJW = tsjw;
CAN_InitSturcture.CAN_BS1 = tbs1;
CAN_InitSturcture.CAN_BS2 = tbs2;
CAN_InitSturcture.CAN_Prescaler = brp;
CAN_Init(CAN1, &CAN_InitSturcture);
/* identifier/mask mode, One 32-bit filter, ExtId: 0x12124567 */
CAN_FilterInitSturcture.CAN_FilterNumber = 0;
CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x9092;
CAN_FilterInitSturcture.CAN_FilterIdLow = 0x2B3C;
CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0xFFFE;
CAN_FilterInitSturcture.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitSturcture.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitSturcture);
CAN_TTComModeCmd(CAN1, ENABLE);
#if(CAN_MODE == TX_MODE)
CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);
#elif(CAN_MODE == RX_MODE)
CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
#endif
}
#if(CAN_MODE == TX_MODE)
/*********************************************************************
* @fn CAN_Send_Msg
*
* @brief CAN Transmit function.
*
* @param msg - Transmit data buffer.
* len - Data length.
*
* @return 0 - Send successful.
* 1 - Send failed.
*/
u8 CAN_Send_Msg(u8 *msg, u8 len)
{
u8 mbox;
u16 i = 0;
CanTxMsg CanTxStructure;
CanTxStructure.ExtId = 0x12124567;
CanTxStructure.IDE = CAN_Id_Extended;
CanTxStructure.RTR = CAN_RTR_Data;
CanTxStructure.DLC = len;
for(i = 0; i < len; i++) {
CanTxStructure.Data[i] = msg[i];
}
mbox = CAN_Transmit(CAN1, &CanTxStructure);
i = 0;
while((CAN_TransmitStatus(CAN1, mbox) != CAN_TxStatus_Ok) && (i < 0xFFF))
{
i++;
}
if(i == 0xFFF)
{
return 1;
}
else
{
return 0;
}
}
void USB_HP_CAN1_TX_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn USB_HP_CAN1_TX_IRQHandler
*
* @brief This function handles CAN transmit mailboxe Handler.
*
* @return none
*/
void USB_HP_CAN1_TX_IRQHandler(void)
{
u8 i;
if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
{
printf("Send Success\r\n");
printf("Send Data:\r\n");
for(i = 0; i < 8; i++) {
printf("%02x\r\n", txbuf[i]);
}
printf("TDTR:%08x\r\n", CAN1->sTxMailBox[0].TXMDTR);
}
CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
}
#elif(CAN_MODE == RX_MODE)
/*********************************************************************
* @fn CAN_Receive_Msg
*
* @brief CAN Receive function.
*
* @param buf - Receive data buffer.
* len - Data length.
*
* @return CanRxStructure.DLC - Receive data length.
*/
u8 CAN_Receive_Msg(u8 *buf)
{
u8 i;
CanRxMsg CanRxStructure;
if(CAN_MessagePending(CAN1, CAN_FIFO0) == 0)
{
return 0;
}
CAN_Receive(CAN1, CAN_FIFO0, &CanRxStructure);
for(i = 0; i < 8; i++){
buf[i] = CanRxStructure.Data[i];
}
return CanRxStructure.DLC;
}
void USB_LP_CAN1_RX0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn USB_LP_CAN1_RX0_IRQHandler
*
* @brief This function handles CAN receive FIFO0 Handler.
*
* @return none
*/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
u8 rx, i;
u8 rxbuf[8];
if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
{
rx = CAN_Receive_Msg(rxbuf);
if(rx)
{
printf("Receive Data:\r\n");
for(i = 0; i < 8; i++) {
printf("%02x\r\n", rxbuf[i]);
}
}
printf("RDTR:%08x\r\n", CAN1->sFIFOMailBox[0].RXMDTR);
}
CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
}
#endif
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
u8 i = 0;
u8 cnt = 1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n", SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
/* Bps = 250Kbps */
CAN_Mode_Init(CAN_SJW_1tq, CAN_BS2_5tq, CAN_BS1_6tq, 16, CAN_Mode_Normal);
#if(CAN_MODE == TX_MODE)
printf("TX Mode\r\n");
#elif(CAN_MODE == RX_MODE)
printf("RX Mode\r\n");
#endif
while(1)
{
#if(CAN_MODE == TX_MODE)
for(i = 0; i < 8; i++) {
txbuf[i] = cnt + i;
}
tx = CAN_Send_Msg(txbuf, 8);
Delay_Ms(1000);
cnt++;
#endif
}
}