LPC1343 ADC データ測定 リアルタイムグラフ表示


1. フォトダイオードのアナログ出力をADCで10ms毎に取得
2. UARTで取得データをPCに送信
3. フリーソフトCPLTでデータログ&ほぼリアルタイムグラフ表示

開発Listへ戻る

ちょっと前にネット検索をしていると面白いソフトの紹介記事を見つけたので
使ってみることにしました。

ソフトはデータテクノという会社さんのCPLTというものです。
リンク先の「その他」の4番です。

これを使うとUARTで送ったデータを、下の図のようにほぼリアルタイムにグラフにしてくれます。
データはフォトダイオードの出力をA/D変換したものです。

フォトダイオードを手で覆うと出力が下がることをほぼリアルタイムで確認できます。
ほぼというのは少しディレイがあるということです。
また、データもCSVファイルにログしてくれるという優れたフリーソフトです。

グラフの数も増やすことが出来ます(同時に8本までのデータを引くことが出来る模様)

xp用ですがwin7でも動作はします。(この図はwin7でとりました)
ただしwin7ではhelpが見えません。
helpで動作条件を知るためにもxpが必要です。


回路
準備物
 FT232RL USBシリアル変換モジュール
 フォトダイオードS9648-100 秋月電子 120円
 このフォトダイオードはアンプも不要で大きな出力が出たのでちょうど良かったです。

接続図
 

コード main.c

#ifdef __USE_CMSIS
#include "LPC13xx.h"
#endif

#include
#include
#include "adc0.h"
#include "uart.h"


__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;



#include
#include    //int-> char変換 itoi
// Main loop
int main(void) {
// Variable declaration
char p[4]; // AD0 value
int ad0data;

// Initialize UART
uart_init(9600);
adc0_init();

LPC_SYSCON->SYSAHBCLKCTRL |=0x100; // Timer16B1 Turn ON
LPC_TMR16B1->PR = 7200-1; // 10kHz (Max 16bit dec:65535)
LPC_TMR16B1->MR0 = 100; // 0.01S
LPC_TMR16B1->MCR = 0x04; // Stop timer on MR0

// Enter an infinite loop, just echo lines
while (1) {
LPC_TMR16B1->TCR = 0x02; // TCR Reset
LPC_TMR16B1->TCR = 1; // TCR Start
ad0data=adc0read();
itoa(ad0data, p, 10);
uart_puts(p);
uart_puts("\r\n");

while (LPC_TMR16B1->TCR & 0x01);
}
}

コード解説 

・まずインクルードです。
 以前のエントリ LPC1343 UARTでADCを制御する 2/2を参照です。
 adc0.c, adc0.h, uart.c, uart.hはリンク先からコピーしてプロジェクトに追加してください。

#include "adc0.h"
#include "uart.h"

・次はmain内です。これも基本的に以前のエントリのmain.cのモディファイです。
LPC1343 UARTでADCを制御する 2/2

変更部分だけ説明します。

・10ms毎にADCをするようにタイマーをイニシャライズします。
LPC_SYSCON->SYSAHBCLKCTRL |=0x100; // Timer16B1 Turn ON
LPC_TMR16B1->PR = 7200-1; // 10kHz (Max 16bit dec:65535)
LPC_TMR16B1->MR0 = 100; // 0.01S
  LPC_TMR16B1->MCR = 0x04; // Stop timer on MR0

永遠ループ内です
 タイマーをリセットする(TCカウンタを0にする) & カウントアップスタートする

LPC_TMR16B1->TCR = 0x02; // TCR Reset
LPC_TMR16B1->TCR = 1; // TCR Start

・ADCの値を読む、charに変換する, Uartでcharデータ送信, CR+LFを送信
ad0data=adc0read();
itoa(ad0data, p, 10);
uart_puts(p);
uart_puts("\r\n");

TCRが設定カウント値になるまで待つ
(TCRが設定カウント値(今回はMR0=100)になるとTCRのbit0が"0"になる。その状態になるまで待つ)

while (LPC_TMR16B1->TCR & 0x01);


結構使えるソフトだと思います!!

LPC1343 USB virtual COMでローカルエコー


1.LPC1343のVirtual comでエコー(Example project modify)

