Arduino同士でI2C通信してもらいます。
R4がMaster、R3がSlaveでR3はI2Cメモリーとして働いてもらいます。R4のI/Oが5Vなので、R3とレベル変換なしに通信できるのがいい。さすがルネ。
I2Cの接続はとても簡単です。SCL同士、SDA同士を接続するだけ。
wire_master_study1.ino
#include <stdint.h>
#include <Wire.h>
uint8_t slave_address = 0x55;
uint16_t slave_memadr[] = {0x0000, 0x0010, 0x0020, 0x0130};
void setup(void)
{
Wire.begin();
Serial.begin(115200);
}
uint8_t cnt = 0;
void loop(void)
{
uint8_t txbuf[16];
uint8_t rxbuf[16];
uint8_t i;
char uart_txbuf[128];
for (i = 0; i < 16; i++){
txbuf[i] = cnt + i;
}
Serial.println("start ");
sprintf(
uart_txbuf,
"%04X : %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
slave_memadr[0], txbuf[0], txbuf[1], txbuf[2], txbuf[3], txbuf[4], txbuf[5], txbuf[6], txbuf[7],
txbuf[8], txbuf[9], txbuf[10], txbuf[11], txbuf[12], txbuf[13], txbuf[14], txbuf[15]);
Serial.println(uart_txbuf);
Wire.beginTransmission(slave_address);
Wire.write((uint8_t)((slave_memadr[0] >> 8) & 0x00FF));
Wire.write((uint8_t)((slave_memadr[0] >> 0) & 0x00FF));
for (i = 0; i < 16; i++){
Wire.write(txbuf[i]);
}
Wire.endTransmission();
delay(10);
Wire.beginTransmission(slave_address);
Wire.write((uint8_t)((slave_memadr[0] >> 8) & 0x00FF));
Wire.write((uint8_t)((slave_memadr[0] >> 0) & 0x00FF));
//Wire.endTransmission();
Wire.requestFrom(slave_address, 16);
for (i = 0; i < 16; i++){
rxbuf[i] = Wire.read();
}
Wire.endTransmission();
sprintf(
uart_txbuf,
" %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7],
rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11], rxbuf[12], rxbuf[13], rxbuf[14], rxbuf[15]);
Serial.println(uart_txbuf);
cnt = ((cnt + 1) & 0x3F);
delay(1000);
}
wire_slave_study1.ino
#include <Wire.h>
uint8_t slave_address = 0x55;
uint8_t slave_memory[0x0500];
uint16_t adr;
uint8_t recv_flag;
void requestEvent(){
uint8_t n;
uint16_t i = 0;
for (n = 0, i = 0; n < 64; n++, i++){
Wire.write(slave_memory[adr + i]);
}
}
void receiveEvent(int n){
uint16_t i = 0;
if (Wire.available()){
adr = (uint16_t)(Wire.read()) * 256;
}
if (Wire.available()){
adr = adr + (uint16_t)(Wire.read());
}
while (Wire.available()){
slave_memory[adr + i] = Wire.read();
i = i + 1;
}
recv_flag = 1;
}
void setup(void)
{
pinMode(A5, INPUT_PULLUP);
pinMode(A4, INPUT_PULLUP);
Wire.begin(slave_address);
Serial.begin(115200);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
recv_flag = 0;
}
void loop(void)
{
char uart_txbuf[16];
uint16_t i;
if (recv_flag == 1){
recv_flag = 0;
sprintf(uart_txbuf, "%04X : ", adr);
Serial.print(uart_txbuf);
for (i = 0; i < 16; i++){
sprintf(uart_txbuf, "%02X", slave_memory[adr + i]);
Serial.print(uart_txbuf);
}
Serial.println("");
}
}
はい。いつも通りのいきなりな感じです。デバイスアドレスは0x55で1バイト目がメモリ(のふり)のアドレスのHighバイトで、2バイト目がLowバイトを指示する。Slave側はこれを記憶しておく。続けてデータが来れば、それを保存していき、リクエストが来ればWire.writeでデータを返送する。
通信の全体像はこんな感じ。
Masterが送っている(書き込んでいる(つもり))部分はこんな感じ。
Masterが要求してSlaveが返答している部分はこんな感じ。
いい感じです。
いやーついでといえばついでで久しぶりに更新しましたー。
ついでがなければ、冬休みまで放置するところやったわ。ここ1,2ヶ月でも世の中がどんどん混沌としてきて、どうなっちゃうんやろ。
供給を人質にして、(自らが作りこんだ)問題の対応にコストアップを要求してくるメーカーがあったり、まさに苦難の行軍。



0 件のコメント:
コメントを投稿