1 | // Programm: CAN Funktionen
|
2 | // Achtung! KEINE GLEICHZEITIGE NUTZUNG MIT USB MÖGLICH!!!
|
3 | // Mikrocontroller: STM32F103RE
|
4 | // Speicher: 512KB FLASH, 64KB SRAM
|
5 | // Taktfrequenz: 8MHz, PLL: 72MHz
|
6 |
|
7 | // System-Inlude
|
8 | #include <stddef.h>
|
9 | #include "stm32f10x.h"
|
10 |
|
11 | #include <string.h> // Stringfunktion
|
12 | #include <stdio.h> // Standardfunktion
|
13 | #include <stdlib.h> // Standardbibliothek
|
14 |
|
15 | //***********************************************************************************************
|
16 | // CAN Initialisierung
|
17 | //***********************************************************************************************
|
18 | void init_can (void) {
|
19 | CAN_InitTypeDef CAN_InitStructure;
|
20 | CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
21 | NVIC_InitTypeDef NVIC_InitStructure;
|
22 |
|
23 | // CAN RX0 Interrupt
|
24 | NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
25 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
26 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
27 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
28 | NVIC_Init(&NVIC_InitStructure);
|
29 |
|
30 |
|
31 | // CAN1 Periph clock enable
|
32 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // CAN1 Takt freigeben
|
33 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // AFIO Takt freigeben (für Remapping)
|
34 |
|
35 | // PB8 als GPIO_Mode_IPU, PB9 als GPIO_Mode_AF_PP definiert (50MHz!)
|
36 | // Remapping CANRX und CANTX von PA11 und PA12 auf PB8 und PB9
|
37 | // (PA11/12 sind die USB-Pins)
|
38 | GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
|
39 |
|
40 | // CAN Register init
|
41 | CAN_DeInit(CAN1);
|
42 | CAN_StructInit(&CAN_InitStructure);
|
43 |
|
44 | // CAN cell init
|
45 | CAN_InitStructure.CAN_TTCM=DISABLE;
|
46 | CAN_InitStructure.CAN_ABOM=DISABLE;
|
47 | CAN_InitStructure.CAN_AWUM=DISABLE;
|
48 | CAN_InitStructure.CAN_NART=DISABLE;
|
49 | CAN_InitStructure.CAN_RFLM=DISABLE;
|
50 | CAN_InitStructure.CAN_TXFP=DISABLE;
|
51 | CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
|
52 | //CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
53 |
|
54 | // CAN Bitrate
|
55 | CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; // SJW (1 bis 4 möglich)
|
56 | CAN_InitStructure.CAN_BS1=CAN_BS1_12tq; // Samplepoint 72%
|
57 | CAN_InitStructure.CAN_BS2=CAN_BS2_5tq; // Samplepoint 72%
|
58 |
|
59 | //CAN_InitStructure.CAN_Prescaler=1; // 2000 kbit/s
|
60 | //CAN_InitStructure.CAN_Prescaler=2; // 1000 kbit/s
|
61 | //CAN_InitStructure.CAN_Prescaler=4; // 500 kbit/s
|
62 | //CAN_InitStructure.CAN_Prescaler=5; // 400 kbit/s
|
63 | //CAN_InitStructure.CAN_Prescaler=8; // 250 kbit/s
|
64 | //CAN_InitStructure.CAN_Prescaler=10; // 200 kbit/s
|
65 | //CAN_InitStructure.CAN_Prescaler=16; // 125 kbit/s
|
66 | CAN_InitStructure.CAN_Prescaler=20; // 100 kbit/s
|
67 | //CAN_InitStructure.CAN_Prescaler=40; // 50 kbit/s
|
68 | //CAN_InitStructure.CAN_Prescaler=80; // 40 kbit/s
|
69 | //CAN_InitStructure.CAN_Prescaler=200; // 10 kbit/s
|
70 | //CAN_InitStructure.CAN_Prescaler=1023; // ganz langsam
|
71 |
|
72 | CAN_Init(CAN1, &CAN_InitStructure);
|
73 |
|
74 | // CAN filter init
|
75 | CAN_FilterInitStructure.CAN_FilterNumber=1;
|
76 | CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
|
77 | CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
|
78 | CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
|
79 | CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
|
80 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
|
81 | CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
|
82 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
|
83 | CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
|
84 | CAN_FilterInit(&CAN_FilterInitStructure);
|
85 |
|
86 | // CAN FIFO0 message pending interrupt enable
|
87 | CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
88 | }
|
89 |
|
90 | //***********************************************************************************************
|
91 | // CAN Messange senden
|
92 | //***********************************************************************************************
|
93 | void can_send_test (void) {
|
94 | uint8_t CanMailBox;
|
95 | uint8_t CanTxStatus;
|
96 |
|
97 | printf_tft(1,60,"CAN Test: Senden einer Message");
|
98 |
|
99 | // CAN Message senden
|
100 | CanTxMessage.StdId=0x00;
|
101 | CanTxMessage.ExtId=0x1234;
|
102 | CanTxMessage.IDE=CAN_ID_EXT;
|
103 | CanTxMessage.RTR=CAN_RTR_DATA;
|
104 | CanTxMessage.DLC=3;
|
105 | CanTxMessage.Data[0] = 'P';
|
106 | CanTxMessage.Data[1] = 'R';
|
107 | CanTxMessage.Data[2] = 'O';
|
108 | CanMailBox = CAN_Transmit(CAN1, &CanTxMessage); // Rückgabe Mailbox-Nr. 0,1,3 (4=keine Mailbox frei)
|
109 | if (CanMailBox == CAN_NO_MB) {
|
110 | // Mailboxen voll mit ungesendeten Messages
|
111 | printf_tft(1,75,"--> keine Mailbox frei");
|
112 | } else {
|
113 | // Mailbox verfügbar
|
114 | // Sendevorgang läuft
|
115 | sprintf(tft.buffer,"--> Mailbox-Nr.: %u",CanMailBox);
|
116 | printf_tft(1,75,tft.buffer);
|
117 | while(1) {
|
118 | CanTxStatus = CAN_TransmitStatus(CAN1, CanMailBox); // Rückgabe 0=Fehler, 1=ok, 2=senden läuft noch
|
119 |
|
120 | sprintf(tft.buffer,"--> TxStatus: %u",CanTxStatus);
|
121 | printf_tft(1,90,tft.buffer);
|
122 | if (CanTxStatus == CANTXPENDING) {
|
123 | // Message Sendevorgang läuft gerade
|
124 | printf_tft(1,105,"--> Sendevorgang aktiv!");
|
125 |
|
126 | sprintf(tft.buffer,"EWG:%u EPV:%u BOF:%u TEC:%u",CAN_GetFlagStatus(CAN1, CAN_FLAG_EWG),CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV), CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF), (uint16_t)(CAN1->ESR >> 16) & 0x000000FF);
|
127 | printf_tft(1,120,tft.buffer);
|
128 |
|
129 | }
|
130 | if (CanTxStatus == CANTXFAILE) { // CANTXFAILED bis V3.4.0 - V3.5.0 dann CANTXFAILE
|
131 | // Fehler Message nicht gesendet
|
132 | printf_tft(1,135,"--> Senden nicht erfolgreich");
|
133 | break;
|
134 | }
|
135 | if (CanTxStatus == CANTXOK) {
|
136 | // Message gesendet und bestätigt
|
137 | printf_tft(1,135,"--> Senden OK");
|
138 | break;
|
139 | }
|
140 | }
|
141 | }
|
142 | }
|
143 |
|
144 | ...
|
145 |
|
146 | // Interrupt Handler
|
147 | /*******************************************************************************
|
148 | * USB_LP_CAN1_RX0_IRQHandler
|
149 | *******************************************************************************/
|
150 | void USB_LP_CAN1_RX0_IRQHandler(void) {
|
151 |
|
152 | /*
|
153 | if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) == SET) {
|
154 | // CAN Fifo0 Receive
|
155 | CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
|
156 | }
|
157 | if (CAN_GetITStatus(CAN1, CAN_IT_FOV0) == SET) {
|
158 | // CAN Fifo0 Receive Overrun
|
159 | CAN_ClearITPendingBit(CAN1, CAN_IT_FOV0);
|
160 | }
|
161 | if (CAN_GetITStatus(CAN1, CAN_IT_FF0) == SET) {
|
162 | // CAN Fifo0 Receive Buffer full
|
163 | CAN_ClearITPendingBit(CAN1, CAN_IT_FF0);
|
164 | }
|
165 | */
|
166 | CAN_Receive(CAN1, CAN_FIFO0, &CanRxMessage);
|
167 |
|
168 | // if((CanRxMessage.ExtId==0x1234) && (CanRxMessage.IDE==CAN_ID_EXT) && (CanRxMessage.DLC==3)) {
|
169 | CanRxReady = 1;
|
170 | // }
|
171 | }
|