ATMELのAT-Tiny26,ATmega,R8Cなどのワンチップマイコン,C言語,JAVAなどのプログラミング言語の入門のためのページです.サンプルプログラムを中心に紹介します.他にもLinixや数学ソフトなどの紹介も行います.

このブログを検索

あなたは 番目のお客様です.

2010年12月7日火曜日

PSOCでクロックモジュールを使う









PSOC24123でクロックモジュールRTC-8564NBを使います.
PC+Teraterm+FT232+CY8C24123+RTC8564NB
PSOCとRTCの電源はFT232から供給する.
RTC-8564NBは,CR2032電源のモジュール化し切り離せるようにした.
CY8C24123の設定:5V 24MHz CPU=SysClk/3

VC3:UARTのクロック
VC1=SysClk/8,VC3=VC1/39=9600bps*8
P10:SDA P11:SCL P02:RX P03:TX
RTC-8564NB:Slave Adress=0B10100010
FT232とPSOCのGNDを共通にする必要あり!
cGetChar()を使うとデータが来るまで止まってしまう
's'でs=0,"txxxx"でRTC-8564NBの指定するアドレスの値を変更する.
cReadChar()は,最新のUARTの値を読むので,tをタイプしたあと
十分に待ってから後続の数値を打ち込む
02(Sec),03(Min),04(Hour),05(Day)

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#define AD 0B1010001 //Address of Clock

void main(void)
{
unsigned int i;
unsigned char a,b,x1,x2,x3,j,Buf[32];


for(i=0;i<60000;i++){}//wait
UART_CmdReset();
UART_IntCntl(UART_ENABLE_RX_INT);
UART_Start(UART_PARITY_NONE);
I2Cm_Start(); // Initialize I2C Master interface


while(1){
//a=UART_cGetChar();//Waits for valid character in UART RX and return its value.
a=UART_cReadChar();
//Set s =0
if(a=='s'){ I2Cm_fSendStart(AD,I2Cm_WRITE);
I2Cm_fWrite(0x02);//Address
I2Cm_fWrite(0x00);//Data s=0
I2Cm_SendStop();
}//t
//Set m h d
if(a=='t'){ a=UART_cGetChar(); b=UART_cGetChar();
x1=(a-'0')*16+(b-'0');//Address
a=UART_cGetChar(); b=UART_cGetChar();
x2=(a-'0')*16+(b-'0');//Data
I2Cm_fSendStart(AD,I2Cm_WRITE);
I2Cm_fWrite(x1);//Address
I2Cm_fWrite(x2);//Data
I2Cm_SendStop();
}//t

//read s m h d
Buf[0]=0x02;// address from seconds
I2Cm_bWriteBytes(AD,Buf,1,I2Cm_NoStop );
I2Cm_fReadBytes(AD,Buf,4,I2Cm_RepStart );
//D
a=Buf[3]/16; if(a>3)a-=4;
UART_PutChar(a+'0');//Upper bits
UART_PutChar(Buf[3]%16+'0');//Lower bits
UART_PutChar('d');
//H
a=Buf[2]/16; if(a>3)a-=4;
UART_PutChar(a+'0');//Upper bits
UART_PutChar(Buf[2]%16+'0');//Lower bits
UART_PutChar('h');
//M x4218421
a=Buf[1]/16; if(a>7)a-=8;
UART_PutChar(a+'0');//Upper bits
UART_PutChar(Buf[1]%16+'0');//Lower bits
UART_PutChar('m');
//S x4218421
a=Buf[0]/16; if(a>7)a-=8;
UART_PutChar(a+'0');//Upper bits
UART_PutChar(Buf[0]%16+'0');//Lower bits
UART_PutChar('s');
UART_PutChar(0x0a);//LF
UART_PutChar(0x0d);//CR
for(j=0;j<20;j++)for(i=0;i<20000;i++){}//Wait
}//while(1)

}

2010年11月20日土曜日

Arduino(アルドゥイーノ)入門


