
写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる
それはさておき、
このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。
変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。
まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。
フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。
半田吸い取り線で、余分な半田を吸い取って、出来上がり。
慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。
このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。
今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。
MSP430 LaunchPadにI2C LCDをつなぐ
投稿日 2013/10/27
MSP430 LaunchPadにI2C キャラクタLCD ACM1602N1をつないでみました。
LaunchPadにはMSP430G2553が搭載されています。
LCDのACM1602N1は一般的なキャラクタLCDで、Vcc 3.3V I2Cインターフェース 2x16文字表示です。

SDAはP1.7、SCLはP1.6につないでおきます。両信号とも10KΩ位でプルアップが必要です。
MSP430ではUSCIモジュールをI2Cモードで動かすのですが、結構くせ者で、サンプルプログラムやユーザーズガイドを読んでみても、なかなか難解です。
今回は割り込みを使っていません。
I2Cの初期化とIOCtl以外は、PIC等で動いたものがそのまま使えます。
I2Cの初期化はサンプルプログラムを参考にします。
スレーブアドレスは7bitモードです。
SCLクロックはUCB0BR0 = 15として周期 約15uS 周波数 約67KHzとしています。
LCDのスレーブアドレスは0x7Cですが、R/Wビットの1ビット分右にシフトして与えます。
void init_i2c(void){
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2 |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Disable I2C
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 15; // fSCL = SMCLK/15 = 67KHz
UCB0BR1 = 0;
UCB0I2CSA = 0xA0 >> 1; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Enable I2C
}
問題はIOCtlですが、試行錯誤が必要でした。
これで動いたというレベルですので、参考になるかどうかわかりません。
void i2c_lcd_IOCtl(unsigned char command, unsigned char data){
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition and send slave address
UCB0TXBUF = command;
while(UCB0CTL1 & UCTXSTT); // Comand byte
while((IFG2 & UCB0TXIFG) == 0);
UCB0TXBUF = data; // Data byte
while((IFG2 & UCB0TXIFG) == 0);
UCB0CTL1 |= UCTXSTP; // Stop condition
while(UCB0CTL1 & UCTXSTP);

i2c_lcd_IOCtl(0x00, 0x30)実行時の波形
スタートコンディション スレーブアドレス 0xA0 コマンド 0x00 データ 0x30 ストップコンディションの順
ソースコード (開発環境は CCS 5.5.0を使用)
#include <msp430.h>
const int lcd_adrbase[2] = { 0x80, 0xC0 };
void delay_ms(int ms){
volatile int i;
for (i = 0; i < ms; i++) __delay_cycles(1000);
}
void delay_us(int us){
volatile int i;
for (i = 0; i < us; i++) __delay_cycles(1);
}
void init_i2c(void){
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2 |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 15; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0xA0 >> 1; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
void i2c_lcd_IOCtl(unsigned char command, unsigned char data){
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition and send slave address
UCB0TXBUF = command;
while(UCB0CTL1 & UCTXSTT); // Comand byte
while((IFG2 & UCB0TXIFG) == 0);
UCB0TXBUF = data; // Data byte
while((IFG2 & UCB0TXIFG) == 0);
UCB0CTL1 |= UCTXSTP; // Stop condition
while(UCB0CTL1 & UCTXSTP);
}
//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++);
}
int main(void){
WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer
init_i2c();
init_lcd();
lcd_write(0, 0, "1234567890123456" );
lcd_write(0, 1, "ABCDEFGHIJKLMNOP" );
while(1);
}
(JF1VRR)