凌云物联网实验室ISKBoard(IoT Starter Kits Board)开发板项目源码
guowenxue
2023-04-04 204613ab0b84b39c707900d276b5ff35ce67d96e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"
 
/* USER CODE BEGIN 0 */
#include "comport.h"
 
//#define CONFIG_CAN_DEBUG
#ifdef  CONFIG_CAN_DEBUG
#define can_print(format,args...) printf(format, ##args)
#else
#define can_print(format,args...) do{} while(0)
#endif
/* USER CODE END 0 */
 
CAN_HandleTypeDef hcan1;
 
/* CAN1 init function */
void MX_CAN1_Init(void)
{
 
  /* USER CODE BEGIN CAN1_Init 0 */
    CAN_FilterTypeDef can1FilterConfig;
  /* USER CODE END CAN1_Init 0 */
 
  /* USER CODE BEGIN CAN1_Init 1 */
 
  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 10;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
  can1FilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  can1FilterConfig.FilterIdHigh = 0x0000;
  can1FilterConfig.FilterIdLow = 0x0000;
  can1FilterConfig.FilterMaskIdHigh = 0x0000;
  can1FilterConfig.FilterMaskIdLow = 0x0000;
  can1FilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  can1FilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  can1FilterConfig.FilterBank = 0;
  can1FilterConfig.SlaveStartFilterBank = 13;
  can1FilterConfig.FilterActivation = CAN_FILTER_ENABLE; //使能过滤ï¿????
  if(HAL_CAN_ConfigFilter(&hcan1, &can1FilterConfig) != HAL_OK)
  {
      Error_Handler();
  }
  if(HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
      Error_Handler();
  }
  can_init(&hcan1);
  /* USER CODE END CAN1_Init 2 */
 
}
 
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */
 
  /* USER CODE END CAN1_MspInit 0 */
    /* CAN1 clock enable */
    __HAL_RCC_CAN1_CLK_ENABLE();
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */
 
  /* USER CODE END CAN1_MspInit 1 */
  }
}
 
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
 
  if(canHandle->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspDeInit 0 */
 
  /* USER CODE END CAN1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN1_CLK_DISABLE();
 
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
 
    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspDeInit 1 */
 
  /* USER CODE END CAN1_MspDeInit 1 */
  }
}
 
/* USER CODE BEGIN 1 */
can_t can={-1, NULL};
uint8_t aRxData[COMM_RXBUFSIZE];//不能太小
 
CAN_RxHeaderTypeDef         hCAN1_RxHeader; //接收报文定义结构ï¿???
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    can_t                      *cans = &can;
    uint8_t                  i;
 
    /* Check can receive ringbuffer */
    if( cans->fd<0 || !cans->xRxBuffer.buffer || !rb_free_size(&cans->xRxBuffer) )
    {
        return;
    }
 
    /* Put the receive byte data into Ringbuffer */
    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &hCAN1_RxHeader, aRxData) == HAL_OK)
    {
        can_print("\r\nGet Rx Message Success!!\r\n");
        can_print("[ID]:0x%lX [DLC]:%ld [Data]:", hCAN1_RxHeader.StdId, hCAN1_RxHeader.DLC);
 
        for(i=0; i<hCAN1_RxHeader.DLC; i++)
            can_print("%X ", aRxData[i]);
        can_print("\r\n");
    }
    else
    {
        can_print("\r\nGet Rx Message error!!\r\n");
        return;
    }
    rb_write(&cans->xRxBuffer, aRxData, 8);
}
 
can_t *can_init(CAN_HandleTypeDef *hcan)
{
    can_t              *cans = &can;
    rb_init(&can.xRxBuffer, aRxData, sizeof(aRxData));
    // è§¦å‘唤醒的字节数,流缓冲区中必须存在不少该字节数的数据才能唤醒等待数据的任务
    //(设置为0时,将按照如1的方式处理,设置的数比buffer_size还大时,创建无效ï¿???
 
    if( !cans )
    {
        return NULL;
    }
 
    can.fd = 3;
 
    if (HAL_CAN_Start(&hcan1) != HAL_OK)    //å¼?启CAN
    {
        can_print("start can Error_Handler ....\r\n");
        Error_Handler();
    }
 
    return cans;
}
 