Arduino(アルドゥイーノ)の使い方などまとめてみました.
(Arduinoとは)
AT-Megaをベースとしたマイコンモジュールです.起動に必要なプログラム(ブートローダー)
がプログラムされたAT-Mega+PCとシリアル通信できる回路が基本的な構成です.
PCとはUSBで接続した場合,電源供給もUSBで行えます.
Arduino本体と開発ソフト(Arduino IDE)があればすぐにプログラムを実行できます.
ATマイコンやPSOCと比べても,最初のプログラム実行(LED点滅)までのハードルは
低いと思います.
AD変換,シリアル通信,時間管理などが,ATマイコン単独のプログラミングより
とても容易です.
価格はATマイコン単独より高いです.周辺回路を含むため,ATマイコン単独より
サイズが大きく,消費電流も大きくなります.
ATマイコンの機能を最大限に引き出すのは難しいです.例えば,AT-Megaをアセンブラで
動かす場合,MHz以上のクロック単位の高速の処理ができますが,Arduinoでは難しいです.

(Arduinoの種類)
使用するAT-Megaマイコン,電源電圧,クロック,周辺機能などにより色々なバージョンがあります.
Arduino Uno:ATmega328,5V,Flash Memory32KB,SRAM2 KB,EEPROM1 KB,Clock Speed16 MHz
本体がAT-Megaを含む比較的大きなボードなので,学習用には向いていますが小回りは利きません.
ArduinoProMini:ATmega168,3.3V版と5V版あり,Flash Memory16KB,SRAM1KB,EEPROM512B,ClockSpeed8MHz(3.3V) ,16 MHz(5V)USB-シリアル変換機能は別
Arduino Fio:ATmega328P,3.3V,Flash Memory32KB,SRAM2KB,EEPROM1KB,ClockSpeed8MHz
XBEEのソケットが付いていますので,すぐに無線対応となります.
Arduino Nano 3.0:ATmega328,5V,Flash Memory32KB,SRAM2KB,EEPROM1KB,ClockSpeed16MHz

(Arduino実行の手順)
開発環境ソフト(フリー)をPCにダウンロードして,Program Files内に展開します.展開したファイルは300Mぐらいのサイズがあります.
setupは不要で,展開したフォルダ内にあるarduino.exeをダブルクリックすると起動します.ソースプログラムを記述します.Boardのオプションで使用するArduinoを選び,Verifyのボタンでコンパイルします.
ArduinoとPCをUSBで接続します.USB-シリアル変換機能のないAruduinoの場合,USB-シリアル変換モジュールと,GND,CTS,VCC,TXD,RXD,DTRの接続を行います.
ToolsのSerialPortで,USBポートを指定し,Uploadのボタンで,プログラムがシリアル通信経由でArduinoに送られ,Arduinoが動きます.

(Arduinoのソースプログラム)
Arduinoのソースプログラムは,スケッチと呼ばれます.スケッチは,C言語に似ており,setup()関数とloop()関数から構成されます.
setup()関数に入出力などの初期設定を記述し,loop()関数に通常の繰り返し動作を記述します.

(ATmega168をArduino化する)
ATmega168の設定
AVRISPmkIIまたはAVRDragonとATmega168のターゲットを接続し,
AVRStudioを起動する.
ProgramAVRを起動する.
MainタブでEraseDeviceする(そうしないとLockbitsを書き換えられない)
ブートローダー(ATmegaBOOT_168.hexやATmegaBOOT_168_diecimila.hex)をプログラムする.
ATmegaBOOT_168_diecimila.hexはArduino IDEをダウンロードすると付いてくる.
FUSESを以下のようにプログラムする
EXTENDED 0xF8
HIGH 0xDF
LOW 0xFF
LockBitsを0xCFにプログラムする
Fuseの書き換えの際.ターゲットの電圧が低いとうまく書き換えられないので注意.Programのボタンを2度押すと,うまく書き換えられることもある.

FT232モジュールとMega168を接続する
VCC-VCC
GND-GND
TXD RXD
RXD TXD
Mega168のRESETピンは,10kΩでVCCに接続し,0.1μFでDTR(またはRTS)と接続する.
Mega168に16MHz発振子を接続する.(20pFのコンデンサは使わなくても動作する)セラロックでもOK.
Arduino IDEでBoardの選択をArudinoDiecimila or Duemilanove w/ATMEGA 168にすれば動きます.

(液晶表示)
Arduino化したAT-Mega168で液晶モジュールに表示するプログラムです.
DMC16117Aなどの横1列のピン配列のモジュールに対応しています.
接続リード線の数を減らすため,DB4-7をAT-Mega168の15-18ピンに対応させました.
液晶モジュールのコントラスト(Vo,VLC)とR/WはGNDに接続しています.
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);の行は,液晶表示のオブジェクト生成のようなもので,
ここでは名前をlcd(たぶん任意)にしています.ここで引数の数で,対応するピンが変わるので注意が必要です.引数が6個の場合,R/WはGNDに接続していますが,引数を7個にした場合,(rs, rw, enable, d4, d5, d6, d7) の順で,R/WとArduinoの接続が必要になります.

//testLCD
//LCD:Arduino(Mega168)
//VSS:GND
//VCC:VCC
//Vo:GND
//RS:D7(PIN13)
//R/W:GND
//E:D8(PIN14)
//DB0-3:NC
//DB4:D9(PIN15)
//DB5:D10(PIN16)
//DB6:D11(PIN17)
//DB7:D12(PIN18)
#include
//ATMega168 13,14,15,16,17,18PIN
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Arduino");
}
void loop() {
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
}

(学研のJapanino)
学研の大人の科学を入手し,付録のJapanino(Arduino互換)を試してみました.Japaninoは,内部発振8MHzのmaga168を使っています.多くの人が指摘していますが,回路には8MHz水晶発振子が入っているのに,なぜか内部発振で動いています.またUSB-シリアル変換が,CP210Xという,純正Arduinoとは異なる会社のものを使っています.税込み3360円という値段で,Arduino互換が楽しめるのでお買い得だと思います.
学研のサイトからArduino IDEをダウンロードします.またCP210Xドライバをインストールします.書き込みの際,Boardの選択でGakkenJapaninoを選択します.
すでにArduino IDEをインストール済みの人は,Boardの選択でArduino Pro or Pro Mini (3.3V,8MHz) w/ATmega168 を選択すれば,書き込み実行ができます.

(電子オルゴール)
Japaninoには,圧電サウンダも付いているので,簡単に電子オルゴールが作れます.関数を使った電子オルゴールのプログラムを作ってみました.Japaninoのサンプルプログラムでは,音程,音符で異なる配列を使っています.また音階のためのpitches.hをインクルードしています.インクルードを使わず,play()という関数を使いました.#define文で,A5はすでにピン名として定義済みですので,AA5としています.キーと長さのplay関数を並べるだけなので,サンプルプログラムより簡単に音楽を編集できると思います.

#define C5 523
#define CS5 554
#define D5 587
#define DS5 622
#define E5 659
#define F5 698
#define FS5 740
#define G5 784
#define GS5 831
#define AA5 880

void play(unsigned int note, int t){
tone(14, note, 2000.0/t);
delay(2000.0/t*1.10);
noTone(14);
}
void setup() {
}
void loop() {
play(G5,4);play(E5,4);play(E5,2);
play(F5,4);play(D5,4);play(D5,2);
play(C5,4);play(D5,4);play(E5,4);play(F5,4);
play(G5,4);play(G5,4);play(G5,2);
play(G5,4);play(E5,4);play(E5,4);play(E5,4);
play(F5,4);play(D5,4);play(D5,4);play(D5,4);
play(C5,4);play(E5,4);play(G5,4);play(G5,4);
play(E5,4);play(E5,4);play(E5,2);
play(D5,4);play(D5,4);play(D5,4);play(D5,4);
play(D5,4);play(E5,4);play(F5,2);
play(E5,4);play(E5,4);play(E5,4);play(E5,4);
play(E5,4);play(F5,4);play(G5,2);
play(G5,4);play(E5,4);play(E5,4);play(E5,4);
play(F5,4);play(D5,4);play(D5,2);
play(C5,4);play(E5,4);play(G5,4);play(G5,4);
play(E5,4);play(E5,4);play(E5,2);
delay(1000);
}

2010年6月22日火曜日

PSocでIrDA
























PSocでIrDAのテスト