開発Listへ戻る

このエントリではNXPから提供されているExample Projectを使います。
準備はコチラ
・Example projectのインポート方法
・USBコネクタの接続
Win7 x64用のDriver入手方法
があります。


で、今回やってみることは
Teratermでキーボード or File転送
    ↓
LPC1343はUSB経由でデータを受け取り、まったく同じデータをUSB経由でTeratermへ返す
    ↓
Teratermの表示で結果を確認

やっていることは単なるエコーです。


モディファイしたコードです。
vcomdemo.cを修正します。青文字のところが修正した部分です。

#include
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include "LPC13xx.h"
#include "type.h"

#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "vcomdemo.h"

#define EN_TIMER32_1 (1<<10)
#define EN_IOCON (1<<16)
#define EN_USBREG (1<<14)

typedef struct {
char d[32];
int num;
}GETDAT_T;

/*----------------------------------------------------------------------------
Initializes the VCOM port.
Call this function before using VCOM_putchar or VCOM_getchar
*---------------------------------------------------------------------------*/
void VCOM_Init(void) {

CDC_Init ();
}


/*----------------------------------------------------------------------------
Reads character from serial port buffer and writes to USB buffer
*---------------------------------------------------------------------------*/
void VCOM_Serial2Usb(GETDAT_T dat) {

if (dat.num!=0 && CDC_DepInEmpty) { // 1 is empty so if empty
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&dat.d[0], dat.num);
}

}

/*----------------------------------------------------------------------------
Reads character from USB buffer and writes to serial port buffer
*---------------------------------------------------------------------------*/
#include
GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;

}
return(Getdata);
}


/*----------------------------------------------------------------------------
checks the serial state and initiates notification
*---------------------------------------------------------------------------*/
void VCOM_CheckSerialState (void) {
unsigned short temp;
static unsigned short serialState;

temp = CDC_GetSerialState();
if (serialState != temp) {
serialState = temp;
CDC_NotificationIn(); // send SERIAL_STATE notification
}
}

/*----------------------------------------------------------------------------
Main Program
*---------------------------------------------------------------------------*/
int main (void) {
/* Basic chip initialization is taken care of in SystemInit() called
* from the startup code. SystemInit() and chip settings are defined
* in the CMSIS system_.c file.
*/

/* Enable Timer32_1, IOCON, and USB blocks */
GETDAT_T Getdata;
Getdata.num=0;

LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);

USBIOClkConfig();

VCOM_Init(); // VCOM Initialization

USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect

while (!USB_Configuration) ; // wait until USB is configured

while (1) { // Loop forever
VCOM_Serial2Usb(Getdata); // read serial port and initiate USB event
Getdata.num=0;
VCOM_CheckSerialState();
Getdata=VCOM_Usb2Serial();

} // end while
} // end main ()

解説です。
といっても、USBの詳細部分はほとんど理解できてません。。
動いたからイイや程度です。


コンセプト
試してみることは、下の図のように
Example projectではUSBで受信したデータをUART TXに変換
UART RXで受信したデータをUSBに変換という機能だったのを

USBで受信データをGetdataという変数で受け渡して、USBでそのまま返すというものにします。



将来的に、センサーなどのデータをUSB経由でPCに転送することを想定して
データの受け渡し方法を確認することが目的です。

↓将来やりたいことのイメージ↓

コード
・まず、変数を定義します。
typedef struct {
char d[32];
int num;
}GETDAT_T;

d :受け渡しデータ 32byteのchar
VCOM_Usb2SerialでserBuf が32byte charだったからそうしてます。
num : 有効データ数です。

・次はmainです。

while (1) { // Loop forever
VCOM_Serial2Usb(Getdata); // read serial port and initiate USB event
Getdata.num=0;
VCOM_CheckSerialState();
Getdata=VCOM_Usb2Serial();
}

VCOM_Usb2Serial関数でUSB経由のデータと有効データ数をGetdataに入れます。
そしてVCOM_Serial2USB関数でGetdataをUSB経由でPCに送信です。
送信した後は有効データを0にしてます。


・VCOM_Usb2SerialではserBufに入ったデータと
numBytesReadに入った有効データ数をGetdataに入れ込んで戻してます。

#include
GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;
}
return(Getdata);
}


・最後にVCOM_Serial2UsbでEmpty flagが立ったうえで有効データがあった場合に
USBでデータを転送してます。

void VCOM_Serial2Usb(GETDAT_T dat) {

if (dat.num!=0 && CDC_DepInEmpty) { // 1 is empty so if empty
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&dat.d[0], dat.num);
}

}


これでエコーの完成です。

Teratermで試した結果です。


キーボードから入力した場合は転送速度が遅い(間欠的)のでまったく問題ありませんが
ファイル転送を選んだときは転送速度が速い(連続)ので
VCOM_Usb2Serial()内の serBuf [32];で指定している
32byteを超えるデータを転送すると32byte以上は無視されます。

青地で示した以下の32の数字を増やせばより多くのデータを送信できるようです
(48にして試したところOKでした)


typedef struct {
char d[32];
int num;
}GETDAT_T;


GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;
}
return(Getdata);

LPCexpresso IDE 使い方メモ1 View消したとき, インクルードフォルダ指定

LPCexpresso IDEの使い方だんだんとわかってきたのでメモしていきます。

マイコン開発経験者の方々は勘所がわかってすぐ見つけられるんでしょうが
初心者はツールの使い方から敷居が高くなるんですよね。


今回は、
Viewを消してしまったときに再度表示させるには?と
インクルードフォルダの設定の仕方です。

1.Viewの再表示方法

たとえば下の図のVariableの表示を消してしまった場合(結構やるんですよね。。)


ツールバー window → show view → others から選びます。

ちなみに、今まで手元がくるってviewを消した場合はIDEを立ち上げなおして対処していました。


2.インクルードフォルダの設定の仕方

サンプルプロジェクトには下の図のようにincフォルダがあるわけです。
最初は自動的に察してくれるのかと思ってフォルダ作ってコンパイルしてみましたが、無理でした。
設定が要るわけです。

プロジェクトフォルダを右クリックPropertiesを選択
(上の図でいうとusbtest部を右クリ)
1.Path & symbol を選択
2.Include tabで Languages の中の GNU C を選択
3.Add... をclick
4.ポップアップしたwindowのworkspace...をクリックして
インクルードしたいフォルダを選択です!



ちなみに今まではsrcフォルダにヘッダファイルから全部入れてました。。

また随時メモを追加していきますです。

LPC1343 USB Virtual COMをカスタマイズ!

出来た事

1.LPC1343でUSB Virtual COMのExample pjtをモディファイしてカスタマイズ

開発Listへ戻る

前回、Example codeをそのままコンパイルしてUSBシリアル変換を実現しましたが
はっきり言って単なるUSBシリアル変換ならFT232RLを買えばいいんですよ。
そんなモンをLPC1343で作ってもまったく意味がない。(と感じてる)

USBを使ってコマンド転送(設定変更などの指示)とか、内部処理結果などのデータ取得が出来れば
おおっ!!結構やるね!みたいになります(私の周りではですが・・・)


今回、NXPのサンプルコードを眺めていたら結構簡単に出来そうな感じでした!
(ポジティブ(^^)/)


まず、Example codeをみてみます。USB-シリアル変換機能を実現するExample pjtのコードです。
見てみるといっても概略です。詳細はぜんぜんわかっていません。
インポートしたusbcdcのpjt内のsrcフォルダ内のvcomdemo.cを見ます。
(インポートの仕方などは前回のエントリ参照)

vcomdemo.c
まずmain関数

int main (void) {
/* Enable Timer32_1, IOCON, and USB blocks */
LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);

USBIOClkConfig();
VCOM_Init(); // VCOM Initialization
USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect

while (!USB_Configuration) ; // wait until USB is configured

while (1) { // Loop forever
VCOM_Serial2Usb();
VCOM_CheckSerialState();
VCOM_Usb2Serial();
} // end while
} // end main ()

大事なところは青字のところです。
まぁ記載を見ると大体意味がわかるんですが。。。

1.VCOM_Serial2USB()は シリアルデータ(UART Rx受信データ)をUSBに変換してLPC1343からPCに送信します。

2.VCOM_CheckSerialState() こいつはステータスなんでしょうが、削除するとPCがLPC1343をVirtual COMとして
認識できなくなりました。盲目に入れておきましょう。

3.VCOM_Usb2Serial()はPCからUSBで送信されてきたデータをシリアルに変換してUARTのTxとして出力します。


3については、USB受信データをそのまま利用出来れば良いです。シリアルはいりません。
1はUARTの受信データではなく内部信号をUSBで送信できれば良いわけです。
つまり、1,3からシリアル部分を切り離すことが出来ればいいのです。



VCOM_Serial2USB

void VCOM_Serial2Usb(void) {
static char serBuf [USB_CDC_BUFSIZE];
int numBytesRead, numAvailByte;

ser_AvailChar (&numAvailByte); //UART RXのバッファ確認
if (numAvailByte > 0) {   // UART Rxのバッファになんか入ってる? 
if (CDC_DepInEmpty) {   // USBの送信処理終わってる?
numBytesRead = ser_Read (&serBuf[0], &numAvailByte); //UART Rxのバッファに入ってるもを移動+有効byte数も取り出す。

CDC_DepInEmpty = 0;  // USBをBusyにする
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&serBuf[0], numBytesRead); //USBで有効Byte数のデータを送信する。
}
}
}

コメントの説明で大体わかるかと思いますが。
UARTの受信部分はデータを溜め込んでいます。
それを numBytesRead = ser_Read (&serBuf[0], &numAvailByte); で取り出しています。

USBの送信も時間がかかるので、USB送信中に入力されたUART Rxの信号をロストしないように
別のバッファを持っているということでしょう。

シリアル部分は要りませんので送信データと有効Byte数を独自で作成できれば良いようです。
(上記関数内でのserBuf とnumBytesReadをカスタマイズする)


VCOM_Usb2Serial

void VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

CDC_OutBufAvailChar (&numAvailByte); //USBから受けたデータのバッファ確認
if (numAvailByte > 0) {  //USBから有効なデータを受けている?
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead); //バッファの内容移動 + 有効byte数取り出し
ser_Write (&serBuf[0], &numBytesRead);  //Uartで送信する。
}
}

似たような感じです。
USBで受信したデータを一度バッファに溜め込んで
別のバッファに移し、移したデータをUARTで送信しています。

こちらもUARTで送信中にUSBに新たなデータが入力された場合にデータロストしないように
バッファがあります。

ココでは結構簡単で、ser_Writeがまったく不要です。

numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);後の
serBufが読み込んだ値、numByteReadが有効byte数ですから取り出せればOKです。


モディファイ内容

キーボードで's'と入力したら40桁の数字を帰ってくるようにする。
USB Virtual COM経由
Teratermで確認

まず VCOM_Usb2Serialです。

char VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);
// ser_Write (&serBuf[0], &numBytesRead);
return(serBuf[0]); // 1文字だけ返す
}
}

キーボードの入力は人力なので非常に遅いです。
バッファに2byteもたまることは無いでしょう。

今回は1文字 1byteのみ検出するようにしました。
シリアルでの送信関数を削除し、関数の結果として1文字だけ返すようにしました。


次にVCOM_Serial2Usbです。

void VCOM_Serial2Usb(char in_char) {
// static char serBuf [USB_CDC_BUFSIZE];
// int numBytesRead, numAvailByte;
char test[USB_CDC_BUFSIZE]="1234567890123456789012345678901234567890"; //送信データ作成
// ser_AvailChar (&numAvailByte);
// if (numAvailByte > 0) { // serial buffer has some data.
if(in_char=='s'){ // USBで's'が入力されたら
if (CDC_DepInEmpty) { // 1 is empty so if empty
// numBytesRead = ser_Read (&serBuf[0], &numAvailByte);
CDC_DepInEmpty = 0;
// USB_WriteEP (CDC_DEP_IN, (unsigned char *)&serBuf[0], numBytesRead);
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&test[0], 40); //作成した40桁の数値を送信
}
}
}

シリアル部分は要りませんので削除
USBで's'が入力されたら、独自で作成した40桁の数値をUSBで送信。
(なので、1文字 char 入力としています)

最後にmain関数です。

int main (void) {
/* Enable Timer32_1, IOCON, and USB blocks */
char test='0';

LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);

USBIOClkConfig();

VCOM_Init(); // VCOM Initialization

USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect

while (!USB_Configuration) ; // wait until USB is configured

while (1) { // Loop forever
VCOM_Serial2Usb(test); // read serial port and initiate USB event
VCOM_CheckSerialState();
test=VCOM_Usb2Serial();
}
}

新しく関数間でcharの受け渡しがあるのでtestという変数で受け渡しを実現しています。


この変更後、Teratermでsを入力するとちゃんと期待した40桁の数値が表示されました。

ちなみにBaudrateの設定は関係ありません。
USB部分にBaudrateの概念が無いからです。

また以下にコピペすれば今回の機能が実現するコードを置いておきます。
vcomdemo.c全部をコピペで入れ替え

#include "LPC13xx.h"
#include "type.h"

#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "serial.h"
#include "vcomdemo.h"
#include

#define EN_TIMER32_1 (1<<10)
#define EN_IOCON (1<<16)
#define EN_USBREG (1<<14)

/*----------------------------------------------------------------------------
Initializes the VCOM port.
Call this function before using VCOM_putchar or VCOM_getchar
*---------------------------------------------------------------------------*/
void VCOM_Init(void) {

CDC_Init ();
}


/*----------------------------------------------------------------------------
Reads character from serial port buffer and writes to USB buffer
*---------------------------------------------------------------------------*/
void VCOM_Serial2Usb(char in_char) {
// static char serBuf [USB_CDC_BUFSIZE];
// int numBytesRead, numAvailByte;
char test[USB_CDC_BUFSIZE]="1234567890123456789012345678901234567890";
// ser_AvailChar (&numAvailByte);
// if (numAvailByte > 0) { // serial buffer has some data.
if(in_char=='s'){
if (CDC_DepInEmpty) { // 1 is empty so if empty
// numBytesRead = ser_Read (&serBuf[0], &numAvailByte);
CDC_DepInEmpty = 0;
// USB_WriteEP (CDC_DEP_IN, (unsigned char *)&serBuf[0], numBytesRead);
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&test[0], 40);
}
}
}

/*----------------------------------------------------------------------------
Reads character from USB buffer and writes to serial port buffer
*---------------------------------------------------------------------------*/
char VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);
// ser_Write (&serBuf[0], &numBytesRead);
return(serBuf[0]);
}
}

/*----------------------------------------------------------------------------
checks the serial state and initiates notification
*---------------------------------------------------------------------------*/
void VCOM_CheckSerialState (void) {
unsigned short temp;
static unsigned short serialState;

temp = CDC_GetSerialState();
if (serialState != temp) {
serialState = temp;
CDC_NotificationIn(); // send SERIAL_STATE notification
}
}

/*----------------------------------------------------------------------------
Main Program
*---------------------------------------------------------------------------*/
int main (void) {
/* Enable Timer32_1, IOCON, and USB blocks */
char test='0';

LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);

USBIOClkConfig();

VCOM_Init(); // VCOM Initialization

USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect

while (!USB_Configuration) ; // wait until USB is configured

while (1) { // Loop forever
VCOM_Serial2Usb(test); // read serial port and initiate USB event
VCOM_CheckSerialState();
test=VCOM_Usb2Serial();
} // end while
} // end main ()

LPC1343 USB Virtual COM (USBシリアル変換 : Example pjt使用)

出来た事

1.Example Pjtを利用してLPC1343でUSB-シリアル変換を実現

開発Listへ戻る

Exampleコードを利用してLPC1343でUSB-シリアル変換機能を実現します。
要はLPC1343がFT232RLと同じ機能を持つということです。

こんな感じ

検証はFT232RLを使って行います。


接続
新しく Mini USBのコネクタを準備しなければなりません。
秋月電子Mini USB→DIP 変換の部品があり購入しました。便利です!

USB接続はlpcxpresso.getting.startedのPage45/49参照です

USBとFT232RLの実際の接続


プロジェクトのインポート

-CMSIS バージョン1.3で作成
Example プロジェクトはCMSISの1.3で作られているのでCMSIS1.3にリンクしたプロジェクトとして実行するとすんなり出来ます。
 
 1)Import archived projects (zip)をクリック

2)Browseからインポートするzipファイルを選択。Pathは下の図参照

 3)CMSISv1p30_LPC13xx をインポート
  もう一度1),2)を行い
  examples.lpc13xx.newをインポート
  目的のプロジェクトはusbcdcです。
  じゃまっけなのでusbcdcのみを選択し他はインポートしないようにするとよいでしょう。

 4)Buildする。とエラーなく出来るはずです。
  なんなくDebug(ダウンロード)出来るはずです。


-CMSIS バージョン2.0で作成
 Example プロジェクトはCMSIS1.3にリンクしています、設定でCMSIS2.0に変更する方法がわからないので
 (あるのかないのかも知らないので)New projectから実現します。

 1)New project作成する。このときリンクはCMSIS2.0にする。
 

 2)作ったプロジェクトのsrc内のmain.cは消す
  cr_startup_lpc13.cは残す


 3)Example プロジェクト usbcdcの srcからcコードをコピーし作ったプロジェクトのsrcフォルダへペースト
  このときcr_startup_lpc13.cはコピーしない。
  (下図の青矢印は作ったプロジェクト内にあったものを使う)
  usbcdcのincからhファイルも同様にコピーする。

 4)メインファイル vcomdemo.cにコード追加
 #include
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

 5)Buildする。とエラーなく出来るはずです。
  なんなくDebug(ダウンロード)出来るはずです。


動作確認
USBケーブルを差し込むとドライバインストールの要求があります。
ドライバはusbcdcのフォルダにあるのですが、どうやら私のPC win7x64では動きません。

そこでnxpのサイトから入手します。

このリンクでsoftwareにチェックしてlpc13xxでサーチすると出てくる
下の図のファイルをダウンロードし、中のUSBCDCのフォルダから入手します。

 
検証の図のように接続して
Teratermで動作確認したところBardrate 230400まで動きました。
それ以上は文字化けしていましたのでスピードが間に合っていないのでしょう。

ダウンロードするサンプルコードはたぶんkeilコンパイラー用だと思います
LPCXPRESSOではそのまま使えなかったのでドライバだけ頂きます。

2012.3.13追記
FT232RLをはずしてLPC1343のUART Rx,Txを直結して速度を確認したところ
Teratermのmaxだった921600まで通信できました。
FT232RLがよろしくなかったようです。

5分でつながる!! Bluetooth module

出来た事

1.Bluetooth moduleでの無線シリアル通信

開発Listへ戻る

Bluetoothに興味を持ってイロイロと調べました。

まず思ったこと。

結構簡単そう

インターフェースがUARTだということがわかりました(USBもあるようです)
これを見たときなんだか敷居が下がりました。

今までは無線関連は、どうせ難しいだろうと思ってスルーしてましたが
いけそうな気がします!

次に思ったこと。

高い!!

Wiiの換えのBluetoothモジュールは$5程度で買えるようです。
ただし、インターフェースはUSBらしいこととドキュメントもありません。
でも$5です。

それに対して回路実験用に使うBluetoothモジュールは
ヴィストンのVS-VT001が代表格らしいのですが8400円します。

