STM32の下のCAN通信のデバッグ
CANは、コントローラエリアネットワーク(以下、CANと称する)の略で、ISO国際標準シリアル通信プロトコルです。現在の自動車業界では、安全性、快適性、利便性、低公害、低コスト要件のために、様々な電子制御システムは、それを開発しています。これらのシステムおよび信頼性要件との間の通信に使用されるデータ型が変化するので、バス構成の数が多く、複数のワイヤハーネスも増加あります。複数のLAN、高速データ通信多数のスルー「「ハーネスの数を減少させる」必要性を満たすために、」1986年ドイツの電気サプライヤーボッシュは車指向CAN通信プロトコルを開発しました。その後、CANは現在、ヨーロッパでは車載ネットワークのための標準プロトコルであり、ISO11898及びISO11519によって標準化されました。
さて、CANの高い性能と信頼性は、広く産業用オートメーション、海洋、医療機器、産業機器に使用されるというように、認識されています。フィールドバスは、自動化技術、自動化の分野として知られているコンピュータのローカルエリアネットワークの熱い分野の一つ、今日です。信頼性の高いデータ通信が強力なサポートを提供し、ノード間でリアルタイムに分散制御システムとして表示されます。
2つのCANコントローラとの間の電位差は、バスラインレベルを決定します。バスレベルがドミナントレベルと劣性レベル分けされ、それは1でなければなりません。送信者は、それが受信者にメッセージを送信し、バスレベルによって変更されます。
STM32は、すなわち、基本拡張CAN bxCAN、付属しています。これは、CANプロトコル2.0Aおよび2.0Bをサポートしています。その設計目標は、効率的に大量のパケットを受信し処理するために、CPUの負荷を最小限に抑えることです。また、優先順位の要件(ソフトウェア設定可能な優先度のプロパティ)パケットて送信をサポートしています。安全上重要なアプリケーションのために、bxCANはタイムトリガ通信モードのハードウェア機能のために必要なすべてのサポートを提供しています。
STM32 bxCANの主な機能は次のとおりです。
LサポートCANプロトコル2.0Aおよび2.0Bアクティブモード
最大1Mbpsリットルのボーレート
lはタイムトリガ通信をサポートしています
3つの送信メールボックスを有するL
Lは、2つの受信FIFO 3の深さを有します
L可変フィルタセット(28まで)
STM32コネクティビティ2つのCANコントローラと製品、および強化され、相互接続されていないタイプ属しSTM32F103ZET6、唯一のCANコントローラで
STM32識別子は複素フィルタのものであり、その存在は、CAN通信を処理するCPUのオーバーヘッドを減少させます。STM32は、フィルタ28(ネットワークタイプ)が、唯一の14 STM32F103ZET6(拡張)を設定し、各フィルタバンク32は二つのレジスタ、CAN_FxR1とCAN_FxR2組成物からはX。
各フィルタ群のSTM32のビット幅は、異なるアプリケーションの要件を満たすために独立して設定可能です。異なるビット幅によれば、各フィルタセットを提供することができます。
可能な構成の初期化ステップ、ファームウェア及び文書プロファイル関連のCAN stm32f10x_can.cのstm32f10x_can.hファイルおよびヘッダファイルに定義されたライブラリ関数。
1)クロックCANを可能にするために、対応するピン多重化機能を構成しました。
私たちは、CANを使用して、最初のステップは、クロックCANのことができるようにすることです。第二に、我々はPA12(CAN_TXピン)の出力と多重化されたプルPA11のセット入力(CAN_RXピン)に必要な多重CAN関連する出力ピン、ポートPAを有効にクロックを設定する必要があります。CAN1クロックは、機能を有効です。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1、ENABLE); //クロックCAN1を有効にします
2)ボーレートとCAN動作モードを設定します。
INRQを設定することにより、この最初のステップは、そう初期化モードに入ることができ、CAN_MCRレジスタビットは、他の制御ビットCAN_MCRを設定します。次に、ボーレートと動作モード(通常モード/ループバック・モード)情報CAN_BTRを設定します。0にINRQ最後のセットは、初期設定モードが終了します。
ライブラリ関数では、関数CAN_Init()前初期に、本体の動作モードとCANのボーレート、CAN_Init()関数を初期化するには、レジスタが1に設定されているINRQ CAN_MCRは、初期化、次いで、初期化モードに入る許可しましたCAN_MCR CRN_BTRレジスタ及びレジスタセットのレジスタ後CAN_MCR 0 INRQは、初期化モードを終了させました。だから我々は前となし、さらに初期化モード設定後、この関数を呼び出します。定義CAN_Init()関数で見てみましょう:
uint8_t CAN_Init(CAN_TypeDef * CANx、CAN_InitTypeDef * CAN_InitStruct)。
最初のパラメータはCANのラベルで、ここで我々は唯一の1チップCANを持って、それがCAN1です。
二番目のパラメータは、CAN構造体ポインタを初期化され、構造物の種類はCAN_InitTypeDef、この構造体の定義で見てみましょうです。
構造体のtypedef
{
CAN_Prescaler uint16_t;
CAN_Mode uint8_t;
CAN_SJW uint8_t;
CAN_BS1 uint8_t;
CAN_BS2 uint8_t;
FunctionalState CAN_TTCM;
FunctionalState CAN_ABOM;
FunctionalState CAN_AWUM;
FunctionalState CAN_NART;
FunctionalState CAN_RFLM;
FunctionalState CAN_TXFP;
} CAN_InitTypeDef。
この構造は、実際には、パラメータを2つのカテゴリに分けることができ、より多くのメンバ変数を探します。上記5つのパラメータは、CAN_BTRレジスタを設定するために使用するボーレートモードおよび関連するパラメータを設定するために使用され、パラメータ設定モードは、我々の実験で使用し、CAN_Modeでされているモードと通常モードCAN_Mode_NormalをループバックCAN_Mode_LoopBack、あなたはまた、サイレントモードを選択することができ、かつサイレントループバックテストモード。ボーレート設定CAN_Prescaler、CAN_SJW、CAN_BS1に関連する他のパラメータは、ボーレートとCAN_BS2デバイダ再同期ホップカウント期間と1つの単位の時間幅を設定するために使用され、時間は2によって占め。変数がCAN_MCRを登録設定する6背面部材、CAN通信は、関連する制御ビットが設けられています。
初期の例は以下のとおりです。
CAN_InitStructure.CAN_TTCM = DISABLE; //非タイムトリガ通信モード
CAN_InitStructure.CAN_ABOM = DISABLE; //自動オフライン管理ソフトウェア
CAN_InitStructure.CAN_AWUM = DISABLE;ソフトウェア経由//ウェイクスリープモード
CAN_InitStructure.CAN_NART = ENABLE; //自動送信パケットを禁止します
CAN_InitStructure.CAN_RFLM = DISABLE;メッセージは、古いものの上に、新しいロックされていません//
CAN_InitStructure.CAN_TXFP = DISABLE; //優先度はパケットによって決定される識別子
CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; //設定モード:1、ループバック・モード。
//ボーレートを設定
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //スキップ幅の再同期時間単位
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; // 1が8を占有する期間の時間単位
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //期間は2時間単位7を占め
CAN_InitStructure.CAN_Prescaler = 5; //分割ファクタ(FDIV)
CAN_Init(CAN1、&CAN_InitStructure); //初期化することができます
3)フィルタの設定。
我々は、作業マスクビットパターンでフィルタバンク0、及び32ビットの識別子を使用します。FINIT CAN_FMRは、第1のフィルタ群は、初期化モードで働くように、ビットのセット、及び、フィルタバンク0と識別子IDとマスクビットの動作モードを設定します。最後に、フィルタと出口フィルタ初期化モードを有効にします。
ライブラリ関数、関数CAN_FilterInit()、初期化モードに入ることを許可されINRQ CAN_FMR INITレジスタを設定する前に初期化にCAN_Init()体内の機能を、CANフィルタパラメータを初期化するために、次に初期化することができるフィルタレジスタセットの関連レジスタ後CAN_FMR 0 FINITは、初期化モードを終了させることができます。だから我々は前となし、さらに初期化モード設定後、この関数を呼び出します。定義CAN_FilterInit()関数で見てみましょう:
空CAN_FilterInit(CAN_FilterInitTypeDef * CAN_FilterInitStruct)。
この機能は、一つの入口CANフィルタの初期化パラメータの構造体へのポインタである、構造型はCAN_FilterInitTypeDef、型定義で見てみましょうです。
構造体のtypedef
{
CAN_FilterIdHigh uint16_t;
CAN_FilterIdLow uint16_t;
CAN_FilterMaskIdHigh uint16_t;
CAN_FilterMaskIdLow uint16_t;
CAN_FilterFIFOAssignment uint16_t;
CAN_FilterNumber uint8_t;
CAN_FilterMode uint8_t;
CAN_FilterScale uint8_t;
FunctionalState CAN_FilterActivation;
} CAN_FilterInitTypeDef。
9つの構造体のメンバ変数の合計は、第4の第1のフィルタ32および32ビットのマスクID番号を設定するために使用され、2つの16ビットによって結合され
関連FIFOおよびフィルタを設定するにはCAN_FilterFIFOAssignment第五メンバ変数、我々の実験は、FIFO0フィルタ0、値CAN_Filter_FIFO0に関連しています。
第六のメンバーは0〜13の範囲で、変数CAN_FilterNumberフィルタ群を初期化するために提供しました。
メンバ変数フィルタセット、識別子の値と識別子リストモードCAN_FilterMode_IdListマスクビットパターンCAN_FilterMode_IdMaskを設定するためのFilterModeを第モード。
FilterScale第8メンバ変数は、フィルタ2の16ビットのビット幅または32ビットCAN_FilterScale_16bit CAN_FilterScale_32bitを設定します。
第9回メンバ変数は非常に明確CAN_FilterActivation、およびフィルタをアクティブにします。
参考例のフィルタの初期化コード:
CAN_FilterInitStructure.CAN_FilterNumber = 0; // 0フィルター
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask。
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit。// 32位
CAN_FilterInitStructure.CAN_FilterIdHigh = 0000; //// 32位ID
CAN_FilterInitStructure.CAN_FilterIdLow = 0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0000; // 32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; // FIFO0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //フィルタをアクティブ0
CAN_FilterInit(&CAN_FilterInitStructure); //初期化フィルタ
これまでのところ、CANは、作業を開始することができます。あなたが割り込みを使用する場合は、関連する構成を中断する必要があります
4)受諾メッセージを送信します
CANおよびフィルタパラメータを初期化した後、次のステップは、メッセージを送受信することです。ライブラリ機能やメッセージを受け入れる送信する機能を提供します。関数のメッセージが送信されます。
uint8_t CAN_Transmit(CAN_TypeDef * CANx、CanTxMsg * TxMessage)。
この機能は、よりよく理解されて、最初のパラメータは、CAN番号、我々はCAN1を使用しています。第二のパラメータは、標準識別子、拡張識別子、メッセージタイプとフレーム長情報を設定するためのメッセージ構造CanTxMsgポインタ型のメンバ変数CanTxMsg構造に関連しています。
この関数は、メッセージがある取ります。
空CAN_Receive(CAN_TypeDef * CANx、FIFONumber uint8_t、CanRxMsg * RxMessage)。
最初の2つのパラメータは、より良い理解、CAN番号とFIFOの番号です。RxMessage第二パラメータが受信されたメッセージ情報を記憶するために使用されます。
構造および構造CanTxMsg CanRxMsg近い、それぞれ定義してメッセージを送信するメッセージを受け入れる説明するために、
5)CANステータス取得
、CANのステータスメッセージを伝送状態情報を保留中のメッセージの数、ライブラリ関数はCAN_TransmitStatus()関数で、CAN_MessagePending()関数、CAN_GetFlagStatus()関数を含む関数、などを提供するように、我々ができ送信あなたは、呼び出す必要があります。
折りたたまれたまたは折り畳まれていない(こちら)をクリックします
// CAN初期化
// tsjw:; CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq 1〜3:再同期手段は、時間範囲をジャンプします。
// TBS2:1~8 ;.:期間は、2時間の範囲を意味します
// TBS1:時間の単位期間1の範囲:1〜16; CAN_BS1_1tq〜CAN_BS1_16tq
// BRP:ボーレートプリスケーラの範囲:1〜1024、(実際に1を加算、すなわち〜1024 1)TQ =(BRP)* tpclk1
//上記のパラメータのいずれかが、それ以外の場合は、混乱になり、0に設定することはできません。
//ボーレート= Fpclk1 /((tsjw + TBS1 + TBS2)* BRP)。
//モード:0、ノーマルモード; 1、ループバック・モード。
初期化時// Fpclk1 36Mクロックセット、CAN_Normal_Initを設けた場合には(1,8,7,5,1)。
//ボーレート:36M /((1 + 8 + 7)* 5)= 450Kbps
//戻り値:0、[OK]を初期化。
//その他の初期化に失敗しました。
U8 CAN_Mode_Init(U8 tsjw、U8 TBS2、U8 TBS1、U16 BRP、U8モード)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_RX0_INT_ENABLEの#if
NVIC_InitTypeDef NVIC_InitStructure;
#endifの
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA、ENABLE); //クロックPORTAを有効にします
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1、ENABLE); //クロックCAN1を有効にします
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //多重プル
GPIO_Init(GPIOA、&GPIO_InitStructure); //初期化IO
// CANユニットの設定
CAN_InitStructure.CAN_TTCM = DISABLE; // //非タイムトリガ通信モード
CAN_InitStructure.CAN_ABOM = DISABLE; // //管理ソフトウェアを自動的にオフライン
CAN_InitStructure.CAN_AWUM = DISABLE; //ウェイクスリープモードソフトウェア経由(MCRでクリアCAN-> SLEEPビット)//
CAN_InitStructure.CAN_NART = ENABLE; // //が自動的に送信されたメッセージを禁止
CAN_InitStructure.CAN_RFLM = DISABLE; //メッセージロックされていない、古いものの上に新しい//
CAN_InitStructure.CAN_TXFP = DISABLE; //優先度は、メッセージIDによって決定される//
CAN_InitStructure.CAN_Mode =モード; //設定されたモード:モード:0、ノーマルモード1、ループバック・モード; //
//ボーレートを設定
CAN_InitStructure.CAN_SJW = tsjw; //再同期ジャンプ幅(tSJW)tsjw + 1つの単位時間CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tqあります
CAN_InitStructure.CAN_BS1 = TBS1; // TBS1 = TBS1 + 1時間単位CAN_BS1_1tq〜CAN_BS1_16tq
CAN_InitStructure.CAN_BS2 = TBS 2; // TBS 2 = TBS 2 + 1時間単位CAN_BS2_1tq〜CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler = BRP; BRP + 1の//分割ファクタ(FDIV)//
CAN_Init(CAN1、&CAN_InitStructure); //初期化CAN1
CAN_FilterInitStructure.CAN_FilterNumber = 0; // 0フィルター
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask。
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit。// 32位
CAN_FilterInitStructure.CAN_FilterIdHigh = 0000; //// 32位ID
CAN_FilterInitStructure.CAN_FilterIdLow = 0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0000; // 32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; // 0フィルター関連FIFO0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //フィルタをアクティブ0
CAN_FilterInit(&CAN_FilterInitStructure); //初期化フィルタ
CAN_RX0_INT_ENABLEの#if
CAN_ITConfig(CAN1、CAN_IT_FMP0、ENABLE); // FIFO0のメッセージはイネーブルレジスタ割り込み。
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn。
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //マスター優先順位1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 0回の優先順位
NVIC_InitStructure.NVIC_IRQChannelCmdは= ENABLE;
NVIC_Init(&NVIC_InitStructure)。
#endifの
0を返します。
}
CAN_RX0_INT_ENABLEの#if //割り込みRX0を有効にします
//割り込みサービスルーチン
空USB_LP_CAN1_RX0_IRQHandler(無効)
{
CanRxMsg RxMessage;
私は0を= int型。
CAN_Receive(CAN1、0、&RxMessage)。
以下のための式(I = 0、I <8; I ++)
printf( "RXBUF [%のD]:%D \ R \ n" は、iは、RxMessage.Data [I])。
}
#endifの
//データのセットを送信することができる(固定フォーマットIDは0x12を、標準フレーム、データフレームです)
// lenの:データ長(8の最大値)
// MSG:データポインタ、8バイトの最大。
//戻り値:0、成功しました。
//その他、失敗しました。
U8 Can_Send_Msg(U8 * MSG、U8 LEN)
{
U8のMBOX。
U16私は= 0;
CanTxMsg TxMessage;
TxMessage.StdId = 0x12を; //標準識別子0
TxMessage.ExtId = 0x12を; //セット識別子エクステンション(29)
TxMessage.IDE = 0; //拡張識別子
TxMessage.RTR = 0; //メッセージ・タイプは、データフレームである8
TxMessage.DLC = LEN; //送信二つの情報
(; iが<lenは、I ++ I = 0)するため
TxMessage.Data [I] = MSGの[I]; //最初のフレーム情報
MBOX = CAN_Transmit(CAN1、&TxMessage)。
I = 0;
((CAN_TransmitStatus(CAN1、mbox形式)== CAN_TxStatus_Failed)&&(I <0XFFF))間、私++; //待機送信端
IF(I> = 0XFFF)リターン1。
0を返します。
}
// CANポートは、データのクエリを受信します
// BUF:データバッファと、
//戻り値:0、データは受信されません。
//他、受信したデータ長、
U8 Can_Receive_Msg(U8 * BUF)
{
U32私は、
CanRxMsg RxMessage;
IF(CAN_MessagePending(CAN1、CAN_FIFO0)== 0)戻り0; //データが受信されない、出口
CAN_Receive(CAN1、CAN_FIFO0、&RxMessage); //データを読み込みます
以下のための式(I = 0、I <8; I ++)
BUF [I] = RxMessage.Data [I]。
RxMessage.DLCを返します。
}