(送信側)
IrDAでは,常時信号がHigh(1)で,信号がLow(0)の時だけ0Vとなる.そして信号がLow(0)の時だけIRLEDが発光する.
データシートでは,送信で,CLKOutputとTXOutputの出力端子,をプルダウンに設定し,これら2つの出力端子を外部で接続すればORとなるとあるが,この場合直接LEDを駆動するのには出力が弱すぎる.そこで今回は,CLKOutputとTXOutputをPSOC内部でORをとり,P00(Strong)に出力した.VCC-IRLED-P00と接続し,出力LOWでLEDが発光する.IRLEDは数10mA電流が流せるので,抵抗を使わずVCC-IRLED-P00と直結した.
IrDATXのテストプログラム'a','b','c','d'の文字を9600bpsで送信する
27443を使い6_MHz(SysClk/4),3V駆動
VC1=SysClk/4
VC2=VC1/6
VC3=VC2/13(≒9800×8)
VC3をBitClock,BaudClkとした


ソースプログラム

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
void main(void)
{
unsigned int i;
char x='a';
IrDATX_Start();
while(1){
IrDATX_SendData(x);
x++;
if(x>'d')x='a';
for(i=0;i<30000;i++){}//wait
for(i=0;i<30000;i++){}
for(i=0;i<30000;i++){}
for(i=0;i<30000;i++){}
}
}

(受信側)
受信では,フォトトランジスタの信号を,赤外受光でLowとなるようコンパレータで信号を変換した.今回は,IRフォトトランジスタの信号をコンパレータTLV2461でHighが0Vになるようレベル変換した.
27443でIrDARXのテストプログラム,受信したデータ9600bpsをLCDに表示する
LCD表示のため5V駆動
PSOCの信号入力端子は,P00(High Z),
BitTimerOutputの出力端子はP01(Pull Up),P00とP01を接続し
受信信号を1kΩでP00,P01に接続する.
BitTimerのInvertBitTimerFeedBackINをInvertにする
VC1=SysCLK(24M)/4
VC2=VC1/6
VC3=VC2/13≒9600×8
BitTimerCLKとBaudCLKは,通信速度9600の8倍VC3にした

ソースプログラム

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules


void main(void)
{
BYTE a,bRxStatus;
IrDARX_Start();
LCD_Start(); // Initialize LCD
LCD_Position(0,0); // Place LCD cursor at row 0, col 5.
while(1){
// wait for receiver to detect start bit
while( !( IrDARX_bReadRxStatus() & IrDA_RX_ACTIVE ) ) {}
// Start bit detected, wait to receive rest of data
while ( !( bRxStatus = IrDARX_bReadRxStatus() & IrDA_RX_COMPLETE ) ){}
a = IrDARX_bReadRxData();
/*
LCD_WriteData(a);
*/
if(a>='d'){LCD_Position(0,0);LCD_PrCString(" ");LCD_Position(0,0);}// Clear LCD
else LCD_WriteData(a);
}
}

2010年2月16日火曜日

Xbeeを使い無線でシリアル通信を行う










Xbeeを使い無線でシリアル通信を行うためのメモです
Series1とSeries2があって互換性がない.相互通信できない.
アンテナのタイプが3種類ある.室内で簡単な通信を行うなら,whipまたはChipアンテナ.屋外で回路をカバーで保護したい場合は,外付けアンテナが良い.
Xbeeのピンは,2mmピッチなので通常の基板にさせない.テスト用には,上部にリード線を
ハンダ付けるるのが簡単.
Xbeeは20ピンあり,単に通信で使うだけなら,VCC(1),DOUT(2),DIN(3),GND(10)のみ使う.
省電力のため通信時以外は休止(Hibernate)させたい場合,SM=1として,SleepModeとする.この場合,9pinをHighで休止,Lowで活動となる.

Xbeeの供給電源は2.8-3.4V,ちなみにADM3202は3-5.5V.
電池×3(4.5V)でも動く.
XBEEの通信速度はdefaultで9600

(はじめの一歩)
PCとXbeeを接続する方法は,Comポートからレベル変換(ADM3202)で接続する方法と,USBシリアル変換モジュールFT232RLで接続する方法がある.FT232RLで接続する方が,接続も簡単だし,FT232RLから3.3Vの電源も取り出せて便利である.
Xbeeの設定はX-CTUを使う.X-CTUはDigi-MaxStreamのサイトからダウンロードできる.
PCにXbeeを接続した状態でX-CTUを立ち上げ,Modem Configurationで
パラメータをリードして,変更したい設定を書き替えてライトすればよい.