何なんだろうね〜
と思って調べていると
SzPartsのSBT1-T-S (#19589287) 2750円を見つけました。

技適が有り無しで大きく値段が違っているようです。

ちなみにBaudrateなどの設定を変更するためには別途Bluetooth BC417143 SPIライタなるものを
2250円で買う必要があります。
(SzParts SBT1-T-Sは購入時Baudrate9600)

ヴィストンも同様にVS-BTプログラマなるもので設定を変更しますがこいつは4410円です。

まぁ家での趣味なので安い方でいいかとSzPartsのものを購入です![SBT1-T-Sスレーブ]


5分でつながった!簡単Bluetoooth

準備物
・PC2台 (1台はBluetooth機能搭載)
・USB シリアルFT232RL
Bluetooth モジュールSBT1-T-S (SzParts)
・ケーブル4本

構成図

FT232RTとSBT1-T-S接続図

作業開始!!
1.FT232RTとSBT1-T-Sを接続する。
こんな感じです。
他にもいろんなものが写ってますが、必要なものはFT232RTとSBT1-T-Sだけですので気にしないでください。

2.FT232RTをUSBでPC1に接続=Bluetoothモジュール電源ON

3.PC2でbluetoothモジュールをペアリングする。
Keyは0000です。
ペアリング後タスクバーのBluetoothマークをダブルクリックすると以下のようになっています。
切断されていたら右クリックから接続を選べばつながります。

4.PC1,PC2ともに通信ソフトを立ち上げる
Baudrateを9600にあわせる。

以下はPC1からテストワードを打ったときのPC2のハイパーターミナルの結果です。
 

見事に無線通信が出来ています!!

ココまで5分!! 簡単に接続できました!

LPC1343 UARTの限界速度と処理時間をCheck!

出来た事

1.UARTの通信速度をチェック(Timerで確認)

現在の限界 Baudrate 230400
実際の転送時間はほぼBaudrate通り
開発Listへ戻る

マイコン初心者の私は、なんとなくイロイロと確認したかったりするので
今日はUARTの限界速度のチェックと
今後、開発するコードの実際の処理時間を確認する方法を試してみる意図で
Timerを使って処理時間を測定を行いました。


使ったもの

方法
4桁の数字を100個表示
数字間には,10個表示でCR+LF
この時間をタイマーで測定し最後にタイマーの値を表示

1000,1001,1002,・・・1009
1010,1011,1012,・・・1019



1099,1091,1092,・・・1099
21456 ← タイマーの値(us)

測定結果

UARTの限界 : 230400までいけました。その次の460800はダメでした。
       原因までは追究していません。シリアル変換基板がNGなのか,LPC1343の限界か、
       コードが悪いのか(コードはエレキジャックさんの記事から引っ張ってきただけなので・・)。。

処理時間確認 : ほぼ正しい。(期待値 22135us 測定値21456)
なぜだか期待値よりも早くなりましたが、まぁこの程度わかれば私の目的では十分です。

解説
今回は4桁の数字+","が90個, 4桁の数字+CR+LFが10個です。
計510charを送信します。

データ8bit パリティなしなので、スタートビット、ストップビットを加味すると
1文字10bitで送信できます。合計5100bitです。

ボーレート230400ですので
予想時間[us]=1000000us/230400x5100=22135us

230400の結果
ちゃんと期待値と測定値が出ています。

460800の結果
文字化けしてNGです。


code

#ifdef __USE_CMSIS
#include "LPC13xx.h"
#endif

#include
#include
#include "uart.h"


__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;



#include
#include    //int-> char変換 itoi

// Main loop
int main(void) {
// Variable declaration
char p[4]; // AD0 value
char q[10];
int data[99]; //
int i=0;
int t=0;
int l=0;
int m=0;
int time;

// 32bit counter
LPC_SYSCON->SYSAHBCLKCTRL |=0x400; // Timer32B1 Turn ON
LPC_TMR32B1->PR =72-1; // 1us(Max 32bit dec:4294967295)
LPC_TMR32B1->MCR =0x600; // MR3 as Period of 32B1 and interrupt
LPC_TMR32B1->MR3 =10000000; // PWM Period 10kx100=100Hz
LPC_TMR32B1->TCR =2; // TCR Reset

// Initialize UART
uart_init(230400);

//Making 100xdummy data
while(t<=99){
data[t]=1000+t;
++t;
}

LPC_TMR32B1->TCR =1; // TCR start = Start measurement

//Send 100xdummy data by UART
while(l<=99){
itoa(data[l], p, 10);
uart_puts(p);
if(m<=8){
uart_puts(",");
++m;
}else{
uart_puts("\r\n");
m=0;
}
++l;
}

//Display measurement result
time=LPC_TMR32B1->TC;
itoa(time, q, 10);
uart_puts(q);
uart_puts("\r\n");



// Enter an infinite loop
while(1) { // Infinite loop
i++; // dummy count.
}
return 0 ;

}

codeは今までの解説の組み合わせです。

UART.C UART.h UARTの送信関係の参照記事 : LPC1343 UARTでADCを制御する 2/2
Timerの動作の参照記事 : LPC1343 32bit TimerでPWM