Add CAN module in ch32v208rbt6
Now input test_can to connect CAN bus. 1. Set the IPC CAN speed to 250kbps. The method how to calculate the CAN speed could be seen in init_can of can_test.c. 2. Connect the board to the USBCAN and open the IPC. 3. input test_can command to send the message to the CAN bus so that the USBCAN receives the message. 4. The USBCAN will print the message.
This commit is contained in:
parent
d75e3ad7f9
commit
090b863637
|
@ -28,6 +28,7 @@
|
|||
* @date 2024-4-29
|
||||
*/
|
||||
#include "ch32v20x.h"
|
||||
#include "connect_can.h"
|
||||
#include "connect_uart.h"
|
||||
#include "core_riscv.h"
|
||||
#include "xsconfig.h"
|
||||
|
@ -86,6 +87,9 @@ void InitBoardHardware()
|
|||
#ifdef BSP_USING_BLE
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
#endif
|
||||
#ifdef BSP_USING_CAN
|
||||
InitHwCan();
|
||||
#endif
|
||||
KPrintf("consle init completed.\n");
|
||||
KPrintf("board initialization......\n");
|
||||
|
|
|
@ -17,4 +17,12 @@ menuconfig BSP_USING_ADC
|
|||
menuconfig BSP_USING_BLE
|
||||
bool "Using BLE"
|
||||
default y
|
||||
|
||||
menuconfig BSP_USING_CAN
|
||||
bool "Using CAN device"
|
||||
default y
|
||||
select RESOURCES_CAN
|
||||
if BSP_USING_CAN
|
||||
source "$BSP_DIR/third_party_driver/can/Kconfig"
|
||||
endif
|
||||
|
|
@ -13,4 +13,7 @@ endif
|
|||
ifeq ($(CONFIG_BSP_USING_BLE),y)
|
||||
SRC_DIR += ble
|
||||
endif
|
||||
ifeq ($(CONFIG_BSP_USING_CAN),y)
|
||||
SRC_DIR += can
|
||||
endif
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -62,6 +62,8 @@ void Main_Circulation(void)
|
|||
int test_ble(int argc, char *argv[])
|
||||
{
|
||||
KPrintf("%s\n", VER_LIB);
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
GAPRole_PeripheralInit();
|
||||
Peripheral_Init();
|
||||
KPrintf("BLE Peripheral Slave Init Success.\n");
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := connect_can.c
|
||||
SRC_DIR := test
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,248 @@
|
|||
|
||||
#include <connect_can.h>
|
||||
#include <ch32v20x_gpio.h>
|
||||
#include <ch32v20x_rcc.h>
|
||||
#include <ch32v20x_misc.h>
|
||||
|
||||
static struct CanSendConfigure can_send_deconfig =
|
||||
{
|
||||
.stdid = 0x12,
|
||||
.exdid = 0x12,
|
||||
.ide = 0 ,
|
||||
.rtr = 0,
|
||||
.data_lenth = 8
|
||||
};
|
||||
|
||||
static void CanGPIOInit(void)
|
||||
{
|
||||
CAN_FilterInitTypeDef can1_filter = {0};
|
||||
GPIO_InitTypeDef gpio_initstructure = {0};
|
||||
CAN_InitTypeDef can_initstruction = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOA, ENABLE); // 如果CAN引脚映射到PA,需要设置A时钟源,否则设置成B时钟源
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
||||
|
||||
// GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
|
||||
/* 这里需要和原理图的引脚对应 */
|
||||
gpio_initstructure.GPIO_Pin = GPIO_Pin_12; // CAN1_TX
|
||||
gpio_initstructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio_initstructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &gpio_initstructure); // 初始化引脚
|
||||
gpio_initstructure.GPIO_Pin = GPIO_Pin_11; // CAN1_RX
|
||||
gpio_initstructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOA, &gpio_initstructure); // 初始化引脚
|
||||
}
|
||||
|
||||
static void Can1NvicConfig(void)
|
||||
{
|
||||
NVIC_InitTypeDef can_nvic_config;
|
||||
|
||||
can_nvic_config.NVIC_IRQChannel = CAN1_RX1_IRQn;
|
||||
can_nvic_config.NVIC_IRQChannelPreemptionPriority = 2;
|
||||
can_nvic_config.NVIC_IRQChannelSubPriority = 2;
|
||||
can_nvic_config.NVIC_IRQChannelCmd = ENABLE;
|
||||
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
||||
NVIC_Init(&can_nvic_config);
|
||||
}
|
||||
|
||||
static uint32 CanModeInit(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
CAN_FilterInitTypeDef can1_filter;
|
||||
CAN_InitTypeDef can_initstruction;
|
||||
|
||||
struct CanDriverConfigure *config = ( struct CanDriverConfigure *)configure_info->private_data;
|
||||
|
||||
can_initstruction.CAN_TTCM = DISABLE;
|
||||
can_initstruction.CAN_ABOM = DISABLE;
|
||||
can_initstruction.CAN_AWUM = DISABLE;
|
||||
can_initstruction.CAN_NART = ENABLE;
|
||||
can_initstruction.CAN_TXFP = DISABLE;
|
||||
can_initstruction.CAN_Mode = config->mode;
|
||||
can_initstruction.CAN_RFLM = DISABLE;
|
||||
can_initstruction.CAN_SJW = config->tsjw;
|
||||
can_initstruction.CAN_BS1 = config->tbs1;
|
||||
can_initstruction.CAN_BS2 = config->tbs2;
|
||||
can_initstruction.CAN_Prescaler = config->brp;
|
||||
|
||||
CAN_Init(CAN1, &can_initstruction);
|
||||
|
||||
can1_filter.CAN_FilterNumber=0;
|
||||
can1_filter.CAN_FilterMode=CAN_FilterMode_IdMask;
|
||||
can1_filter.CAN_FilterScale=CAN_FilterScale_32bit;
|
||||
can1_filter.CAN_FilterIdHigh=0x0000;
|
||||
can1_filter.CAN_FilterIdLow=0x0000;
|
||||
can1_filter.CAN_FilterMaskIdHigh=0x0000;
|
||||
can1_filter.CAN_FilterMaskIdLow=0x0006;
|
||||
can1_filter.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;
|
||||
can1_filter.CAN_FilterActivation=ENABLE;
|
||||
CAN_FilterInit(&can1_filter);
|
||||
|
||||
#ifdef CAN_USING_INTERRUPT
|
||||
Can1NvicConfig();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 CanSendMsg(void * dev , struct BusBlockWriteParam *write_param )
|
||||
{
|
||||
NULL_PARAM_CHECK(write_param);
|
||||
|
||||
uint8 *data = (uint8 * ) write_param->buffer;
|
||||
u8 messege_box;
|
||||
u16 i = 0;
|
||||
u16 timer_count = 1000;
|
||||
CanTxMsg tx_data;
|
||||
tx_data.StdId = 0x55;
|
||||
tx_data.ExtId = 0x00;
|
||||
tx_data.IDE = 0;
|
||||
tx_data.RTR = 0;
|
||||
tx_data.DLC = write_param->size;
|
||||
|
||||
for(i = 0;i < tx_data.DLC;i ++) {
|
||||
tx_data.Data[i] = data[i];
|
||||
}
|
||||
|
||||
messege_box = CAN_Transmit(CAN1,&tx_data);
|
||||
|
||||
while (CAN_TransmitStatus(CAN1,messege_box)== CAN_TxStatus_Failed &&timer_count) {
|
||||
timer_count--;
|
||||
}
|
||||
|
||||
if (timer_count<=0) {
|
||||
return ERROR;
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 CanRecvMsg(void *dev , struct BusBlockReadParam *databuf)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
int i;
|
||||
uint8 * buf = (uint8 *)databuf->buffer;
|
||||
CanRxMsg msg;
|
||||
if (CAN_MessagePending(CAN1, CAN_FIFO0) == 0)
|
||||
return 0;
|
||||
CAN_Receive(CAN1, CAN_FIFO0, &msg);
|
||||
for(i = 0 ;i < msg.DLC;i ++)
|
||||
buf[i] = msg.Data[i];
|
||||
databuf->size = msg.DLC ;
|
||||
|
||||
return msg.DLC;
|
||||
}
|
||||
|
||||
static struct CanDevDone dev_done =
|
||||
{
|
||||
.open = NONE,
|
||||
.close = NONE,
|
||||
.write = CanSendMsg,
|
||||
.read = CanRecvMsg
|
||||
};
|
||||
|
||||
static struct CanHardwareDevice dev;
|
||||
|
||||
#ifdef CAN_USING_INTERRUPT
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
CanRxMsg rxmsg;
|
||||
int i = 0;
|
||||
CAN_Receive(CAN1, 0, &rxmsg);
|
||||
for (i = 0;i < 8;i ++)
|
||||
KPrintf("rxbuf [%d] = :%d",i,rxmsg.Data[i]);
|
||||
}
|
||||
DECLARE_HW_IRQ(CAN1_RX0_IRQn, CAN1_RX0_IRQHandler, NONE);
|
||||
#endif
|
||||
|
||||
static int BoardCanBusInit(struct CanDev *CanDev_bus, struct CanDriver *can_driver)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
/*Init the can bus */
|
||||
ret = CanBusInit(&CanDev_bus->can_bus, CanDev_bus->bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_can_init canBusInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Init the can driver*/
|
||||
ret = CanDriverInit(can_driver, CAN_DRIVER_NAME);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_can_init canDriverInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Attach the can driver to the can bus*/
|
||||
ret = CanDriverAttachToBus(CAN_DRIVER_NAME, CanDev_bus->bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_can_init CanDriverAttachToBus error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static x_err_t HwCanDeviceAttach(const char *bus_name, const char *device_name)
|
||||
{
|
||||
NULL_PARAM_CHECK(bus_name);
|
||||
NULL_PARAM_CHECK(device_name);
|
||||
|
||||
x_err_t result;
|
||||
struct CanHardwareDevice *can_device;
|
||||
|
||||
/* attach the device to can bus*/
|
||||
can_device = (struct CanHardwareDevice *)x_malloc(sizeof(struct CanHardwareDevice));
|
||||
CHECK(can_device);
|
||||
memset(can_device, 0, sizeof(struct CanHardwareDevice));
|
||||
can_device->dev_done = &dev_done;
|
||||
|
||||
result = CanDeviceRegister(can_device, NONE, device_name);
|
||||
if (EOK != result) {
|
||||
KPrintf("board_can_init canDeviceInit device %s error %d\n", "can1", result);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
result = CanDeviceAttachToBus(device_name, bus_name);
|
||||
if (result != EOK) {
|
||||
SYS_ERR("%s attach to %s faild, %d\n", device_name, bus_name, result);
|
||||
}
|
||||
|
||||
CHECK(result == EOK);
|
||||
|
||||
KPrintf("%s attach to %s done\n", device_name, bus_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct CanDev can1;
|
||||
|
||||
int InitHwCan(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
struct CanDev *can_bus;
|
||||
|
||||
static struct CanDriver can_driver;
|
||||
memset(&can_driver, 0, sizeof(struct CanDriver));
|
||||
can_driver.configure = CanModeInit;
|
||||
|
||||
CanGPIOInit();
|
||||
can_bus = &can1;
|
||||
can_bus->instance = CAN1;
|
||||
can_bus->bus_name = CAN_BUS_NAME_1;
|
||||
can_bus->can_bus.private_data = &can1;
|
||||
|
||||
ret = BoardCanBusInit(can_bus, &can_driver);
|
||||
|
||||
if (EOK != ret) {
|
||||
KPrintf(" can_bus_init %s error ret %u\n", can_bus->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = HwCanDeviceAttach(CAN_BUS_NAME_1,CAN_1_DEVICE_NAME_1);
|
||||
if (EOK != ret) {
|
||||
KPrintf(" HwCanDeviceAttach %s error ret %u\n", can_bus->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
return EOK;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
SRC_FILES := can_test.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan
|
||||
* PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
|
||||
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
|
||||
* Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file can_test.c
|
||||
* @brief test ch32v307 can
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-03-14
|
||||
*/
|
||||
#include <ch32v20x_gpio.h>
|
||||
#include <ch32v20x_misc.h>
|
||||
#include <ch32v20x_rcc.h>
|
||||
|
||||
#include "ch32v20x.h"
|
||||
#include "connect_can.h"
|
||||
#include "debug.h"
|
||||
#include "shell.h"
|
||||
|
||||
/* CAN Mode Definition */
|
||||
#define TX_MODE 0
|
||||
#define RX_MODE 1
|
||||
|
||||
/* Frame Format Definition */
|
||||
#define Standard_Frame 0
|
||||
#define Extended_Frame 1
|
||||
|
||||
/* CAN Communication Mode Selection */
|
||||
#define CAN_MODE TX_MODE
|
||||
// #define CAN_MODE RX_MODE
|
||||
|
||||
/* Frame Formate Selection */
|
||||
#define Frame_Format Standard_Frame
|
||||
// #define Frame_Format Extended_Frame
|
||||
|
||||
/*********************************************************************
|
||||
* @fn CAN_Mode_Init
|
||||
*
|
||||
* @brief Initializes CAN communication test mode.
|
||||
* Bps =Fpclk1/((tpb1+1+tbs2+1+1)*brp)
|
||||
* 波特率设置https://www.cnblogs.com/wchmcu/p/17546797.html
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
static int init_can(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode) {
|
||||
CAN_InitTypeDef CAN_InitSturcture = {0};
|
||||
CAN_FilterInitTypeDef CAN_FilterInitSturcture = {0};
|
||||
|
||||
CAN_InitSturcture.CAN_TTCM = DISABLE;
|
||||
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);
|
||||
|
||||
CAN_FilterInitSturcture.CAN_FilterNumber = 0;
|
||||
|
||||
#if (Frame_Format == Standard_Frame)
|
||||
/* identifier/mask mode, One 32-bit filter, StdId: 0x317 */
|
||||
CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdMask;
|
||||
CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_32bit;
|
||||
CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x62E0;
|
||||
CAN_FilterInitSturcture.CAN_FilterIdLow = 0;
|
||||
CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0xFFE0;
|
||||
CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0x0006;
|
||||
|
||||
/* identifier/mask mode, Two 16-bit filters, StdId: 0x317锟斤拷0x316 */
|
||||
// CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdMask;
|
||||
// CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_16bit;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x62E0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdLow = 0xFFF8;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0x62C0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0xFFF8;
|
||||
|
||||
/* identifier list mode, One 32-bit filter, StdId: 0x317锟斤拷0x316 */
|
||||
// CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdList;
|
||||
// CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_32bit;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x62E0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdLow = 0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0x62C0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0;
|
||||
|
||||
/* identifier list mode, Two 16-bit filters, StdId: 0x317,0x316,0x315,0x314
|
||||
*/
|
||||
// CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdList;
|
||||
// CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_16bit;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x62E0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterIdLow = 0x62C0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0x62A0;
|
||||
// CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0x6280;
|
||||
|
||||
#elif (Frame_Format == Extended_Frame)
|
||||
/* identifier/mask mode, One 32-bit filter, ExtId: 0x12124567 */
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
CAN_FilterInitSturcture.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
|
||||
CAN_FilterInitSturcture.CAN_FilterActivation = ENABLE;
|
||||
CAN_FilterInit(&CAN_FilterInitSturcture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 CAN_Send_Msg(u8 *msg, u8 len) {
|
||||
u8 mbox;
|
||||
u16 i = 0;
|
||||
|
||||
CanTxMsg CanTxStructure;
|
||||
|
||||
CanTxStructure.StdId = 0x317;
|
||||
CanTxStructure.IDE = CAN_Id_Standard;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 CAN_Receive_Msg(u8 *buf) {
|
||||
u8 i;
|
||||
|
||||
CanRxMsg CanRxStructure;
|
||||
|
||||
if (CAN_MessagePending(CAN1, CAN_FIFO1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAN_Receive(CAN1, CAN_FIFO1, &CanRxStructure);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
buf[i] = CanRxStructure.Data[i];
|
||||
}
|
||||
|
||||
return CanRxStructure.DLC;
|
||||
}
|
||||
|
||||
int test_can(int argc, char *argv[]) {
|
||||
u8 i;
|
||||
u8 cnt = 0;
|
||||
u8 tx, rx;
|
||||
u8 txbuf[8];
|
||||
u8 rxbuf[8];
|
||||
init_can(
|
||||
CAN_SJW_1tq, CAN_BS2_5tq, CAN_BS1_6tq, 20,
|
||||
CAN_Mode_Normal); // 在这种参数下,设置时钟源为外部时钟120M,对应的波特率是250kbps
|
||||
#if (CAN_MODE == TX_MODE)
|
||||
for (cnt = 0; cnt < 8; cnt++) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
txbuf[i] = cnt + i;
|
||||
}
|
||||
tx = CAN_Send_Msg(txbuf, 8);
|
||||
|
||||
if (tx) {
|
||||
KPrintf("CAN1 Send Failed\r\n");
|
||||
} else {
|
||||
KPrintf("CAN1 Send Success\r\n");
|
||||
KPrintf("CAN1 Send Data:\r\n");
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
KPrintf("%02x\r\n", txbuf[i]);
|
||||
}
|
||||
}
|
||||
Delay_Ms(1000);
|
||||
}
|
||||
#elif (CAN_MODE == RX_MODE)
|
||||
rx = CAN_Receive_Msg(rxbuf);
|
||||
|
||||
if (rx) {
|
||||
KPrintf("CAN1 Receive Data:\r\n");
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
KPrintf("%02x\r\n", txbuf[i]);
|
||||
}
|
||||
} else {
|
||||
KPrintf("CAN1 No Receive Data\r\n");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
test_can, test_can, test CAN);
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef CONNECT_CAN_H
|
||||
#define CONNECT_CAN_H
|
||||
|
||||
|
||||
#include <bus_can.h>
|
||||
#include <dev_can.h>
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
#include <ch32v20x_can.h>
|
||||
|
||||
|
||||
struct CanDev
|
||||
{
|
||||
CAN_TypeDef *instance;
|
||||
|
||||
char *bus_name;
|
||||
|
||||
// CAN_InitTypeDef init;
|
||||
|
||||
uint8 can_flag;
|
||||
struct CanBus can_bus;
|
||||
};
|
||||
|
||||
int InitHwCan(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue