史也 菅
/
I2c_slave
encslave
Revision 2:2ee241819861, committed 2021-09-01
- Comitter:
- kurobikari
- Date:
- Wed Sep 01 07:01:56 2021 +0000
- Parent:
- 1:7945cd701d0d
- Commit message:
- aaaa
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CANMsg.lib Wed Sep 01 07:01:56 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/kurobikari/code/CanMsga/#4f03cb1e882b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/can.cpp Wed Sep 01 07:01:56 2021 +0000 @@ -0,0 +1,95 @@ +//#include "YKNCT_MD.h" +#include "can.h" +#include "mbed.h" +/******************************************************************************* + * @名称 YKNCT_MD_I2C + * @概要 I2Cモジュール"MD"用ライブラリ +*******************************************************************************/ + + +/* 送信データ +[0] [| none | none | none | none | none | none |LAP or SMB| |LAP or SMB|] +[1] PWM値1 +[2] PWM値2 +*/ + +YKNCT_MD_CAN::YKNCT_MD_CAN(PinName rd, PinName td,int t) : can(rd, td,t) +{ + /* 初期化 */ + NumCnt = 0; + /* 送信割り込み */ + interrupt.attach_us(this,&YKNCT_MD_CAN::sent,1800); + /* 受信割り込み */ + can.attach(this,&YKNCT_MD_CAN::onCanReceived); +} +void YKNCT_MD_CAN::Init(int8_t address, MD_ModeStatus_TypeDef mode) +{ + /* アドレス設定 */ + txMsg[NumCnt/2].id = address+CAN_TX_ADDRESS; + /* モード設定 */ + txMsg[NumCnt/2].data[0] |= mode<<NumCnt%2; + /* 出力状態初期化 */ + txMsg[NumCnt/2].data[NumCnt%2+1] = 0; + /* カウンター増やす */ + Rx_Id[NumCnt] = CAN_RX_ADDRESS+NumCnt; + NumCnt++; +} +void YKNCT_MD_CAN::Set(int8_t ConNumber, int16_t val) +{ + Set(ConNumber, val, MD_BRAKE); +} + +void YKNCT_MD_CAN::Set(int8_t ConNumber, int16_t val, MD_BrakeStatus_TypeDef option) +{ + int PWM = 0; + PWM = abs(val); + PWM = Rest(PWM,95); + + /* 送るバイト数設定 */ + txMsg[ConNumber/2].len=3; + + /* idを設定 */ + txMsg[ConNumber/2].id = ConNumber/2+CAN_TX_ADDRESS; + + /* マイナスならフラグ立てる */ + if(val<0) + txMsg[ConNumber/2].data[ConNumber%2+1] |= (1<<7); + + /* データセット PWMを各配列に代入 */ + txMsg[ConNumber/2].data[ConNumber%2+1] |=(char) PWM; +} + +int16_t YKNCT_MD_CAN::Get_enc(int8_t ConNumber) +{ + + return (int)(double)(data[ConNumber]); +} + +void YKNCT_MD_CAN::Exe(void) +{ + static int Scnt=0; + /* 送信 */ + can.write(txMsg[Scnt]); + Scnt++; + Scnt%=NumCnt; +} + +void YKNCT_MD_CAN::onCanReceived(void) +{ + static int cnt=0; + can.read(rxMsg); + for(int i=0; i<NumCnt; i++) { + if (rxMsg.id == Rx_Id[i]) { + /* エンコーダのデータ受信 一つの基板に付き二つ受信*/ + data[cnt]=(int)((rxMsg.data[2]<<4|rxMsg.data[1]>>4)&0x0fff); + data[cnt+1]=(int)((rxMsg.data[1]<<8|rxMsg.data[0])&0x0fff); + } + cnt+=2; + } + cnt=0; +} + +void YKNCT_MD_CAN::sent(void) +{ + Exe(); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/can.h Wed Sep 01 07:01:56 2021 +0000 @@ -0,0 +1,79 @@ +#ifndef INCLUDED_can_h_ +#define INCLUDED_can_h_ + +#include "mbed.h" +#include "CAN.h" +#include "CANMsg.h" +//#include "YKNCT_I2C.h" + +/* 定数定義 ------------------------------------------------------------------*/ + +/* 分解能(最大255まで有効)*/ +#define MD_RESOLUTION 100 +#define MD_max 10 +#define ABS(__VAL__) (((__VAL__) < 0) ? (-(__VAL__)) : (__VAL__)) +#define Rest(__val__, __Limit__) ((__val__) >= (__Limit__) ? (__Limit__) : ((__val__) <= (-(__Limit__)) ? (-(__Limit__)) : (__val__))) +#define CAN_TX_ADDRESS 50 +#define CAN_RX_ADDRESS 0 + +typedef enum { + MD_SMB, + MD_LAP +} MD_ModeStatus_TypeDef; + +typedef enum { + MD_FREE, + MD_BRAKE=2 +} MD_BrakeStatus_TypeDef; + +typedef enum { + MD_FORWARD, + MD_REVERSE +} MD_DriveStatus_TypeDef; + +/* クラス定義 ----------------------------------------------------------------*/ + +/******************************************************************************* + * @名称 YKNCT_MD_I2C + * @概要 I2Cモジュール"MD"用ライブラリ +*******************************************************************************/ +class YKNCT_MD_CAN +{ +private: + /* 出力先の数をカウントする */ + int8_t NumCnt; + /* 送信データ + [0] [ MD出力更新 | 0 | 0 | 0 | 0 | ブレーキ | 回転方向 | SMP/RAP ] + [1] PWM値(7bit) + */ + int32_t data[MD_max]; + + /* CAN受信用 */ + CANMsg rxMsg; + /* CAN送信用 */ + CANMsg txMsg[MD_max]; + /* 送信割り込み */ + Ticker interrupt; + + int8_t Rx_Id[MD_max]; +public: + CAN can; + //can.attach(onCanReceived); + /* I2CのバスのInit */ + YKNCT_MD_CAN(PinName rd, PinName td,int t); + /* アドレス,モードを設定する */ + void Init(int8_t address, MD_ModeStatus_TypeDef mode); + /* 出力値を設定する */ + void Set(int8_t ConNumber, int16_t val); + /* 出力値を設定する(モーター開放あり) */ + void Set(int8_t ConNumber, int16_t val, MD_BrakeStatus_TypeDef option); + /* 出力値を確認する */ + int16_t Get_enc(int8_t ConNumber); + /* 設定された出力値の出力をする */ + void Exe(void); + /* 割り込み用関数 */ + void sent(void); + /* 受信用関数 */ + void onCanReceived(void); +}; +#endif \ No newline at end of file
--- a/main.cpp Sat Dec 07 00:42:48 2019 +0000 +++ b/main.cpp Wed Sep 01 07:01:56 2021 +0000 @@ -1,122 +1,45 @@ #include "mbed.h" - -#define SDA PB_7 -#define SCL PB_6 +#include "can.h" +/* PCへのプリント用 */ +Serial pc(USBTX, USBRX); -/*クラス宣言*/ -I2CSlave slave(SDA, SCL); -Serial pc(USBTX, USBRX); - +/* CAN宣言 */ +YKNCT_MD_CAN MD(PA_11,PA_12,500000);//(rd , td, 周波数, 送信割り込み速度) -/*In,Out宣言*/ -DigitalOut CS (PA_1); -DigitalOut CLK (PA_2); -DigitalIn Do (PB_5); -DigitalOut led[4]={PA_4,PA_5,PA_6,PA_7}; -DigitalOut k (PB_3); -/*変数宣言*/ -unsigned long data = 0; -char msg[5]={0}; -int enc_deg[2]; //角度を保存する変数 -int cnt = 0; //割り込んだ回数を保存する -long deg = 0; //DOの値を保存 -int64_t sent_data=0; +/* ----------------メイン----------------------- */ +int main(void) +{ + /* プリントのボーレート設定 */ + pc.baud(115200); + /* MD初期化 */ + MD.Init(0,MD_SMB); + MD.Init(1,MD_LAP); + MD.Init(2,MD_SMB); + MD.Init(3,MD_LAP); + MD.Init(4,MD_SMB); + MD.Init(5,MD_LAP); + MD.Init(6,MD_SMB); + MD.Init(7,MD_LAP); -int main() -{ - msg[0]=0; - msg[1]=0; - slave.frequency(100000); - int receive; - slave.address(1); while(1) { - - receive = slave.receive(); - //cntが偶数の場合の処理 - if (cnt % 2 == 0) { - if (cnt == 0) { - CS=0; - data = 0; - } - CLK=1; - } - - //cntが奇数の場合の処理 - else { - if (cnt != 1) data |= Do; //cntが1ではない時の処理 - //cntが25ではない時の処理 - if (cnt != 25) { - data <<= 1; - CLK=0; - } - //cntが25の時の処理 - else { - /* 前回の値更新 - 今回の値更新(エンコーダの値(0?4096)を角度(0?360)に) */ - enc_deg[1] = enc_deg[0]; - enc_deg[0] = data * 360 / 4096; - - /* 前回270度以上,今回90度より小さい… 359→0を跨いだ時 - 前回の値を0から逆回転で負の値で表記 */ - if ((270 <= enc_deg[1] ) && (enc_deg[0] < 90)) enc_deg[1] -= 360; - - /* 0→359を跨いだ時, - 前回の値を360以上の値で表記 */ - else if ((enc_deg[1] < 90) && (270 <= enc_deg[0])) enc_deg[1] += 360; - - deg += enc_deg[0] - enc_deg[1]; - - sent_data=deg; - CS=1; - + /* MD実行 */ + MD.Set(0,100); + MD.Set(1,100); + MD.Set(2,100); + MD.Set(3,0); + MD.Set(4,0); + MD.Set(5,50); + MD.Set(6,0); + MD.Set(7,50); - if(receive){ - - msg[0]=sent_data; - msg[1]=sent_data>>8; - msg[2]=sent_data>>16; - msg[3]=sent_data>>24; - slave.write(msg,4); - } - - /* LEDの管理 */ - static int LED_cnt=0; - static int LED_flag=0; - static long log[2]={0}; - - /* logデータの更新 */ - log[1]=log[0]; - log[0]=sent_data<<24|sent_data<<16|sent_data<<8|sent_data; - /* 変化の正負に応じてLED点灯 */ - if((log[0]-log[1])>1)led[0]=1; - else led[0]=0; - if(((log[0]-log[1])<0?-1:1)*(log[0]-log[1])<=1) led[1]=1; - else led[1]=0; - if((log[1]-log[0])>1) led[2]=1; - else led[2]=0; - - LED_cnt++; - LED_cnt%=10; - if(LED_cnt==0) LED_flag++; - LED_flag%=2; - if(LED_flag) led[3]=1; - else led[3]=0; - - } - - } - cnt++; - cnt %= 26; - + /* エンコーダ取得 */ + for(int i=0; i<8; i++) + pc.printf("%d ",MD.Get_enc(i)); + pc.printf("\n\r"); - - + } +} - - - } - -} \ No newline at end of file