写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる

 

それはさておき、

 

このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。

 

変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。

 

まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。

 

フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。

 

半田吸い取り線で、余分な半田を吸い取って、出来上がり。

 

慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。

 

このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。

 

今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。

STM32F4 DiscoveryにI2C LCDをつなぐ

投稿日 2014/04/13

久しぶりにSTM32 Discoveryに戻ってきました。

 

STM32F4Discoveryでデジタル・フィルタの実験をしたかったので、その前に表示器としてI2C LCDの接続を確認しておくことにしました。

STM32_VLD_I2C_LCD_2.jpg

写真:I2C LCDをSTM32F4 DiscoveryのI2C1に接続

 

STM32F4Discoveryは秋月電子等で購入可能です。基板のバージョンが上がって100円高くなったようです。(@1750円)

 

I2C LCDも容易に入手可能です。今回使用したのはACM1602N1です。(@800)

 

このI2C LCD(ACM1602N1)は、

 

I2Cスレーブ・アドレス 0xA0
I2Cクロック 最高100KHz
電源電圧 3.3V
バックライト付き

 

I2CSCL, SDA信号にプルアップ抵抗が別途必要です。 今回は4.7KΩを使用しました。

 

STM32F4DiscoveryにはI2Cが3個搭載されていますが、今回はI2C1につなぎました。

 

I2C1のSCL, SDA信号はGPIO PORTBのピン8(PB8)とピン9(PB9) に出せるようになっています。STM32F4Discoveryボードでは、P2のピン19とピン20に出ています。これらのピンは標準ではGPIOのPB8, PB9ですので、これらをI2Cで使えるようにするためオルタネート・ファンクションでSCL, SDAにリマップしてやらなければなりません。

 

ACM1602N1のGNDはP2のピン1、3.3VはP2のピン4につなぎます。
SCLはP2のピン19、SDAはP2のピン20につなぎ、4.7KΩの抵抗で3.3Vにプルアップしておきます。
バックライトにも3.3Vをつないでおきます。

 

I2Cの準備手順は、

 

I2C_Configration()
①GPIOBポートとI2C1にクロックを供給する 
②GPIOBポートのPB8とPB9を設定する
③GPIOのピンをI2C1のSCLとSDAにリマップする。
③I2C1を設定する
④I2C1を初期化する
⑤I2C1をイネーブルにする

 

クロックの供給は、GPIOはAHB1, I2CはAPB1の各クロック系統に接続します。


 

I2C LCDの制御手順(文字表示のための書き込みのみ)は、

 

I2C_IOCtl() (一般的なI2Cの制御手順です。)
①I2Cスタート・コンディションを発行する
②I2Cスレーブアドレスを書き込みモードで発行する
③LCDのモード・バイトを送信する
④LCDのコマンドまたはデータ・バイトを送信する

 

③のモード・バイトは0x00の場合は、④がコマンド・バイト、0x01の場合は④がデータ・バイトとなります。

 

I2C LCDの初期化手順は、

 

Init_LCD()
以下のコマンドを順に送信します。LCDのデータシートに記載されています。
0x30
0x30
0x30
0x38
0x08
0x01
0x06
0x0C


 

便利なように、下記のようなファンクションを用意しておきました。

 

I2C_LCD_IOCtl() LCDの制御
Init_LCD() LCDの初期化
LCD_Clear() LCD画面クリア
LCD_Position(x, y) LCDの表示位置指定
LCD_write(x, y, string) 指定の表示位置に文字列を表示
LCD_str(string) 現在の位置から文字列を表示

 

LCDのコマンドは一定の時間間隔を空けないといけないので、SysTick割り込みを使った遅延ファンクション Delay_ms()を用意しました。(時間間隔は適当です。チューニングしていません。)

STM32_VLD_I2C_LCD_1.jpg

写真:KEILのuVision4

 

開発環境は、KEILのuVision4を使用しました。

 

このLCDのI2C SCLクロック周波数は最高100KHzですが、100KHzにすると不安定ですので、I2C_CLOCKを50KHzとしました。ブレッドボードによる簡易配線が影響しているのかも知れません。

 

LCDに文字列を表示した後は、LED3が点滅します。

 

LED3がオフのままの場合は、I2Cの制御のどこかでACKが帰っていない場合が考えられます。その場合はI2Cのスレーブアドレス、SCL/SDAの接続とプルアップなどを確認します。

 

ちなみに、STM32VL_Discoveryで動かす場合は、以下の変更が必要です。

 

SCLをPB6に、SDAをPB7に接続
GPIOへのクロック供給をAHB1からAPB2に変更
GPIO_Pin_8 | GPIO_Pin_9をGPIO_Pin_6 | GPIO_Pin_7に変更
GPIO_Mode_AFをGPIO_Mode_AF_ODに変更
GPIO_PinAFConfig()はりマッピングが必要ないので削除
GPIO_Speed_100MHzをGPIO_Speed_50MHzに変更
Systickの割り込みハンドラをvoid SysTick_Handler(void)に名称変更

 

ソース・コード
STM32VL_Discovery用の部分はコメントにしてあります。

 

#include "stm32f4_discovery.h"
#include "main.h"

 

#define I2C_LCD_SLAVE_ADDRESS 0xA0 //for ACM1602N1 I2C LCD
#define I2C_CLOCK 50000 //50KHz

 

RCC_ClocksTypeDef RCC_Clocks;
const int lcd_adrbase[2] = { 0x80, 0xC0 };
static __IO uint32_t TimingDelay;

 

void I2C_Configuration(void);
void I2c_LCD_IOCtl(unsigned char, unsigned char);
void Init_LCD(void);
void LCD_position(unsigned char xpos, unsigned char ypos);
void LCD_write(unsigned char xpos, unsigned char ypos, char* ptr);
void LCD_clear(void);
void LCD_str(unsigned char* ptr);
void Delay_ms(int);

 

int main(void){
volatile int i;

/* Initialize LEDS */
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
STM_EVAL_LEDInit(LED5);
STM_EVAL_LEDInit(LED6);

/* Green Led On: start of application */
STM_EVAL_LEDOn(LED4);

 

if(SysTick_Config(SystemCoreClock / 1000)) while(1);

I2C_Configuration();

Init_LCD();

LCD_write(0, 0, "1234567890123456" );
LCD_write(0, 1, "ABCDEFGHIJKLMNOP" );

while (1){

STM_EVAL_LEDToggle(LED3);
Delay_ms(500);

}
}

 

void I2C_Configuration(void){

GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //I2C Periph Clock Enable

// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //GPIOB Periph Clock Enable for STM32VL_Discovery

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //GPIOB Periph Clock Enable for STM32F4_Discovery

//Configure I2C pins: SCL and SDA */

// GPIO_InitStructure.GPIO_Pin = GPIO_Pcin_6 | GPIO_Pin_7; //for STM32VL_Discovery

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //for STM32F4_Discovery

// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //for STM32VL_Discovery

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //for STM32F4_Discovery

// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //for STM32VL_Discovery

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //for STM32F4_Discovery
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

//I2C configuration
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_CLOCK;

// Apply I2C configuration
I2C_Init(I2C1, &I2C_InitStructure);

//I2C Peripheral Enable
I2C_Cmd(I2C1, ENABLE);

}

 

void I2c_LCD_IOCtl(unsigned char command, unsigned char data){
I2C_GenerateSTART(I2C1, ENABLE); //Send START Condition
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

I2C_Send7bitAddress(I2C1, I2C_LCD_SLAVE_ADDRESS, I2C_Direction_Transmitter); //Send Slave Address on write mode
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

I2C_SendData(I2C1, command); //Send command
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

 

I2C_SendData(I2C1, data); //Send data
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

I2C_GenerateSTOP(I2C1, ENABLE); //Send STOP Condition
}

//I2C LCD ACM1602N1

void Init_LCD(void){
Delay_ms(100);
I2c_LCD_IOCtl(0x00, 0x30);
Delay_ms(5);
I2c_LCD_IOCtl(0x00, 0x30);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x30);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x38);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x08);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x01);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x06);
Delay_ms(1);
I2c_LCD_IOCtl(0x00, 0x0C);
Delay_ms(1);

}

 

void LCD_position(unsigned char xpos, unsigned char ypos){

I2c_LCD_IOCtl(0x00, lcd_adrbase[ypos] + xpos );

}


 

void LCD_write(unsigned char xpos, unsigned char ypos, char* ptr){
LCD_position(xpos, ypos);
while(*ptr != 0x00){

I2c_LCD_IOCtl(0x80, *ptr++);

}
}


 

void LCD_clear(void){

I2c_LCD_IOCtl(0x00, 0x01);
Delay_ms(10);

}


 

void LCD_str(unsigned char* ptr){

while(*ptr != 0) I2c_LCD_IOCtl(0x80, *ptr++);

}

 

void Delay_ms(int nTime){

TimingDelay = nTime;
while(TimingDelay != 0);

}

 

//void SysTick_Handler(void) //for STM32VL_Discovery
void TimingDelay_Decrement(void) // for STM32F4_Discovery{
if(TimingDelay != 0){

TimingDelay--;

}
}
//end of main.c

 

参考: CQ出版 世界の定番 ARMマイコン 超入門キット STM32ディスカバリ
    CQ出版 STM32マイコン徹底入門 



 

(JF1VRR)