3

MCU の低レベルのコードを書くとき、私はいつもこのジレンマに遭遇するようです。コードをできるだけ再利用可能にするために、ピン定義をどこで宣言すればよいかわかりません。

この場合、8051MCP4922 12 ビット シリアル DACに接続するドライバを作成しています。DAC のCS (チップ セレクト) とLDAC (データ ラッチ)のピン定義をどこでどのように宣言すればよいかわかりません。現時点では、ドライバーのヘッダー ファイルで宣言されています。

私は最善のアプローチを見つけようとして多くの調査を行いましたが、実際には何も見つかりませんでした.

私は基本的にベストプラクティスを知りたいです...読む価値のある本やオンライン情報、例などがあれば、どんな推奨事項も歓迎します。

ドライバーのほんの一部なので、アイデアが得られます

/**
    @brief  This function is used to write a 16bit data word  to DAC B -12 data bit plus 4 configuration bits
    @param  dac_data A 12bit word 
    @param  ip_buf_unbuf_select Input Buffered/unbuffered  select bit. Buffered = 1; Unbuffered = 0
    @param  gain_select Output Gain Selection bit. 1 = 1x (VOUT = VREF * D/4096).  0 =2x (VOUT = 2 * VREF * D/4096)
*/
void MCP4922_DAC_B_TX_word(unsigned short int dac_data, bit ip_buf_unbuf_select, bit gain_select)
{                                             

    unsigned char low_byte=0, high_byte=0;
    CS = 0;                                               /**Select the chip*/

    high_byte |= ((0x01 << 7) | (0x01 << 4));            /**Set bit to select DAC A and Set SHDN bit high for DAC A active operation*/
    if(ip_buf_unbuf_select) high_byte |= (0x01 << 6);
    if(gain_select)         high_byte |= (0x01 << 5);

    high_byte |= ((dac_data >> 8) & 0x0F);
    low_byte |= dac_data;
    SPI_master_byte(high_byte);
    SPI_master_byte(low_byte);

    CS = 1;                                               
    LDAC = 0;                                             /**Latch the Data*/
    LDAC = 1;                                         
}
4

4 に答える 4

3

これは私が同様のケースで行ったことです。この例は、I²C ドライバーを作成するためのものです。

// Structure holding information about an I²C bus
struct IIC_BUS
{
    int pin_index_sclk;
    int pin_index_sdat;
};

// Initialize I²C bus structure with pin indices
void iic_init_bus( struct IIC_BUS* iic, int idx_sclk, int idx_sdat );

// Write data to an I²C bus, toggling the bits
void iic_write( struct IIC_BUS* iic, uint8_t iicAddress, uint8_t* data, uint8_t length );

すべてのピン インデックスは、アプリケーションに依存するヘッダー ファイルで宣言されているため、概要をすばやく確認できます。たとえば、次のようになります。

// ...
#define MY_IIC_BUS_SCLK_PIN 12
#define MY_IIC_BUS_SCLK_PIN 13
#define OTHER_PIN 14
// ...

この例では、I²C バスの実装は完全に移植可能です。インデックスによってチップのピンに書き込むことができる API にのみ依存します。

編集:

このドライバーは次のように使用されます。

// main.c
#include "iic.h"
#include "pin-declarations.h"

main()
{
    struct IIC_BUS mybus;
    iic_init_bus( &mybus, MY_IIC_BUS_SCLK_PIN, MY_IIC_BUS_SDAT_PIN );

    // ...

    iic_write( &mybus, 0x42, some_data_buffer, buffer_length );
}
于 2010-05-27T13:16:04.000 に答える
2

ランタイム構成の答えは、ARM、PowerPC などのまともな CPU で機能しますが、著者はここで 8051 を実行しています。#define がおそらく最善の方法です。これが私がそれをどのように分解するかです:

blah.h:

#define CSN_LOW()   CS = 0
#define CSN_HI()    CS = 1
#define LATCH_STROBE() \
 do { LDAC = 0; LDAC = 1; } while (0)

blah.c:
#include <blah.h>
void blah_update( U8 high, U8 low ) 
{
   CSN_LOW();
   SPI_master_byte(high);
   SPI_master_byte(low);
   CSN_HI();
   LATCH_STROBE();
} 

ピン定義を変更する必要がある場合、または別の CPU に移動する必要がある場合は、どこを更新する必要があるかは明らかです。また、バスのタイミングを調整する必要がある場合 (あちこちに遅延を挿入するなど) にも役立ちます。それが役に立てば幸い。

于 2010-07-28T22:51:04.847 に答える
2

ドライバーのみが CS ピンについて知る必要がある場合、宣言はヘッダーではなく、ドライバー モジュール自体に表示する必要があります。コードの再利用は、可能な限り制限されたスコープでデータを非表示にすることによって最適に機能します。

外部モジュールで CS を制御する必要がある場合は、デバイス ドライバ モジュールにアクセス機能を追加して、一点制御を行うことができます。これは、デバッグ中に I/O ピンがいつどこでアサートされているかを知る必要がある場合に役立ちます。インストルメンテーションまたはブレークポイントを適用するポイントは 1 つだけです。

于 2010-05-28T08:30:11.960 に答える
2

私が働いていたあるショップでは、ピンの定義がプロセッサ固有のヘッダー ファイルに入れられていました。別のショップでは、ヘッダー ファイルを DAC、DMA、USB など、プロセッサ内のモジュールに関連付けられたテーマに分割しました。プロセッサのマスター インクルード ファイルには、これらのテーマ付きヘッダー ファイルがすべて含まれていました。プロセッサ ファイルにさまざまなモジュール ヘッダー ファイルを含めることで、同じプロセッサのさまざまな種類をモデル化できます。

実装ヘッダー ファイルを作成できます。このファイルは、プロセッサ ヘッダー ファイルに関して I/O ピンを定義します。これにより、アプリケーションとハードウェアの間に 1 つの抽象化レイヤーが提供されます。アイデアは、アプリケーションをハードウェアからできるだけ疎結合することです。

于 2010-05-27T21:21:32.393 に答える