(2台のPCを使ったテストの例)
PC-COM-ADM3202-XBEE-(無線)-XBEE-ADM3202-COM-PC
PC-USB-FT232RL-XBEE-(無線)-XBEE-FT232RL-USB-PC
通信は,Teraterm等の通信ソフトやX-CTUでできる.

(XBEEの設定の例)
Series1で1対1の接続の場合
自分のアドレスMYと相手のアドレスDLを互い違いになるように設定する.
Series1で多対多の接続の場合
自分のアドレスMYをゼロ(0)と相手のアドレスDLもゼロ(0)に設定する.
Series2で多対多の接続の場合
それぞれのXBEEのFunctionSetをZigbee router/End device ATに設定する.
DHをゼロ(0),DLを0X0000FFFFに設定する.
こうするとbroadcastの設定となり全XBEEに信号を送れる.
Series2で1対多の接続の場合
1台のXBEEのFunctionSetをZigbee coordinator ATに設定する.
DHをゼロ(0),DLを0X0000FFFFに設定する.
残りのXBEEのFunctionSetをZigbee router/End device ATに設定する.
DH,DLにはcoordinatorのSerialNumberのHighとLowを入れる.
こうするとcoordinatorは残りの全XBEEに信号を送り(broadcast)
各router/End deviceはcoordinatorにのみ信号を送る.

(ターミナルソフト)
シリアル通信のターミナルソフトとしてはやはりTeraTermが便利である.
お互いに画面に表示を行い通信を行うに場合は,
TeraTermの設定・端末・改行コードを「送信:CR+LF」「受信:CR」とすればよい

(AT-mega88を使ったシリアル通信のテストプログラム)
/*
adcom88.c
mega88p用AD変換,シリアル通信のプログラム
Ext8MHz分周なし
ADC0(PC0)は入力,可変抵抗の電圧を入力する
電源5V
ADCSR=0B11000000でAD変換がスタートし,ADIF=1でAD変換完了
AVCCとVCCを接続,AVGND(22ピン)とGNDを接続,AREFは無接続
AD変換の精度を確保するためにはADPS0-2で
A/D変換クロックを50-200kHzに設定する必要あり
CK=8MHzのときCK/64=125kHz
avrデータシートのUSARTサンプルプログラムでは
データを受信する関数は,データが来るまで待ち続けるので
データが来ないときには'*'を返すように変更した
*/
#include <avr/io.h>

//マイクロ秒単位の待ち(t<256)
void delay(uint8_t t){
TCCR0B=0B00000010;//タイマカウンタ0の分周をセットCK/8
TCNT0=0;
while(TCNT0<t){}
}

void Utx(uint8_t data) //マイコンがデータを送信する
{
while ( !(UCSR0A & (1<<UDRE0)) );
UDR0 = data;
}

uint8_t Urx(void)//マイコンがデータを受信する(修正)
{
if(UCSR0A & (1<<RXC0))return UDR0;
else return '*';
}

int main( void )
{
int16_t i,baud;
uint8_t ad,dat,st=0;
dat='e';

//USART
baud=8000000/16/9600-1;//ボーレートの計算
UBRR0H = (uint8_t)(baud>>8);//ボーレート上位
UBRR0L = (uint8_t)baud; //ボーレート下位
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
UCSR0B = (1<<RXEN0)|(1<<TXEN0);//送受信可

//AD
ADMUX=0B11100000; //基準電圧1.1V Left Adjust ADC0(PC0)
ADCSRA=0B10000110; //CK/64

while((dat = Urx())!='s'){}
while(1){
dat = Urx();
if(dat=='s')st=1;
if(dat=='e')st=0;

if(st==1){
//AD
ADCSRA |= 1<<ADSC; //AD start
while(!(ADCSRA & (1<<ADIF))){} //ADCSRのビット4(ADIF)が1になるまで待つ
ad=ADCH;
//AD to dec, send data
dat=ad/100+'0';
Utx(dat);
ad%=100;
dat=ad/10+'0';
Utx(dat);
ad%=10;
dat=ad+'0';
Utx(dat);
Utx(0x0a); //LF
Utx(0x0d); //CR
}//if(st==1)
for(i=0;i<4000;i++)delay(250);//wait 1s

}//while(1)

}