void can_term(can_t *pcan)
{
    if( !pcan )
        return;
 
    pcan->fd = -1;
 
    if( pcan->xRxBuffer.buffer )
    {
        rb_clear(&pcan->xRxBuffer);
    }
 
    return;
}
/*
 * @brief: CAN Send Message.
 * @param: "TxData[]" stored the message of ready to send, which length must between 0 and 8.
 * @param: "length" stored the number of the data (one data is 8 bit) of ready to send.
 * @retval: Tx_Error: send error; other: the mailbox which has been used, this parameter can be a CAN_TX_MAILBOX0,
 *                                                                                            CAN_TX_MAILBOX1,
 *                                                                                            CAN_TX_MAILBOX2.
 */
 
CAN_TxHeaderTypeDef          Tx_pHeader;     //发�?�报文定义结构体
int can_send(can_t *pcan, char *data, int bytes)
{
    if( !pcan || !data || bytes<=0 )
    {
        return -1;
    }
 
    //发�?�函数的改写
    uint32_t TxMailboxNumber = 0x00000000U;    // å­˜å‚¨æœ¬æ¬¡å‘�?�所使用邮箱的邮箱号
 
    Tx_pHeader.StdId = 0x122;    /*!标准ID。参数�?�只能是 0 ï¿??? 0x7FF(二进制的11ï¿???1) */
    Tx_pHeader.ExtId = 0x0000;      /*!扩展ID。参数�?�只能是 0 ï¿??? 0x1FFFFFFF(二进制的29ï¿???1)*/
    Tx_pHeader.IDE = CAN_ID_STD;    /*!IDE。HAL库编程时,标准帧填写CAN_ID_STD,扩展帧填写CAN_ID_EXT */
    Tx_pHeader.RTR = CAN_RTR_DATA;  /*!RTR。HAL库编程时,数据帧填写CAN_RTR_DATA,遥控帧填写CAN_RTR_REMOTE */
    Tx_pHeader.DLC = bytes;    /*!DLC。数据长度,参数值只能是 0 ï¿??? 8 */
    Tx_pHeader.TransmitGlobalTime = DISABLE;
 
    //ï¿??? Tx é‚®ç®±ä¸­å¢žåŠ ä¸€ä¸ªæ¶ˆï¿???,并且ï¿???活对应的传输请求
    if(HAL_CAN_AddTxMessage(&hcan1, &Tx_pHeader, (uint8_t *)data, &TxMailboxNumber) != HAL_OK)
    {
        return -1;
    }
    return 0;
}
 
int can_recv(can_t *pcan, char *buf, int size, uint32_t timeout)
{
    uint32_t          tickstart = 0;
    size_t            bytes = 0;
 
    if( !pcan || !buf || size<=0 )
        return -1;
 
    if( !pcan->xRxBuffer.buffer )
        return -2;
 
    tickstart = HAL_GetTick();
 
//    bytes = rb_data_size(&can->xRxBuffer);
    can_print("bytes is %d\r\n", bytes);
 
    while((HAL_GetTick() - tickstart) < timeout)
    {
        bytes = rb_data_size(&pcan->xRxBuffer);
        HAL_Delay(10);
 
        /* can received data before but not receive in 10ms now, maybe data receive over */
        if( bytes>0 && rb_data_size(&pcan->xRxBuffer)==bytes )
        {
            break;
        }
    }
 
    bytes = rb_data_size( &pcan->xRxBuffer );
    if( !bytes )
    {
        return 0;
    }
    bytes = bytes>size ? size : bytes;
 
    can_print("bytes=%d size=%d\r\n", bytes, size);
 
    rb_read(&pcan->xRxBuffer, (uint8_t *)buf, bytes);
 
    return bytes;
}
 
/* USER CODE END 1 */