04.29.19:25
[PR]
03.27.00:33
ペリフェラルを利用しないマイコン間シリアル通信
マイコンには多くの通信機能が搭載されています。私が今開発に用いているAVRマイコン(ATMega1284P)にはSPI, TWI, USARTなどの通信機能があります。これらの通信機能はマイコン内部のハードウェア上で行っているのでソフトウェア上でそれを再現するより高速でしょう。
まずペリフェラルを利用しないマイコン間シリアル通信をするメリットを挙げてみます。- SPIは1対多の通信をサポートしていますが新しいモジュールと通信するときなど不安要素はなるべくなくしておきたいものです。対象のモジュールはSPIを使いマイコン間通信はソフトウェアで行えば安心です。
- 今回の通信方法は超低速マイコンと高速マイコンの通信でも動作します。(人 対 マイコンなど笑)
- I/Oさえあれば動くので楽です
使用するピンですが超低速マイコンと高速マイコンの通信でも動作させるためにDREQピンを使います。
- SCK
- MISO
- MOSI
- DREQ
//COMピン
#define COM_PORT_OUT PORTB
#define COM_PORT_IN PINB
#define C_SCK 0
#define C_MISO 1
#define C_MOSI 2
#define C_DREQ 3
回路はお互いに同じピンをつなぐだけです。
あとは下のフローチャートに従って通信します。
参考にAVRのコードを載せておきます
1. Master側
//シリアル送受信関数 Master
// uint8_t COMSendData(uint8_t data);
// r24 : data(u8bit)
.GLOBAL COMSendData
.FUNC COMSendData
COMSendData:
.irp bit, 7,6,5,4,3,2,1,0
CBI _SFR_IO_ADDR(COM_PORT_OUT), C_SCK
;MOSI
CBI _SFR_IO_ADDR(COM_PORT_OUT), C_MOSI
SBRC r24, \bit
SBI _SFR_IO_ADDR(COM_PORT_OUT), C_MOSI
DREQ_LOOP_L\bit:
SBIC _SFR_IO_ADDR(COM_PORT_IN), C_DREQ
RJMP DREQ_LOOP_L\bit
SBI _SFR_IO_ADDR(COM_PORT_OUT), C_SCK
DREQ_LOOP_H\bit:
SBIS _SFR_IO_ADDR(COM_PORT_IN), C_DREQ
RJMP DREQ_LOOP_H\bit
;MISO
CBR r25, (1 << \bit)
SBIC _SFR_IO_ADDR(COM_PORT_IN), C_MISO
SBR r25, (1 << \bit)
.endr
MOV r24, r25
RET
.ENDFUNC
2. Slave側
//シリアル送受信関数 Slave
// uint8_t COMRecvData(uint8_t data);
// r24 : data(u8bit)
.GLOBAL COMRecvData
.FUNC COMRecvData
COMRecvData:
.irp bit, 7,6,5,4,3,2,1,0
SCK_LOOP_L\bit:
SBIC _SFR_IO_ADDR(COM_PORT_IN), C_SCK
RJMP SCK_LOOP_L\bit
CBI _SFR_IO_ADDR(COM_PORT_OUT), C_DREQ
SCK_LOOP_H\bit:
SBIS _SFR_IO_ADDR(COM_PORT_IN), C_SCK
RJMP SCK_LOOP_H\bit
;MOSI
CBR r25, (1 << \bit)
SBIC _SFR_IO_ADDR(COM_PORT_IN), C_MOSI
SBR r25, (1 << \bit)
;MISO
CBI _SFR_IO_ADDR(COM_PORT_OUT), C_MISO
SBRC r24, \bit
SBI _SFR_IO_ADDR(COM_PORT_OUT), C_MISO
SBI _SFR_IO_ADDR(COM_PORT_OUT), C_DREQ
.endr
MOV r24, r25
RET
.ENDFUNC
引数には送信するデータを渡してあげると受信したデータが関数から返ってきます。
PR
- トラックバックURLはこちら