基板マイコンカー製作キットVer.2 プログラム解説マニュアル

Similar documents
デュアルショック2制御基板 製作・プログラム解説マニュアル(R8C/38A版)

KINGSOFT Office 2016 動 作 環 境 対 応 日 本 語 版 版 共 通 利 用 上 記 動 作 以 上 以 上 空 容 量 以 上 他 接 続 環 境 推 奨 必 要 2

積 載 せず かつ 燃 料 冷 却 水 及 び 潤 滑 油 の 全 量 を 搭 載 し 自 動 車 製 作 者 が 定 める 工 具 及 び 付 属 品 (スペアタイヤを 含 む )を 全 て 装 備 した 状 態 をいう この 場 合 に おいて 燃 料 の 全 量 を 搭 載 するとは 燃 料

ミニマイコンカー製作キットVer.2 C言語走行プログラム解説マニュアル

目 次 1. 積 算 内 訳 書 に 関 する 留 意 事 項 1 ページ 2. 積 算 内 訳 書 のダウンロード 3 ページ 3. 積 算 内 訳 書 の 作 成 (Excel 2003の 場 合 ) 6 ページ 4. 積 算 内 訳 書 の 作 成 (Excel 2007の 場 合 ) 13

別冊資料-11

購買ポータルサイトyOASIS簡易説明書 b

POWER EGG V2.01 ユーザーズマニュアル ファイル管理編

HTG-35U ブルーバック表示の手順書 (2014年12月改定)

ファイルサーバー(NFS) 構築ガイド

R4財務対応障害一覧

4 応 募 者 向 けメニュー 画 面 が 表 示 されます 応 募 者 向 けメニュー 画 面 で [ 交 付 内 定 時 の 手 続 を 行 う] [ 交 付 決 定 後 の 手 続 を 行 う]をクリックします 10

<4D F736F F D2090BF8B818AC7979D8B40945C91808DEC837D836A B2E646F63>

<4D F736F F D2095CA8E A90DA91B18C9F93A289F1939A8F D8288B3816A5F E646F63>

ができます 4. 対 象 取 引 の 範 囲 第 1 項 のポイント 付 与 の 具 体 的 な 条 件 対 象 取 引 自 体 の 条 件 は 各 加 盟 店 が 定 めます 5.ポイントサービスの 利 用 終 了 その 他 いかなる 理 由 によっても 付 与 されたポイントを 換 金 すること

事前チェック提出用現況報告書作成ツール入力マニュアル(法人用)

の と す る (1) 防 犯 カ メ ラ を 購 入 し 設 置 ( 新 設 又 は 増 設 に 限 る ) す る こ と (2) 設 置 す る 防 犯 カ メ ラ は 新 設 又 は 既 設 の 録 画 機 と 接 続 す る こ と た だ し 録 画 機 能 付 防 犯 カ メ ラ は

目 次 目 次 1 ログイン ログアウト ログインする...1 ログイン 画 面 が 表 示 されないときは?... 1 初 めてログインするときのパスワードは?... 2 初 期 パスワードを 忘 れてしまったときは?... 2 変 更 したパスワードを 忘 れてしまったときは?.


赤外線受光モジュール C言語リモコンプログラム解説マニュアル

「給与・年金の方」からの確定申告書作成編

MetaMoJi ClassRoom/ゼミナール 授業実施ガイド

アスラテック株式会社 会社案内

G-Web操作マニュアル

SMILEes 人事給与 「年間報酬平均による保険者算定」 Q&A集

Microsoft PowerPoint - 医用工学概論実習1203.ppt [互換モード]

資料3 家電エコポイント制度の政策効果等について

「シンセツくん」簡易マニュアル 低圧新増設 街灯一括申込み編

第2回 制度設計専門会合 事務局提出資料

<4D F736F F D20819C486F70658F6F93588ED297708AC7979D89E696CA837D836A B E A2E646F63>

る 第 三 者 機 関 情 報 保 護 関 係 認 証 プライバシーマーク ISO27001 ISMS TRUSTe 等 の 写 しを 同 封 のうえ 持 参 又 は 郵 送 とする 但 し 郵 送 による 場 合 は 書 留 郵 便 とし 同 日 同 時 刻 必 着 とする 提 出 場 所 は 上

御 利 用 規 約 Excel でつくる 配 光 曲 線, 直 射 水 平 面 照 度 Version 2.0 小 冊 子 を 御 利 用 頂 くにあたり 以 下 の 内 容 をよく 御 読 み 頂 き 御 同 意 の 上 御 利 用 頂 く 様 宜 しく 御 願 い 致 します 1. 著 作 物

マスタの 登 録 処 理 月 の 登 録 勤 怠 管 理 対 象 となる 処 理 月 を 設 定 します 1つのエクセルのファイル(ブック)で1ヵ 月 分 の 勤 怠 管 理 ができます 初 めてご 使 用 になる 場 合! 本 エクセルを 初 めてご 使 用 になる 場 合 は 処 理 月 を 設

遡及処理

<4D F736F F D B796EC8CA7835C F815B E646F63>

治 験 実 施 管 理 システム NMGCP 向 け Excel 形 式 プロトコール 作 成 手 順 書 V4.0.3 対 応 版 第 1 版 株 式 会 社 富 士 通 アドバンストエンジニアリング All Rights Reserved,Copyright 株 式 会 社 富 士 通 アドバン

1. 業 務 概 要 貨 物 情 報 登 録 済 の 貨 物 に 対 して システムを 介 さずに 行 われた 税 関 手 続 きについて 税 関 が 許 可 承 認 等 を 行 った 旨 を 登 録 する また システムで 行 われた 以 下 の 税 関 手 続 き( 以 下 輸 出 申 告 等

03_主要処理画面.xlsx

スライド 1

取扱説明書

1 総 合 設 計 一 定 規 模 以 上 の 敷 地 面 積 及 び 一 定 割 合 以 上 の 空 地 を 有 する 建 築 計 画 について 特 定 行 政 庁 の 許 可 により 容 積 率 斜 線 制 限 などの 制 限 を 緩 和 する 制 度 である 建 築 敷 地 の 共 同 化 や

端 末 型 払 い 出 しの 場 合 接 続 構 成 図 フレッツ グループから 払 出 されたIPアドレス /32 NTT 西 日 本 地 域 IP 網 フレッツ グループ フレッツ グループから 払 出 されたIPアドレス /

目 次 1 インストール 手 順 プログラム データファイルのインストール Microsoft Access2013Runtime SP1(32bit) 版 のインストール 基 本 操 作 ログイン メニュー...

2. ど の 様 な 経 緯 で 発 覚 し た の か ま た 遡 っ た の を 昨 年 4 月 ま で と し た の は 何 故 か 明 ら か に す る こ と 回 答 3 月 17 日 に 実 施 し た ダ イ ヤ 改 正 で 静 岡 車 両 区 の 構 内 運 転 が 静 岡 運

サービス説明書 - STP 10000TLEE-JP-10 / STP 10000TLEE-JP-11 / STP 20000TLEE-JP-11 / STP 25000TL-JP-30

TIPS - 棚 割 りを 開 始 するまで Liteを 起 動 し 企 業 情 報 の 追 加 を 行 い 棚 割 を 行 う 企 業 の 追 加 をして 下 さい 企 業 情 報 の 追 加 時 に エラーメッセージが 表 示 された 場 合 別 途 TIPS トラブルが 発 生 した 場 合

1.2. ご 利 用 環 境 推 奨 ブラウザ Internet Explorer Google Chrome(バージョン 32 時 点 で 動 作 確 認 済 み) Mozilla Firefox(バージョン 26 時 点 で 動 作 確 認 済 み) Safari 7

Transcription:

基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 公 開 しているプログラムは レーンチェンジには 対 応 していません 公 開 しているプログラムは 基 本 的 な 考 え 方 のみ 記 述 しています 実 際 にコースを 完 走 させるには 各 自 プログラムを 改 造 して 対 応 してください 本 マニュアルでプログラムの 説 明 をしている 基 板 本 基 板 の 対 象 マイコンボード 基 板 マイコンカー 製 作 キット Ver.2 ミニマイコンカー 製 作 キット Ver.2 のマイコンボード 部 分 もしくは RMC-R8C35A マイコンボード 第 1.13 版 2015.04.20 株 式 会 社 日 立 ドキュメントソリューションズ

注 意 事 項 (rev.6.0h) 著 作 権 本 マニュアルに 関 する 著 作 権 は 株 式 会 社 日 立 ドキュメントソリューションズに 帰 属 します 本 マニュアルは 著 作 権 法 および 国 際 著 作 権 条 約 により 保 護 されています 禁 止 事 項 ユーザーは 以 下 の 内 容 を 行 うことはできません 第 三 者 に 対 して 本 マニュアルを 販 売 販 売 を 目 的 とした 宣 伝 使 用 営 業 複 製 などを 行 うこと 第 三 者 に 対 して 本 マニュアルの 使 用 権 を 譲 渡 または 再 承 諾 すること 本 マニュアルの 一 部 または 全 部 を 改 変 除 去 すること 本 マニュアルを 無 許 可 で 翻 訳 すること 本 マニュアルの 内 容 を 使 用 しての 人 命 や 人 体 に 危 害 を 及 ぼす 恐 れのある 用 途 での 使 用 転 載 複 製 本 マニュアルの 転 載 複 製 については 文 書 による 株 式 会 社 日 立 ドキュメントソリューションズの 事 前 の 承 諾 が 必 要 です 責 任 の 制 限 本 マニュアルに 記 載 した 情 報 は 正 確 を 期 すため 慎 重 に 制 作 したものですが 万 一 本 マニュアルの 記 述 誤 り に 起 因 する 損 害 が 生 じた 場 合 でも 株 式 会 社 日 立 ドキュメントソリューションズはその 責 任 を 負 いません その 他 本 マニュアルに 記 載 の 情 報 は 本 マニュアル 発 行 時 点 のものであり 株 式 会 社 日 立 ドキュメントソリューション ズは 予 告 なしに 本 マニュアルに 記 載 した 情 報 または 仕 様 を 変 更 することがあります 製 作 に 当 たりまして は 最 新 の 内 容 を 確 認 いただきますようお 願 いします すべての 商 標 および 登 録 商 標 は それぞれの 所 有 者 に 帰 属 します 連 絡 先 株 式 会 社 日 立 ドキュメントソリューションズ 135-0016 東 京 都 江 東 区 東 陽 六 丁 目 3 番 2 号 イースト 21 タワー E-mail:himdx.m-carrally.dd@hitachi.com

目 次 目 次 1. 基 板 マイコンカーVer.2 の 仕 様... 3 1.1 概 要... 3 1.2 仕 様... 4 1.3 ブロック 図... 5 1.4 外 観 と 寸 法... 6 2. RMC-R8C35A マイコンボード... 7 2.1 外 観... 7 2.2 R8C/35A マイコンのポート 表... 8 2.3 R8C/35A マイコンで 使 用 する 内 蔵 周 辺 機 能... 9 3. 基 板 マイコンカーVer.2 の 回 路... 10 3.1 モータドライブ 回 路... 10 3.1.1 モータドライブ 基 板 TypeS Ver.4 との 違 い... 10 3.1.2 N チャネル FET のみを 使 う 利 点... 11 3.1.3 N チャネル FET のみを 使 うときの 問 題 点... 12 3.1.4 N チャネル FET のみを 使 うときの 解 決 策... 13 3.1.5 IR2302 の 動 作 原 理... 13 3.1.6 実 際 の 回 路... 15 3.2 ロータリエンコーダ 信 号 入 力 回 路... 17 3.3 ステアリング 角 度 検 出 用 ポテンショメータ 信 号 入 力 回 路... 17 4. ワークスペース rmc_frame_ver2... 18 4.1 ワークスペースのインストール... 18 4.2 プロジェクト... 20 4.3 プロジェクトの 構 成... 21... 22 5.1 プログラムリスト rmc_frame_ver2.c... 22 5.2 プログラムの 解 説... 33 5.2.1 シンボル 定 義... 33 5.2.2 変 数 の 定 義... 34 5.2.3 内 輪 差 値 計 算 用 の 配 列 追 加... 36 5.2.4 init 関 数 のクロックの 選 択... 37 5.2.5 ポートの 入 出 力 設 定... 38 5.2.6 A/D コンバータの 設 定... 40 5.2.7 タイマ RB の 設 定... 42 5.2.8 タイマ RC の 設 定... 44 5.2.9 タイマ RD0 の 設 定... 54 5.2.10 タイマ RD1 の 設 定... 65 5.2.11 タイマ RB の 1ms ごとの 割 り 込 みプログラム... 68 5.2.12 アナログセンサ 基 板 TypeS Ver.2 のデジタルセンサ 値 読 み 込 み... 70 5.2.13 アナログセンサ 基 板 TypeS Ver.2 の 中 心 デジタルセンサ 読 み 込 み... 71 5.2.14 アナログセンサ 基 板 TypeS Ver.2 のスタートバー 検 出 センサ 読 み 込 み... 72 5.2.15 RMC-R8C35A マイコンボード 上 のディップスイッチ 値 読 み 込 み... 73 5.2.16 基 板 マイコンカーVer.2 上 のプッシュスイッチ 値 読 み 込 み... 74 I

目 次 5.2.17 RMC-R8C35A マイコンボード 上 の LED 制 御... 75 5.2.18 後 輪 の 速 度 制 御 (ディップスイッチによる PWM 減 速 あり)... 76 5.2.19 後 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 )... 78 5.2.20 前 輪 の 速 度 制 御 (ディップスイッチによる PWM 減 速 あり)... 80 5.2.21 前 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 )... 81 5.2.22 後 モータ 停 止 動 作 (ブレーキ フリー) 設 定... 82 5.2.23 前 モータ 停 止 動 作 (ブレーキ フリー) 設 定... 83 5.2.24 ステアリングモータの PWM 設 定... 83 5.2.25 クロスラインの 検 出 処 理... 85 5.2.26 ステアリングモータ 角 度 の 取 得... 86 5.2.27 アナログセンサ 値 の 取 得... 87 5.2.28 ステアリングモータ 制 御... 89 5.2.29 内 輪 PWM 値 計 算... 92 5.2.30 main 関 数 - 初 期 化... 93 5.2.31 パターン 処 理... 94 5.2.32 パターン 0:スタート 待 ち... 94 5.2.33 パターン 1:スタートバー 開 待 ち... 95 5.2.34 パターン 11: 通 常 トレース... 96 5.2.35 パターン 21:クロスライン 検 出 処 理... 97 5.2.36 パターン 22:クロスライン 後 のトレース 直 角 検 出 処 理... 98 5.2.37 パターン 31: 右 クランク 処 理...100 5.2.38 パターン 32: 右 クランク 処 理 後 少 し 時 間 がたつまで 待 つ...101 5.2.39 パターン 41: 左 クランク 処 理...101 5.2.40 パターン 42: 左 クランク 処 理 後 少 し 時 間 がたつまで 待 つ...101 6. 4 輪 の 回 転 数 計 算... 102 6.1 センターピボット 方 式 4 輪 の 回 転 数 計 算...102 6.2 アッカーマン 方 式 4 輪 の 回 転 数 計 算...104 7. ステアリングモータの 角 度 指 定... 108 7.1 PD 制 御...108 7.2 プログラム...108 7.2.1 グローバル 変 数 の 追 加...108 7.2.2 関 数 の 追 加...109 7.2.3 割 り 込 みプログラムの 追 加...109 7.2.4 使 い 方...110 8. プログラムの 調 整 ポイント... 111 9. 参 考 文 献... 112 II

1. 基 板 マイコンカーVer.2 の 仕 様 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 1. 基 板 マイコンカーVer.2 の 仕 様 本 マニュアルでは 基 板 マイコンカー 製 作 キット Ver.2 を 基 板 マイコンカーVer.2 と 略 します モータドライブ 基 板 TypeS Ver.4 のプログラムと 互 換 にするために ステアリングモータ と サーボモータ の 用 語 が 混 在 しています 本 マニュアルでは ステアリングモータ=サーボモータ です 1.1 概 要 基 板 マイコンカー 製 作 キット Ver.2 は ミニマイコンカー 製 作 キット Ver.2(RMC-R8C35A)を 使 用 し ジャパンマイ コンカーラリーの Advanced Class に 出 場 できる 車 体 にするためのキットです 本 マニュアルは 基 板 マイコンカー 製 作 キット Ver.2 のプログラムについて 解 説 します それぞれの 基 板 機 器 の 詳 しい 説 明 は 下 表 のマニュアルを 参 照 してください 基 板 機 器 名 基 板 マイコンカー 製 作 キット Ver.2 ミニマイコンカー 製 作 キット Ver.2 のマイコンボード 部 分 もしくは RMC-R8C35A マイコンボード アナログセンサ 基 板 TypeS Ver.2 ロータリエンコーダ キット 製 作 についてのマニュアル 基 板 マイコンカー 製 作 キット Ver.2 製 作 マニュアル ミニマイコンカー 製 作 キット Ver.2 組 み 立 てマニュアル https://www2.himdx.net/mcr/ product/mini_micom_car_ver2.html アナログセンサ 基 板 TypeS Ver.2 製 作 マニュアル(R8C/38A 版 ) ロータリエンコーダ Ver.2 製 作 マニュア ル(R8C/38A 版 ) プログラムについての マニュアル 本 マニュアル ミニマイコンカー 製 作 キット Ver.2 マイコン 実 習 マニュア ル R8C/35A 版 (URL は 左 と 同 じ) モータドライブ 基 板 TypeS Ver.4 アナログセンサ 基 板 TypeS Ver.2 プログラム 解 説 マ ニュアル ロータリエンコーダ kit12_38a プログラム 解 説 マニュアル (R8C/38A 版 ) URL が 記 載 していないマニュアルは http://www.mcr.gr.jp/tech/download/main11.html からダウンロー ドできます 3

1. 基 板 マイコンカーVer.2 の 仕 様 1.2 仕 様 内 容 詳 細 全 長 全 幅 全 高 重 量 ホイールベース トレッド F/R ギア 比 電 源 マイコンボード モータドライバ 速 度 制 御 コース 検 出 センサ 510mm 170mm 70mm 960g 単 三 2 次 電 池 (2000mAh)8 本 含 んだときの 参 考 重 量 180mm 145mm/145mm 左 右 のタイヤの 中 心 駆 動 8:1(8T/64T) ステアリング 58.7:1(8T/110T 15T/64T) 単 3 型 充 電 池 8 本 マイコンカーラリー 販 売 サイト ミニマイコンカー 製 作 キット Ver.2 のマイコンボ ード 部 分 もしくは 同 RMC-R8C35A マイコンボード を 使 用 ( 別 売 り) ローサイド ハイサイド Nch MOS FET H ブリッジ 5 個 タイマ RC とタイマ RD0 の PWM により モータを 5 個 駆 動 可 能 PWM 周 期 :1kHz モータ 動 作 : 正 転 逆 転 短 絡 ブレーキ フリー IR2302 の 仕 様 で 100% 回 転 はできません 今 回 は 99%を 上 限 にしています マイコンカーラリー 販 売 サイト M-S145:ロータリエンコーダセット Ver.2(2 台 1 セット) を 使 用 ( 別 売 り) パルス 数 :72 パルス/ 回 転 マイコンカーラリー 販 売 サイト M-S199:アナログセンサ 基 板 TypeS Ver.2 を 使 用 ( 別 売 り) アナログセンサ 2 個 デジタルセンサ 5 個 スタートバー 検 出 センサ 1 個 を 搭 載 ステアリング 角 度 約 ±40 度 ( 実 測 ) ステアリング 角 度 検 出 用 ポテンショメータの 分 解 能 その 他 実 測 で A/D 値 ±127 1 度 当 たりの A/D 値 127 / 40 = 約 3.18 タクトスイッチ 4 個 マイコンボード 上 の SW2 はリセットスイッチです 4

1. 基 板 マイコンカーVer.2 の 仕 様 1.3 ブロック 図 基 板 マイコンカーVer.2 のブロック 図 を 下 記 に 示 します 基 板 マイコンカーVer.2 リアユニット 部 分 の 回 路 アナログセンサ 基 板 TypeS Ver.2 デジタルセンサ 左 端 デジタルセンサ 左 中 デジタルセンサ 右 中 デジタルセンサ 右 端 アナログセンサ 左 P2_7 P2_6 P2_5 P0_7 RMC-R8C35A マイコンボード P0_6 AN1 R8C/35A マイコン P6_5 PWM P3_4 正 転 / 逆 転 P3_5 ブレーキ/フリー P6_6 PWM P3_6 正 転 / 逆 転 P3_7 ブレーキ/フリー 正 転 / 逆 転 切 り 替 え 正 転 / 逆 転 切 り 替 え H ブリッジ モータドライブ 回 路 ( 左 前 モータ) H ブリッジ モータドライブ 回 路 ( 左 後 モータ) CN34 M CN35 M アナログセンサ 右 デジタル 中 心 スタートバー ロータリエンコーダ Ver.2 P0_5 AN2 P0_4 P0_3 P2_0 P6_7 PWM 正 転 / 逆 転 P6_0 P6_1 ブレーキ/フリー P2_2 PWM P3_0 正 転 / 逆 転 P3_1 ブレーキ/フリー 正 転 / 逆 転 切 り 替 え 正 転 / 逆 転 切 り 替 え H ブリッジ モータドライブ 回 路 (サーボモータ) H ブリッジ モータドライブ 回 路 ( 右 後 モータ) CN36 M CN37 M 基 板 マイコンカーVer.2 ステアリングモータユニットの 回 路 角 度 検 出 用 ポテンショメータ P0_2 AN5 P1_5 RxD0 P1_4 TxD0 P2_1 PWM P3_2 正 転 / 逆 転 P3_3 ブレーキ/フリー P0_0 P3_3 P6_3 P2_3 正 転 / 逆 転 切 り 替 え タクトスイッチ SW1 タクトスイッチ SW2 タクトスイッチ SW3 タクトスイッチ SW4 H ブリッジ モータドライブ 回 路 ( 右 前 モータ) CN38 M USB シリアル 変 換 IC P4_3 P4_4 P4_5 P5_7 3 2 1 0 ディップスイッチ P1_0 P1_1 P1_2 P1_3 LED0 LED1 LED2 LED3 USB コネクタ 5

1. 基 板 マイコンカーVer.2 の 仕 様 1.4 外 観 と 寸 法 基 板 マイコンカーVer.2 の 外 観 と 寸 法 を 下 写 真 に 示 します アナログセンサ 基 板 TypeS Ver.2 ステアリング 用 ギヤ 110T RMC-R8C35A マイコンボード ロータリエンコーダ Ver.2 145 290 110T のギヤを 外 したところ 180 ステアリング 用 ギヤ 8T 2 ステアリング 用 ギヤ 64T ステアリング 用 ギヤ 15T ステアリング 用 モータ 2 個 ステアリング 角 度 検 出 用 ポテンショメータ シャフトといっしょ に 中 心 部 分 ( 少 し 薄 い 黒 色 部 分 )が 可 動 することによ り 抵 抗 値 が 変 わ ります 正 転 逆 転 切 り 替 え 回 路 74HC125 126 ゲートドライバ IC IR2302 N チャネル MOS FET 2SK2869 6

2. RMC-R8C35A マイコンボード 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 2. RMC-R8C35A マイコンボード 2.1 外 観 今 回 の RMC-R8C35A マイコンボードは 基 板 マイコンカーVer.2 用 として 部 品 の 付 け 替 えをしています 付 け 替 えの 内 容 は 基 板 マイコンカー 製 作 キット Ver.2 製 作 マニュアル を 参 照 してください 書 き 込 みスイッチ USB コネクタ 側 ( 上 側 )で 書 き 込 み ディップスイッチ 側 ( 下 側 )で 実 行 J4 USB コネクタ(B タイプ) SW2 マイコンのリセットスイッチ J6 (P3) J2 (P6) J7 (P2) J3 (P0) 1 0 D13 電 源 が 供 給 され ると 点 灯 します D11 USB ケーブルを 接 続 すると 点 灯 します D9 (P1_3) D8 (P1_2) D6 (P1_1) D5 (P1_0) SW4( 左 から P5_7 P4_5 P4_4 P4_3) 上 ( 内 側 )が"1" 下 ( 外 側 )が"0" D11 の LED は USB ケーブルを 接 続 すると 点 灯 しますが 基 板 マイコンカーVer.2 や RMC-R8C35A マイコンボ ードには 電 源 は 供 給 されません 書 き 込 みや Tera Term で 通 信 をするときは 基 板 マイコンカーVer.2 の 電 源 を 入 れてください(D13 の LED を 点 灯 させてください) 7

2. RMC-R8C35A マイコンボード 2.2 R8C/35A マイコンのポート 表 コネ クタ J3 J7 J6 J2 Po pin rt bit 端 子 名 接 続 先 2 P0 7 P0_7/AN0/DA1(/TRCIOC) アナログセンサー 基 板 TypeS Ver.2 デジタルセンサ 右 端 3 P0 6 P0_6/AN1/DA0(/TRCIOD) アナログセンサー 基 板 TypeS Ver.2 アナログセンサ 左 4 P0 5 P0_5/AN2(/TRCIOB) アナログセンサー 基 板 TypeS Ver.2 アナログセンサ 右 5 P0 4 P0_4/AN3/TREO(/TRCIOB) アナログセンサー 基 板 TypeS Ver.2 デジタルセンサ 中 心 6 P0 3 P0_3/AN4(/CLK1/TRCIOB) アナログセンサー 基 板 TypeS Ver.2 スタートバー 検 出 センサ 7 P0 2 P0_2/AN5(/RXD1/TRCIOA/TRCTRG) ポテンショメータ(ステアリング 角 度 検 出 用 ) 8 P0 1 P0_1/AN6(/TXD1/TRCIOA/TRCTRG) 9 P0 0 P0_0/AN7(/TRCIOA/TRCTRG) SW2 P1 7 P1_7/IVCMP1/INT1(/TRAIO) (マイコンボードからは 出 力 されていない 端 子 のため 使 用 できません) P1 6 P1_6/LVCOUT2/IVREF1(/CLK0) (マイコンボードからは 出 力 されていない 端 子 のため 使 用 できません) P1 5 P1_5(/INT1/RXD0/TRAIO) RxD0 P1 4 P1_4(/TXD0/TRCCLK) TxD0 P1 3 P1_3/AN11/LVCOUT1/Kl3/TRBO(/TRCIOC) LED3 P1 2 P1_2/AN10/LVREF/Kl2(/TRCIOB) LED2 P1 1 P1_1/AN9/LVCMP2/KI1(/TRCIOA/TRCTRG) LED1 P1 0 P1_0/AN8/LVCMP1/KI0(/TRCIOD) LED0 2 P2 7 P2_7(/TRDIOD1) アナログセンサー 基 板 TypeS Ver.2 デジタルセンサ 左 端 3 P2 6 P2_6(/TRDIOC1) アナログセンサー 基 板 TypeS Ver.2 デジタルセンサ 左 中 4 P2 5 P2_5(/TRDIOB1) アナログセンサー 基 板 TypeS Ver.2 デジタルセンサ 右 中 5 P2 4 P2_4(/TRDIOA1) 6 P2 3 P2_3(/TRDIOD0) SW4 7 P2 2 P2_2(/TRCIOD/TRDIOB0) 右 後 モータPWM 8 P2 1 P2_1(/TRCIOC/TRDIOC0) 右 前 モータPWM 9 P2 0 P2_0(/INT1/TRCIOB/TRDIOA0/TRDCLK) ロータリエンコーダパルスカウント 2 P3 7 P3_7/SDA/SSO/TRAO(/RXD2/SCL2/TXD2/SDA2) 左 後 モータ 0:フリー 1:ブレーキ 3 P3 6 P3_6(/INT1) 左 後 モータ 方 向 1: 正 転 0: 逆 転 4 P3 5 P3_5/SCL/SSCK(/CLK2/TRCIOD) 左 前 モータ 0:フリー 1:ブレーキ 5 P3 4 P3_4/IVREF3/SSI(/RXD2/SCL2/TXD2/SDA2/TRCIOC) 左 前 モータ 方 向 1: 正 転 0: 逆 転 6 P3 3 P3_3/IVCMP3/INT3/SCS(/CTS2/RTS2/TRCCLK) 右 前 モータ 0:フリー 1:ブレーキ 7 P3 2 P3_2(/INT1/INT2/TRAIO) 右 前 モータ 方 向 1: 正 転 0: 逆 転 8 P3 1 P3_1(/TRBO) 右 後 モータ 0:フリー 1:ブレーキ 9 P3 0 P3_0(/TRAO) 右 後 モータ 方 向 1: 正 転 0: 逆 転 P4 7 P4_7/XOUT クリスタル(XOUT) (20MHz) P4 6 P4_6/XIN クリスタル(XIN) (20MHz) P4 5 P4_5/ADTRG/INT0(/RXD2/SCL2) マイコンボード 上 のディップスイッチ2(SW4) P4 4 P4_4(/XCOUT) マイコンボード 上 のディップスイッチ1(SW4) P4 3 P4_3(/XCIN) マイコンボード 上 のディップスイッチ0(SW4) P4 2 P4_2/VREF Vccに 接 続 (A/D 変 換 の 基 準 電 圧 ) P5 7 P5_7 マイコンボード 上 のディップスイッチ3(SW4) P5 6 P5_6(/TRAO) (マイコンボードからは 出 力 されていない 端 子 のため 使 用 できません) 2 P6 7 P6_7(/INT3/TRCIOD) ステアリングモータPWM 3 P6 6 P6_6/INT2(/TXD2/SDA2/TRCIOC) 左 後 モータPWM 4 P6 5 P6_5/INT4(/CLK1/CLK2/TRCIOB) 左 前 モータPWM 5 P6 4 P6_4(/RXD1) SW1 6 P6 3 P6_3(/TXD1) SW3 7 P6 2 P6_2(/CLK1) 8 P6 1 P6_1 ステアリングモータ 0:フリー 1:ブレーキ 9 P6 0 P6_0(/TREO) ステアリングモータ 方 向 1: 正 転 0: 逆 転 コネクタは RMC-R8C35A マイコンボードの 番 号 です 8

2.3 R8C/35A マイコンで 使 用 する 内 蔵 周 辺 機 能 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 2. RMC-R8C35A マイコンボード 機 能 A/D コンバータ 詳 細 A/D コンバータを 繰 り 返 し 掃 引 モードで 使 います 繰 り 返 し 掃 引 モードは 複 数 の 端 子 を 繰 り 返 し A/D 変 換 するモードです 今 回 下 記 の 3 つの 端 子 の 電 圧 を 読 み 込 みます 今 回 のプログラムでは A/D 変 換 を P0_0~P0_7 の 8 端 子 分 実 行 していますが A/D 変 換 値 を 読 み 込 んでいるのが AD1 AD2 AD5 の 3 つの 端 子 です P0_6(AD1) アナログセンサ 左 の 電 圧 を 読 み 込 みます P0_5(AD2) P0_2(AD5) アナログセンサ 右 の 電 圧 を 読 み 込 みます ステアリング 角 度 検 出 用 ポテンショメータの 電 圧 を 読 み 込 みます タイマ RA 未 使 用 です タイマ RB タイマ RC タイマ RD0 タイマ RD1 タイマ RE インターバルタイマとして 使 用 して 1ms ごとに 割 り 込 みを 発 生 させます PWM モードとして 使 用 します タイマ RC は PWM 信 号 を 3 本 出 力 することができます 今 回 タイマ RC でスピード 制 御 しているモータを 下 記 に 示 します 1 左 後 モータ 2 左 前 モータ 3ステアリングモータ PWM モードとして 使 用 します タイマ RD0 は PWM 信 号 を 3 本 出 力 することができます 今 回 タイマ RD0 でスピード 制 御 しているモータを 下 記 に 示 します 1 右 後 モータ 2 右 前 モータ ロータリエンコーダ Ver.2 のパルス 入 力 として 使 用 します 未 使 用 です 9

3. 基 板 マイコンカーVer.2 の 回 路 3. 基 板 マイコンカーVer.2 の 回 路 3.1 モータドライブ 回 路 3.1.1 モータドライブ 基 板 TypeS Ver.4 との 違 い モータドライブ 基 板 TypeS Ver.4 と 基 板 マイコンカーVer.2 の 左 後 モータを 駆 動 する 回 路 図 を 下 記 に 示 します モータドライブ 基 板 TypeS Ver.4 の 回 路 の 動 作 原 理 は モータドライブ 基 板 TypeS Ver.4 アナログセンサ 基 板 TypeS Ver.2 プログラム 解 説 マニュアル(R8C/38A 版 ) を 参 照 してください マニュアルは ダウンロードページ(http://mcr.gr.jp/tech/download/main01.html) R8C/38A マイコン(RY_R8C38 ボード)に 関 する 資 料 からダウンロードできます 10

それぞれの 回 路 の 特 徴 を 下 記 に 示 します(ゴシック 体 太 字 が 良 い 方 ) 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 3. 基 板 マイコンカーVer.2 の 回 路 内 容 モータドライブ 基 板 TypeS Ver.4 基 板 マイコンカーVer.2 FET 駆 動 回 路 モータ 駆 動 FET ロジック IC(OR 回 路 AND 回 路 シュミット トリガの NOT 回 路 )と 遅 延 回 路 FET(RQK0302)による 回 路 P チャネル FET(2SJ530)を 2 個 使 用 N チャネル FET(2SK2869)を 2 個 使 用 ロジック IC(74HC125 126)とダイオード コ ンデンサ(10μF) FET を 駆 動 する 専 用 IC(IR2302)による 回 路 N チャネル FET(2SK2869)を 4 個 使 用 部 品 点 数 多 い 少 ない( 専 用 IC 内 に 機 能 が 含 まれている) 部 品 が 壊 れたとき フリー 動 作 汎 用 の 部 品 を 使 うので 故 障 したときに 同 等 の 部 品 が 手 元 にある 場 合 がある また はすぐに 購 入 できる 動 作 <->ブレーキ か 動 作 <->フリー を 選 択 可 能 FET を 駆 動 する 専 用 IC(IR2302)を 使 うの で 手 に 入 りづらい 動 作 <->ブレーキ か フリー(のみ) を 選 択 可 能 今 回 の 回 路 の 最 大 の 特 徴 は N チャネル FET のみを 使 用 して モータを 駆 動 していることです 3.1.2 N チャネル FET のみを 使 う 利 点 FET は P チャネル 型 と N チャネル 型 があります これらをペアで 使 いたいとき コンプリメンタリ ペア の FET を 使 います コンプリメンタリ( 相 補 的 ) ペア とは それぞれで 極 性 が 反 転 している 他 は 特 性 の 似 た P チャネル 型 と N チャネル 型 の FET の 組 のことです 出 典 :ウィキペディア http://ja.wikipedia.org/wiki/バイポーラトランジスタ モータドライブ 基 板 TypeS Ver.4 で 使 用 している 2SJ530 と 2SK2869 はコンプリメンタリです コンプリメンタリかどう かは 部 品 メーカーのホームページやデータシートなどに 記 載 されています 基 板 マイコンカーVer.2 は N チャネル FET だけでモータを 駆 動 します なぜでしょうか? 2SJ530 と 2SK2869 の データの 一 部 を 下 記 に 示 します(ゴシック 体 太 字 の 方 が 特 性 が 良 い) 内 容 2SJ530(P チャネル) 2SK2869(N チャネル) ドレイン ソースオン 抵 抗 条 件 :I D =10V V GS =10V 最 大 値 :0.10Ω 最 大 値 :0.045Ω ドレイン 電 流 I D -15A 20A ターン オン 遅 延 時 間 + 上 昇 時 間 FET が OFF の 状 態 から ON になるまでの 時 間 ターン オフ 遅 延 時 間 + 下 降 時 間 FET が ON の 状 態 から OFF になるまでの 時 間 値 段 標 準 値 :87ns 標 準 値 :200ns コンプリメンタリの 場 合 一 般 的 に P チャネルが 高 い 標 準 値 :120ns 標 準 値 :225ns コンプリメンタリの 場 合 一 般 的 に N チャネルが 安 い N チャネル 型 FET の 2SK2869 のみで 駆 動 した 方 が ON 抵 抗 が 低 く 多 くの 電 流 を 流 すことができます また 部 品 点 数 を 少 なくすることもできます 2 種 類 2 個 ずつ 揃 えるより 1 種 類 4 個 を 揃 えた 方 が 効 率 的 で 数 も 多 くな るので 単 価 が 安 くなるかもしれません しかし モータドライブ 基 板 TypeS Ver.4 ではそうしていません なぜでしょうか 11

3. 基 板 マイコンカーVer.2 の 回 路 3.1.3 N チャネル FET のみを 使 うときの 問 題 点 まず モータドライブ 基 板 TypeS Ver.4 の P チャネル FET(2SJ530) N チャネル FET(2SK2869)を 使 った 回 路 の 動 作 原 理 を 説 明 します(VBAT=10V として 説 明 します) FET はソース(S)を 0V としたとき ゲ ート(G)に 加 える 電 圧 によって ソー ス(S)-ドレイン(D) 間 が ON するか OFF するか 決 まります 0V を 出 力 したいとき それぞれの FET のゲート(G)には 下 記 の 電 圧 を 入 力 します P チャネル FET(2SJ530)のゲート (G)に 10V を 入 力 すると V GS =0V となりソース(S)-ドレイン (D) 間 は OFF になります N チャネル FET(2SK2869)のゲー ト(G)に 10V を 入 力 すると V GS =10V となりソース(S)-ドレイ ン(D) 間 は ON になります 10V を 出 力 したいとき それぞれの FET のゲート(G)には 下 記 の 電 圧 を 入 力 します P チャネル FET(2SJ530)のゲート (G)に 0V を 入 力 すると V GS =-10V となりソース(S)-ドレイ ン(D) 間 は ON になります N チャネル FET(2SK2869)のゲー ト(G)に 0V を 入 力 すると V GS =0V となりソース(S)-ドレイン (D) 間 は OFF になります 次 に 基 板 マイコンカーVer.2 の N チャネル FET(2SK2869)を 使 った 回 路 の 動 作 原 理 を 説 明 します FET はソース(S)を 0V としたとき ゲ ート(G)に 加 える 電 圧 によって ソー ス(S)-ドレイン(D) 間 が ON するか OFF するか 決 まります 0V を 出 力 したいとき それぞれの FET のゲート(G)には 下 記 の 電 圧 を 入 力 します 上 側 の N チャネル FET(2SK286 9)のゲート(G)に 0V を 入 力 すると V GS =0V となりソース(S)-ドレイン (D) 間 は OFF になります(ただし 右 欄 の 説 明 を 参 照 ) 下 側 の N チャネル FET(2SK286 9)のゲート(G)に 10V を 入 力 する と V GS =10V となりソース(S)-ドレ イン(D) 間 は ON になります このように N チャネル FET(2SK2869)だけを 使 った 回 路 では うまく 動 作 しません 10V を 出 力 したいとき それぞれの FET のゲート(G)には 下 記 の 電 圧 を 入 力 します 上 側 の N チャネル FET のソース (S)には 電 圧 が 入 力 されていない ため ゲート(G)に 電 圧 を 加 えて も V GS に 電 圧 は 加 えられません よって この 回 路 では 動 作 しませ ん 左 図 の 0V を 出 力 したいとき も 下 側 FET が ON になる 前 は 同 様 なので 0V 出 力 もこの 回 路 では 動 作 しません 12

3. 基 板 マイコンカーVer.2 の 回 路 3.1.4 N チャネル FET のみを 使 うときの 解 決 策 そこで 上 側 FET を 動 作 させる 専 用 の 別 電 源 を 用 意 します 下 記 に 上 側 FET 専 用 の 10V 電 源 を 用 意 した 様 子 を 示 します 当 然 別 電 源 を 用 意 するのは 大 変 ですし マイコンカーのルールにも 違 反 しています 別 電 源 を 用 意 せずに 1 つの 電 源 のみで 実 現 するのが IR2302 という FET を 駆 動 する 専 用 IC です 3.1.5 IR2302 の 動 作 原 理 IR2302 の 動 作 原 理 を 下 記 に 示 します 上 側 FET のゲートに 加 える 電 圧 は IC 内 部 の VB VS 電 圧 変 換 回 路 で 5V の 信 号 (IN や/SD 信 号 )を VB VS の 電 圧 に 変 換 します VCC 内 部 の 電 源 回 路 と 下 側 FET の 電 源 です 今 回 の IR2302 は 25V まで 加 えることができます LO 下 側 FET のゲート(G)に 接 続 します GND 内 部 の 電 源 回 路 と 下 側 FET の GND です VB 上 側 FET の 電 源 です HO 上 側 FET のゲート(G)に 接 続 します VS 下 側 FET の GND です IN "1":HO=High LO=Low "0":HO=Low LO=High 3V 以 上 で"1"とみなします /SD "1":IN 信 号 に 従 って 動 作 "0":フリー 動 作 (HO=Low LO=Low) 3V 以 上 で"1"とみなします 13

3. 基 板 マイコンカーVer.2 の 回 路 IN="0"にしたときの 様 子 を 下 記 に 示 します 下 側 FET が ON になり モータ 出 力 は 0V になります このとき VS=0V VB=VBAT の 電 圧 となり 10μF のコン デンサが 充 電 されます( 下 記 ) "0" "0" 10V 緑 色 波 線 の 経 路 で コンデンサが 充 電 される "1" 0V OFF "1" 0V ON モータ 出 力 =0V 10V IN="1"にしたときの 様 子 を 下 記 に 示 します GND を 0V とすると VS は 10V VB は 20V になります このとき ダイオードのアノード 側 (VBAT)は 10V なので ダイオードは OFF になります GND を 0V とすると VB は 20V ですが VS=0V としたとき VB は 10V になります 上 側 FET のゲートには 10V が 入 力 され ON になり モータへの 出 力 は 10V になります "1" GND を0V とすると 20V VS を0V とすると 10V "1" OFF コンデンサが 放 電 す る 電 圧 (10V)がゲート に 加 わる ON "1" 10V "0" 10V OFF モータ 出 力 =10V 0V 100% 出 力 について 常 に IN を"1"にすると(PWM=100%にすると) コンデンサを 充 電 する 時 間 がありません コンデンサの 電 圧 が 落 ち ると 上 側 FET が OFF してしまい モータ 出 力 が 0V になってしまいます よって PWM を 100%にすることはでき ません 今 回 のプログラムでは 99% 以 上 は 99%になるよう 作 られています 1%は OFF になるので このときコンデンサが 充 電 されます 14

3. 基 板 マイコンカーVer.2 の 回 路 3.1.6 実 際 の 回 路 実 際 の 回 路 では 74HC125 と 74HC126 を 使 用 しています この IC の 動 作 を 下 記 に 示 します 74HC125 の 回 路 図 入 力 と 出 力 の 関 係 IN /OE OUT IN OUT 0 0 0 (/OE が"0"のとき OUT=IN) /OE 1 0 0or1 1 1 (/OE が"0"のとき OUT=IN) ハイインピーダンス (/OE が"1"のとき IN に 関 わらず 無 接 続 状 態 ) 74HC126 の 回 路 図 入 力 と 出 力 の 関 係 IN OE OUT IN OE OUT 0 1 1 1 0or1 0 0 (/OE が"1"のとき OUT=IN) 1 (/OE が"1"のとき OUT=IN) ハイインピーダンス (OE が"0"のとき IN に 関 わらず 無 接 続 状 態 ) 74HC125 と 74HC126 の 違 いは OE の 論 理 です 74HC125 は /OE が"0"のときに OUT=IN の 動 作 74HC126 は OE が"1"のときに OUT=IN の 動 作 になります 15

3. 基 板 マイコンカーVer.2 の 回 路 左 後 モータを 駆 動 する 実 際 の 回 路 を 下 記 に 示 します IR2302 は 2 組 で 1 個 のモータを 制 御 します U6 IN TR6 G PWM 方 向 TR5 G フリー U7 IN TR8 G TR7 G IN 方 向 フリー U6 IN U7 IN TR6 G TR5 G TR8 G TR7 G モータ 動 作 0 (0V) 0 1 (5V) (0V) 0 (0V) 1 1 (5V) x (5V) x 1 (5V) 0 (0V) 0 (0V) 1 (5V) 0 (0V) 0 (0V) x = "0"でも"1"でも 動 作 に 関 係 ない x 0 (0V) 0 (0V) 0 (0V) 1 (5V) x 0V (OFF) 10V (ON) 0V (OFF) 0V (OFF) 0V (OFF) 10V (ON) 0V (OFF) 10V (ON) 10V (ON) 0V (OFF) 0V (OFF) 0V (OFF) 0V (OFF) 10V (ON) 0V (OFF) 10V (ON) 10V (ON) 10V (ON) 0V (OFF) 0V (OFF) ブレーキ 両 端 子 GND 正 転 上 側 =10V 下 側 =0V ブレーキ 両 端 子 GND 逆 転 上 側 =0V 下 側 =10V フリー 無 接 続 状 態 例 えば 方 向 が"0"のとき U23 の 出 力 は 無 接 続 状 態 になりますが U7 の IN 端 子 にはプルダウン 抵 抗 が 内 蔵 さ れているため "0"になります よって U7 の 出 力 は 常 に 0V になります このときのモータの 動 作 は IN 端 子 が"0" なら U6 は 0V(モータはブレーキ 状 態 ) "1"なら 10V(モータは 正 転 )となります フリー 端 子 を"0"にすると U6 U7 は FET への 出 力 電 圧 を 常 に 0V にしてモータを 無 接 続 状 態 要 はフリー 動 作 にします 16

3. 基 板 マイコンカーVer.2 の 回 路 3.2 ロータリエンコーダ 信 号 入 力 回 路 基 板 マイコンカーVer.2 の CN24 は ロータリエンコーダの 信 号 を 入 力 するコネクタです 基 板 マイコンカーVer.2 のロータリエンコーダ 回 路 プログラムの 特 徴 を 下 記 に 示 します ロータリエンコーダの 接 続 は CN24 ロータリエンコーダのパルスを タイマ RD1 の 外 部 クロック 入 力 端 子 (P2_0)から 入 力 し 立 ち 上 がり 立 ち 下 がりの 回 数 をカウント ロータリエンコーダ Ver.2 について 詳 しくは ロータリエンコーダ kit12_38a プログラム 解 説 マニュアル(R8C/38A 版 ) を 参 照 してください 1:+5V 2: 信 号 入 力 3:GND ロータリエンコーダ Ver.2 3.3 ステアリング 角 度 検 出 用 ポテンショメータ 信 号 入 力 回 路 基 板 マイコンカーVer.2 には ステアリング 角 度 検 出 用 のポテンショメータの 入 力 コネクタが 実 装 されています 基 板 マイコンカーVer.2 の 回 路 プログラムの 特 徴 を 下 記 に 示 します 3 ピン( 抵 抗 の 両 端 と 可 変 部 分 がある)のポテンショメータ(ボリューム)を 取 り 付 け 可 能 入 力 された 電 圧 0~5V を R8C/35A マイコンの P0_2 端 子 で A/D 変 換 して 0~1023(2 10-1)に 変 換 ポテンショメータ 17

4. ワークスペース rmc_frame_ver2 4. ワークスペース rmc_frame_ver2 4.1 ワークスペースのインストール 1 マイコンカーラリーホー ムページ http://www.mcr.gr.jp /index2.html にアクセスします 技 術 情 報 ダウンロー ド をクリックします R8C/35A マイコンに 関 する 資 料 をクリックしま す 2 rmc_frame_ver2.zip を ダウンロード 解 凍 しま す 3 18

4. ワークスペース rmc_frame_ver2 圧 縮 解 除 をクリックします 4 フォルダは 変 更 できません 変 更 した 場 合 は ルネサス 統 合 開 発 環 境 の 設 定 を 変 更 する 場 合 がでてきます 5 解 凍 が 終 わったら 自 動 的 に C ドライブ Workspace フォルダが 開 かれます 今 回 使 用 するのは rmc_frame_ver2 で す 閉 じるをクリックして 終 了 です 6 7 C ドライブ Workspace rmc_frame_ver2 rmc_frame_ver2.hws をダブルクリックすると ルネサス 統 合 開 発 環 境 が 立 ち 上 がります rmc_frame_ver2.hws 19

4. ワークスペース rmc_frame_ver2 4.2 プロジェクト 右 クリックして アクティブプロ ジェクトに 設 定 を 選 択 します ワークスペース rmc_frame_ver2 には 2 つのプロジェクトが 登 録 されています プロジェクト 名 rmc_frame_ver2 rmc_frame_ver2_ test 内 容 RMC-R8C35A マイコンボード アナログセンサ 基 板 TypeS Ver.2 ロータリエンコーダ Ver.2 を 使 った 基 板 マイコンカーVer.2 制 御 プログラムです 本 プログラムは 基 本 的 な 考 え 方 のみ 記 述 しています 実 際 にコースを 完 走 させるには 各 自 プログラムを 改 造 して 対 応 してください 今 回 は このプロジェクトを 使 います rmc_frame_ver2_test プロジェクトをアクティブ( 操 作 対 象 )にしてください 基 板 マイコンカーVer.2 の 動 作 テスト 用 プログラムです 20

4. ワークスペース rmc_frame_ver2 4.3 プロジェクトの 構 成 ファイル 名 1 rmc_frame_ver2.c 2 startup.c 3 sfr_r835a.h 内 容 実 際 に 制 御 するプログラムが 書 かれています R8C/35A の 内 蔵 周 辺 機 能 (SFR)の 初 期 化 も 行 います ファイルの 位 置 C:\Workspace\rmc_frame_ver2\rmc_frame_ver2\rmc_frame_ver2.c 固 定 割 り 込 みベクタアドレスの 設 定 スタートアッププログラム RAM の 初 期 化 ( 初 期 値 のないグローバル 変 数 初 期 値 のあるグローバル 変 数 の 設 定 )などを 行 います ファイルの 位 置 C:\Workspace\rmc_frame_ver2\rmc_frame_ver2\startup.c R8C/35A マイコンの 内 蔵 周 辺 機 能 を 制 御 するためのレジスタ(Special Function Registers)を 定 義 したファイルです ファイルの 位 置 C:\Workspace\common_r8c35a\sfr_r838a.h 21

5.1 プログラムリスト rmc_frame_ver2.c 1 : /****************************************************************************/ 2 : /* 対 象 マイコン R8C/35A or R8C/35C */ 3 : /* ファイル 内 容 ミニマイコンカーVer.2のマイコンボード(RMC-R8C35A)を 使 った */ 4 : /* 基 板 マイコンカーVer.2 制 御 プログラム */ 5 : /* バージョン Ver.1.00 */ 6 : /* Date 2014.06.23 */ 7 : /* Copyright ルネサスマイコンカーラリー 事 務 局 */ 8 : /* 株 式 会 社 日 立 ドキュメントソリューションズ */ 9 : /****************************************************************************/ 10 : 11 : /* 12 : 本 プログラムは 13 : 基 板 マイコンカーVer.2 14 : アナログセンサ 基 板 TypeS Ver.2 15 : を 使 用 した 基 板 マイコンカーVer.2を 動 作 させるプログラムです 16 : */ 17 : 18 : /*======================================*/ 19 : /* インクルード */ 20 : /*======================================*/ 21 : #include <stdio.h> 22 : #include "sfr_r835a.h" /* R8C/35A SFRの 定 義 ファイル */ 23 : 24 : /*======================================*/ 25 : /* シンボル 定 義 */ 26 : /*======================================*/ 27 : /* 定 数 設 定 */ 28 : #define TRC_MOTOR_CYCLE 20000 /* 左 前, 右 前 モータPWMの 周 期 */ 29 : /* 50[ns] * 20000 = 1.00[ms] */ 30 : #define TRD_MOTOR_CYCLE 20000 /* 左 後, 右 後,サーホ モータPWMの 周 期 */ 31 : /* 50[ns] * 20000 = 1.00[ms] */ 32 : #define FREE 1 /* モータモード フリー */ 33 : #define BRAKE 0 /* モータモード ブレーキ */ 34 : 35 : /*======================================*/ 36 : /* プロトタイプ 宣 言 */ 37 : /*======================================*/ 38 : void init( void ); 39 : unsigned char sensor_inp( void ); 40 : unsigned char center_inp( void ); 41 : unsigned char startbar_get( void ); 42 : unsigned char dipsw_get( void ); 43 : unsigned char pushsw_get( void ); 44 : void led_out( unsigned char led ); 45 : void motor_r( int accele_l, int accele_r ); 46 : void motor2_r( int accele_l, int accele_r ); 47 : void motor_f( int accele_l, int accele_r ); 48 : void motor2_f( int accele_l, int accele_r ); 49 : void motor_mode_r( int mode_l, int mode_r ); 50 : void motor_mode_f( int mode_l, int mode_r ); 51 : void servopwmout( int pwm ); 52 : int check_crossline( void ); 53 : int getservoangle( void ); 54 : int getanalogsensor( void ); 55 : void servocontrol( void ); 56 : int diff( int pwm ); 57 : 58 : /*======================================*/ 59 : /* グローバル 変 数 の 宣 言 */ 60 : /*======================================*/ 61 : int pattern; /* マイコンカー 動 作 パターン */ 62 : int crank_mode; /* 1:クランクモード 0: 通 常 */ 63 : unsigned long cnt1; /* タイマ 用 */ 64 : 65 : /* エンコーダ 関 連 */ 66 : int itimer10; /* 10msカウント 用 */ 67 : long lencodertotal; /* 積 算 値 保 存 用 */ 68 : int iencoder; /* 10ms 毎 の 最 新 値 */ 69 : unsigned int uencoderbuff; /* 計 算 用 割 り 込 み 内 で 使 用 */ 70 : 71 : /* サーボ 関 連 */ 72 : int isensorbefore; /* 前 回 のセンサ 値 保 存 */ 73 : int iservopwm; /* サーボPWM 値 */ 74 : int iangle0; /* 中 心 時 のA/D 値 保 存 */ 75 : 76 : /* センサ 関 連 */ 77 : int isensorpattern; /* センサ 状 態 保 持 用 */ 78 : 22

79 : /* TRCレジスタのバッファ */ 80 : unsigned int trcgrb_buff; /* TRCGRBのバッファ */ 81 : unsigned int trcgrc_buff; /* TRCGRCのバッファ */ 82 : unsigned int trcgrd_buff; /* TRCGRDのバッファ */ 83 : 84 : /* TRD0レジスタのバッファ */ 85 : unsigned int trdgrb0_buff; /* TRDGRB0のバッファ */ 86 : unsigned int trdgrc0_buff; /* TRDGRC0のバッファ */ 87 : 88 : /* 内 輪 差 値 計 算 用 各 マイコンカーに 合 わせて 再 計 算 して 下 さい */ 89 : const revolution_difference[] = { /* 角 度 から 内 輪 外 輪 回 転 差 計 算 */ 90 : 100, 99, 97, 96, 95, 91 : 93, 92, 91, 89, 88, 92 : 87, 85, 84, 83, 82, 93 : 81, 79, 78, 77, 76, 94 : 74, 73, 72, 71, 70, 95 : 68, 67, 66, 65, 64, 96 : 62, 61, 60, 59, 57, 97 : 56, 55, 53, 52, 51, 98 : 50, 48, 47, 45, 44, 99 : 43 }; 100 : 101 : /************************************************************************/ 102 : /* メインプログラム */ 103 : /************************************************************************/ 104 : void main( void ) 105 : { 106 : int i; 107 : unsigned char b; 108 : 109 : /* マイコン 機 能 の 初 期 化 */ 110 : init(); /* 初 期 化 */ 111 : asm(" fset I "); /* 全 体 の 割 り 込 み 許 可 */ 112 : 113 : /* マイコンカーの 状 態 初 期 化 */ 114 : motor_mode_f( BRAKE, BRAKE ); /* 基 板 マイコンカーのFREEは */ 115 : motor_mode_r( BRAKE, BRAKE ); /* PWM 値 に 関 係 なく 必 ずフリーになる */ 116 : motor_f( 0, 0 ); 117 : motor_r( 0, 0 ); 118 : servopwmout( 0 ); 119 : 120 : while( 1 ) { 121 : 122 : switch( pattern ) { 123 : case 0: 124 : /* プッシュスイッチ(SW4) 押 下 待 ち */ 125 : servopwmout( 0 ); 126 : if( pushsw_get() == 0x01 ) { 127 : cnt1 = 0; 128 : pattern = 1; 129 : break; 130 : } 131 : i = (cnt1/200) % 2 + 1; 132 : if( startbar_get() ) { 133 : i += ((cnt1/100 ) % 2 + 1) << 2; 134 : } 135 : led_out( i ); /* LED 点 滅 処 理 */ 136 : break; 137 : 138 : case 1: 139 : /* スタートバー 開 待 ち */ 140 : servopwmout( iservopwm / 2 ); 141 : if(!startbar_get() ) { 142 : iangle0 = getservoangle(); /* 0 度 の 位 置 記 憶 */ 143 : led_out( 0x0 ); 144 : cnt1 = 0; 145 : pattern = 11; 146 : break; 147 : } 148 : led_out( 1 << (cnt1/50) % 4 ); 149 : break; 150 : 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 23

151 : case 11: 152 : /* 通 常 トレース */ 153 : servopwmout( iservopwm ); 154 : i = getservoangle(); 155 : if( i > 110 ) { 156 : motor_f( 0, 0 ); 157 : motor_r( 0, 0 ); 158 : } else if( i > 15 ) { 159 : motor_f( diff(80), 80 ); 160 : motor_r( diff(80), 80 ); 161 : } else if( i < -110 ) { 162 : motor_f( 0, 0 ); 163 : motor_r( 0, 0 ); 164 : } else if( i < -15 ) { 165 : motor_f( 80, diff(80) ); 166 : motor_r( 80, diff(80) ); 167 : } else { 168 : motor_f( 100, 100 ); 169 : motor_r( 100, 100 ); 170 : } 171 : if( check_crossline() ) { /* クロスラインチェック */ 172 : cnt1 = 0; 173 : crank_mode = 1; 174 : pattern = 21; 175 : } 176 : break; 177 : 178 : case 21: 179 : /* クロスライン 通 過 処 理 */ 180 : servopwmout( iservopwm ); 181 : led_out( 0x3 ); 182 : motor_f( 0, 0 ); 183 : motor_r( 0, 0 ); 184 : if( cnt1 >= 100 ) { 185 : cnt1 = 0; 186 : pattern = 22; 187 : } 188 : break; 189 : 190 : case 22: 191 : /* クロスライン 後 のトレース 直 角 検 出 処 理 */ 192 : servopwmout( iservopwm ); 193 : if( iencoder >= 11 ) { /* エンコーダによりスピード 制 御 */ 194 : motor_f( 0, 0 ); 195 : motor_r( 0, 0 ); 196 : } else { 197 : motor2_f( 70, 70 ); 198 : motor2_r( 70, 70 ); 199 : } 200 : 201 : if( (sensor_inp()&0x01) == 0x01 ) { /* 右 クランク? */ 202 : led_out( 0x1 ); 203 : cnt1 = 0; 204 : pattern = 31; 205 : break; 206 : } 207 : if( (sensor_inp()&0x08) == 0x08 ) { /* 左 クランク? */ 208 : led_out( 0x2 ); 209 : cnt1 = 0; 210 : pattern = 41; 211 : break; 212 : } 213 : break; 214 : 215 : case 31: 216 : /* 右 クランク 処 理 */ 217 : servopwmout( 50 ); /* 振 りが 弱 いときは 大 きくする */ 218 : motor_f( 60, 35 ); /* この 部 分 は 角 度 計 算 (4WD 時 ).xls */ 219 : motor_r( 48, 24 ); /* で 計 算 */ 220 : if( sensor_inp() == 0x04 ) { /* 曲 げ 終 わりチェック */ 221 : cnt1 = 0; 222 : isensorpattern = 0; 223 : crank_mode = 0; 224 : pattern = 32; 225 : } 226 : break; 227 : 228 : case 32: 229 : /* 少 し 時 間 が 経 つまで 待 つ */ 230 : servopwmout( iservopwm ); 231 : motor2_r( 80, 80 ); 232 : motor2_f( 80, 80 ); 233 : if( cnt1 >= 100 ) { 234 : led_out( 0x0 ); 235 : pattern = 11; 236 : } 237 : break; 238 : 24

239 : case 41: 240 : /* 左 クランク 処 理 */ 241 : servopwmout( -50 ); /* 振 りが 弱 いときは 大 きくする */ 242 : motor_f( 35, 60 ); /* この 部 分 は 角 度 計 算 (4WD 時 ).xls */ 243 : motor_r( 24, 48 ); /* で 計 算 */ 244 : if( sensor_inp() == 0x02 ) { /* 曲 げ 終 わりチェック */ 245 : cnt1 = 0; 246 : isensorpattern = 0; 247 : crank_mode = 0; 248 : pattern = 42; 249 : } 250 : break; 251 : 252 : case 42: 253 : /* 少 し 時 間 が 経 つまで 待 つ */ 254 : servopwmout( iservopwm ); 255 : motor2_f( 80, 80 ); 256 : motor2_r( 80, 80 ); 257 : if( cnt1 >= 100 ) { 258 : led_out( 0x0 ); 259 : pattern = 11; 260 : } 261 : break; 262 : 263 : default: 264 : break; 265 : } 266 : } 267 : } 268 : 269 : /************************************************************************/ 270 : /* R8C/35A スペシャルファンクションレジスタ(SFR)の 初 期 化 */ 271 : /************************************************************************/ 272 : void init( void ) 273 : { 274 : int i; 275 : 276 : /* クロックをXINクロック(20MHz)に 変 更 */ 277 : prc0 = 1; /* プロテクト 解 除 */ 278 : cm13 = 1; /* P4_6,P4_7をXIN-XOUT 端 子 にする*/ 279 : cm05 = 0; /* XINクロック 発 振 */ 280 : for(i=0; i<50; i++ ); /* 安 定 するまで 少 し 待 つ( 約 10ms) */ 281 : ocd2 = 0; /* システムクロックをXINにする */ 282 : prc0 = 0; /* プロテクトON */ 283 : 284 : /* ポートの 入 出 力 設 定 */ 285 : /* bit7 bit6 bit5 bit4 286 : bit3 bit2 bit1 bit0 */ 287 : 288 : /* センサテ シ タル 右 端 センサ 左 アナロク センサ 右 アナロク センサテ シ タル 中 心 289 : センサスタートハ ー 角 度 ボリューム 未 接 続 フ ッシュスイッチ(SW2) */ 290 : p0 = 0x00; 291 : prc2 = 1; /* PD0のプロテクト 解 除 */ 292 : pd0 = 0x00; 293 : pu00 = 1; /* p0_0~p0_3プルアップon */ 294 : 295 : /* 未 接 続 未 接 続 RxD0 TxD0 296 : マイコンホ ート のLED3 マイコンホ ート のLED2 マイコンホ ート のLED1 マイコンホ ート のLED0 */ 297 : p1 = 0x0f; 298 : pd1 = 0xdf; 299 : 300 : /* センサテ シ タル 左 端 センサテ シ タル 左 中 センサテ シ タル 右 中 未 接 続 301 : フ ッシュスイッチ(SW4) 右 後 PWM(TRDGRB0) 右 前 PWM(TRDGRC0)エンコーダパルス*/ 302 : p2 = 0x00; 303 : pd2 = 0x06; 304 : pu04 = 1; /* p2_0~p2_3プルアップon */ 305 : 306 : /* 左 後 BREAKorFREE 左 後 方 向 左 前 BREAKorFREE 左 前 方 向 307 : 右 前 BREAKorFREE 右 前 方 向 右 後 BREAKorFREE 右 後 方 向 */ 308 : p3 = 0xaa; 309 : pd3 = 0xff; 310 : 311 : /* XOUT XIN マイコンホ ート DIPSW2 マイコンホ ート DIPSW1 312 : マイコンホ ート DIPSW0 VREF 端 子 無 し 端 子 無 し */ 313 : p4 = 0x00; 314 : pd4 = 0x80; 315 : 316 : /* マイコンホ ート DIPSW3 未 接 続 端 子 無 し 端 子 無 し 317 : 端 子 無 し 端 子 無 し 端 子 無 し 端 子 無 し */ 318 : p5 = 0x00; 319 : pd5 = 0x40; 320 : 321 : /* ステアPWM(TRCGRD) 左 後 PWM(TRCGRC) 左 前 PWM(TRCGRB) フ ッシュスイッチ(SW1) 322 : フ ッシュスイッチ(SW3) 未 接 続 ステアBREAKorFREE ステア 方 向 */ 323 : p6 = 0x02; 324 : pd6 = 0xe3; 325 : pu14 = 1; /* p6_0~p6_3プルアップon */ 326 : pu15 = 1; /* p6_4~p6_7プルアップon */ 327 : 328 : pinsr = 0x08; /* 入 出 力 に 関 係 なく 端 子 レヘ ルを 読 む*/ 329 : 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 25

330 : /* A/Dコンバータの 設 定 */ 331 : admod = 0x33; /* 繰 り 返 し 掃 引 モードに 設 定 */ 332 : adinsel = 0x30; /* 入 力 端 子 P0の8 端 子 を 選 択 */ 333 : adcon1 = 0x30; /* A/D 動 作 可 能 */ 334 : asm(" nop "); /* φadの1サイクルウエイト 入 れる*/ 335 : adcon0 = 0x01; /* A/D 変 換 スタート */ 336 : 337 : /* タイマRBの 設 定 */ 338 : /* 割 り 込 み 周 期 = 1 / 20[MHz] * (TRBPRE+1) * (TRBPR+1) 339 : = 1 / (20*10^6) * 200 * 100 340 : = 0.001[s] = 1[ms] 341 : */ 342 : trbmr = 0x00; /* 動 作 モード 分 周 比 設 定 */ 343 : trbpre = 200-1; /* プリスケーラレジスタ */ 344 : trbpr = 100-1; /* プライマリレジスタ */ 345 : trbic = 0x05; /* 割 り 込 み 優 先 レベル 設 定 */ 346 : trbcr = 0x01; /* カウント 開 始 */ 347 : 348 : /* タイマRC PWMモード 設 定 ( 左 前 モータ 右 前 モータ ステアリンク モータ) */ 349 : trcpsr0 = 0x60; /* TRCIOA 端 子 =なし,B 端 子 =P6_5 */ 350 : trcpsr1 = 0x55; /* TRCIOC 端 子 =P6_6,D 端 子 =P6_7 */ 351 : trcmr = 0x0f; /* PWMモード 選 択 ビット 設 定 */ 352 : trccr1 = 0x8e; /* ソースカウント:f1, 初 期 出 力 の 設 定 */ 353 : trccr2 = 0x00; /* 出 力 レベルの 設 定 */ 354 : trcgra = TRC_MOTOR_CYCLE - 1; /* 周 期 設 定 */ 355 : trcgrb = trcgrb_buff = trcgra; /* P6_5 端 子 のON 幅 ( 左 前 モータ) */ 356 : trcgrc = trcgrc_buff = trcgra; /* P6_6 端 子 のON 幅 ( 左 後 モータ) */ 357 : trcgrd = trcgrd_buff = trcgra; /* P6_7 端 子 のON 幅 (ステアリンク モータ) */ 358 : trcic = 0x07; /* 割 り 込 み 優 先 レベル 設 定 */ 359 : trcier = 0x01; /* IMIAを 許 可 */ 360 : trcoer = 0x01; /* 出 力 端 子 の 選 択 */ 361 : trcmr = 0x80; /* TRCカウント 開 始 */ 362 : 363 : /* タイマRD0 リセット 同 期 PWMモード 設 定 ( 左 後 モータ 右 後 モータ) */ 364 : trdpsr0 = 0x28; /* TRDIOB0=P2_2,C0=P2_1,D0=なし */ 365 : trdmr = 0x00; /* レジスタは 独 立 動 作 */ 366 : trdpmr = 0x07; /* PWM 端 子 設 定 B0,C0をPMW 端 子 に */ 367 : trdfcr = 0x80; /* アウトフ ットコンヘ ア 機 能 に 設 定 */ 368 : trdcr0 = 0x20; /* ソースカウントの 選 択 :f1 */ 369 : trdgra0 = TRD_MOTOR_CYCLE - 1; /* 周 期 設 定 */ 370 : trdgrb0 = trdgrb0_buff = trdgra0; /* P2_2 端 子 のON 幅 ( 右 後 モータ) */ 371 : trdgrc0 = trdgrc0_buff = trdgra0; /* P2_1 端 子 のON 幅 ( 右 前 モータ) */ 372 : imiea_trdier0 = 1; /* IMFAビットによる 割 り 込 み 許 可 */ 373 : trd0ic = 0x06; /* 割 り 込 み 優 先 レベル 設 定 */ 374 : polb_trdpocr0 = 0; /* TRDIOB0 端 子 出 力 レヘ ルは"L"アクテ ィフ */ 375 : polc_trdpocr0 = 0; /* TRDIOC0 端 子 出 力 レヘ ルは"L"アクテ ィフ */ 376 : tob0_trdocr = 1; /* TRDIOB0 端 子 初 期 はアクテ ィフ レヘ ル*/ 377 : toc0_trdocr = 1; /* TRDIOC0 端 子 初 期 はアクテ ィフ レヘ ル*/ 378 : trdoer1 = 0xf9; /* 出 力 端 子 の 選 択 */ 379 : tstart0_trdstr= 1; /* TRD0カウント 開 始 */ 380 : 381 : /* タイマRD1 外 部 入 力 (ロータリエンコーダのパルスカウント) */ 382 : trdioa0sel0 = 1; /* TRDCLK 端 子 :P2_0に 設 定 */ 383 : stclk_trdfcr = 1; /* 外 部 クロック 入 力 有 効 に 設 定 */ 384 : trdcr1 = 0x15; /* TRDCLK 端 子 両 エッジカウント */ 385 : tstart1_trdstr= 1; /* TRD1カウント 開 始 */ 386 : } 387 : 388 : /************************************************************************/ 389 : /* タイマRB 割 り 込 み 処 理 */ 390 : /************************************************************************/ 391 : #pragma interrupt inttrb(vect=24) 392 : void inttrb( void ) 393 : { 394 : unsigned int i; 395 : 396 : asm(" fset I "); /* タイマRB 以 上 の 割 り 込 み 許 可 */ 397 : 398 : cnt1++; 399 : 400 : /* サーボモータ 制 御 */ 401 : servocontrol(); 402 : 403 : /* 10 回 中 1 回 実 行 する 処 理 */ 404 : itimer10++; 405 : switch( itimer10 ) { 406 : case 1: 407 : /* エンコーダ 制 御 */ 408 : i = trd1; 409 : iencoder = i - uencoderbuff; 410 : lencodertotal += iencoder; 411 : uencoderbuff = i; 412 : break; 413 : 414 : case 2: 415 : break; 416 : 417 : case 3: 418 : break; 419 : 26

420 : case 4: 421 : break; 422 : 423 : case 5: 424 : break; 425 : 426 : case 6: 427 : break; 428 : 429 : case 7: 430 : break; 431 : 432 : case 8: 433 : break; 434 : 435 : case 9: 436 : break; 437 : 438 : case 10: 439 : /* itimer10 変 数 の 処 理 */ 440 : itimer10 = 0; 441 : break; 442 : } 443 : } 444 : 445 : /************************************************************************/ 446 : /* タイマRC 割 り 込 み 処 理 */ 447 : /************************************************************************/ 448 : #pragma interrupt /B inttrc(vect=7) 449 : void inttrc( void ) 450 : { 451 : /* タイマRC デューティ 比 の 設 定 */ 452 : trcgrd = trcgrd_buff; /* ステアリンク モータ PWMセット */ 453 : trcgrb = trcgrb_buff; /* 右 前 モータ PWMセット */ 454 : trcgrc = trcgrc_buff; /* 右 後 モータ PWMセット */ 455 : 456 : imfa_trcsr = 0; 457 : } 458 : 459 : /************************************************************************/ 460 : /* タイマRD0 割 り 込 み 処 理 */ 461 : /************************************************************************/ 462 : #pragma interrupt inttrd0(vect=8) 463 : void inttrd0( void ) 464 : { 465 : asm(" fset I "); /* タイマRD0 以 上 の 割 り 込 み 許 可 */ 466 : 467 : /* タイマRD0 デューティ 比 の 設 定 */ 468 : trdgrb0 = trdgrb0_buff; /* 左 前 モータ PWMセット */ 469 : trdgrc0 = trdgrc0_buff; /* 左 後 モータ PWMセット */ 470 : 471 : imfa_trdsr0 = 0; 472 : } 473 : 474 : /************************************************************************/ 475 : /* アナログセンサ 基 板 TypeS Ver.2のデジタルセンサ 値 読 み 込 み */ 476 : /* 引 数 なし */ 477 : /* 戻 り 値 左 端 左 中 右 中 右 端 のデジタルセンサ 0: 黒 1: 白 */ 478 : /************************************************************************/ 479 : unsigned char sensor_inp( void ) 480 : { 481 : unsigned char sensor; 482 : 483 : sensor = (p2_7<<3) (p2_6<<2) (p2_5<<1) p0_7; 484 : sensor = ~sensor; 485 : sensor &= 0x0f; 486 : 487 : return sensor; 488 : } 489 : 490 : /************************************************************************/ 491 : /* アナログセンサ 基 板 TypeS Ver.2の 中 心 デジタルセンサ 読 み 込 み */ 492 : /* 引 数 なし */ 493 : /* 戻 り 値 中 心 デジタルセンサ 0: 黒 1: 白 */ 494 : /************************************************************************/ 495 : unsigned char center_inp( void ) 496 : { 497 : unsigned char sensor; 498 : 499 : sensor = ~p0_4 & 0x01; 500 : 501 : return sensor; 502 : } 503 : 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 27

504 : /************************************************************************/ 505 : /* アナログセンサ 基 板 TypeS Ver.2のスタートバー 検 出 センサ 読 み 込 み */ 506 : /* 引 数 なし */ 507 : /* 戻 り 値 0:スタートバーなし 1:スタートバーあり */ 508 : /************************************************************************/ 509 : unsigned char startbar_get( void ) 510 : { 511 : unsigned char sensor; 512 : 513 : sensor = ~p0_3 & 0x01; 514 : 515 : return sensor; 516 : } 517 : 518 : /************************************************************************/ 519 : /* マイコンボード 上 のディップスイッチ 値 読 み 込 み */ 520 : /* 引 数 なし */ 521 : /* 戻 り 値 スイッチ 値 0~15 */ 522 : /************************************************************************/ 523 : unsigned char dipsw_get( void ) 524 : { 525 : unsigned char sw; 526 : 527 : sw = (p5_7<<3) (p4_5<<2) (p4_4<<1) p4_3; 528 : 529 : return sw; 530 : } 531 : 532 : /************************************************************************/ 533 : /* 基 板 マイコンカー 上 のプッシュスイッチ 値 読 み 込 み(SW1~4) */ 534 : /* 引 数 なし */ 535 : /* 戻 り 値 スイッチ 値 bit3:sw1 bit2:sw2 bit1:sw3 bit0:sw4 0:OFF 1:ON */ 536 : /************************************************************************/ 537 : unsigned char pushsw_get( void ) 538 : { 539 : unsigned char sw; 540 : 541 : sw = (p6_4<<3) (p0_0<<2) (p6_3<<1) p2_3; 542 : sw = ~sw; 543 : sw &= 0x0f; 544 : 545 : return sw; 546 : } 547 : 548 : /************************************************************************/ 549 : /* マイコンボード 上 のLED 制 御 */ 550 : /* 引 数 4 個 のLED 制 御 0:OFF 1:ON */ 551 : /* 戻 り 値 なし */ 552 : /************************************************************************/ 553 : void led_out( unsigned char led ) 554 : { 555 : unsigned char d; 556 : 557 : d = p1 & 0xf0; 558 : p1 = d (~led & 0x0f); 559 : } 560 : 561 : /************************************************************************/ 562 : /* 後 輪 の 速 度 制 御 */ 563 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 564 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 565 : /* 戻 り 値 なし */ 566 : /************************************************************************/ 567 : void motor_r( int accele_l, int accele_r ) 568 : { 569 : int sw_data; 570 : 571 : sw_data = dipsw_get() + 5; /* ディップスイッチ 読 み 込 み */ 572 : accele_l = accele_l * sw_data / 20; 573 : accele_r = accele_r * sw_data / 20; 574 : 575 : motor2_r( accele_l, accele_r ); 576 : } 577 : 28

578 : /************************************************************************/ 579 : /* 後 輪 の 速 度 制 御 2 ディップスイッチには 関 係 しないmotor 関 数 */ 580 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 581 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 582 : /* 戻 り 値 なし */ 583 : /* メモ 1~4%は 5%になります */ 584 : /************************************************************************/ 585 : void motor2_r( int accele_l, int accele_r ) 586 : { 587 : /* 左 後 モータ */ 588 : if( accele_l >= 0 ) { 589 : p3_6 = 0; 590 : } else { 591 : p3_6 = 1; 592 : accele_l = -accele_l; 593 : } 594 : if( accele_l == 0 ) { 595 : // 0%のとき 596 : trcgrc = trcgrc_buff = trcgra; 597 : } else if( accele_l <= 5 ) { 598 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 599 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * 5 / 100; 600 : } else if( accele_l <= 99 ) { 601 : // 6~99%のとき 602 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * accele_l / 100; 603 : } else { 604 : // 100%のとき( 実 際 は99%を 設 定 ) 605 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 606 : } 607 : 608 : /* 右 後 モータ */ 609 : if( accele_r >= 0 ) { 610 : p3_0 = 0; 611 : } else { 612 : p3_0 = 1; 613 : accele_r = -accele_r; 614 : } 615 : if( accele_r == 0 ) { 616 : // 0%のとき 617 : trdgrb0 = trdgrb0_buff = trdgra0; 618 : } else if( accele_r <= 5 ) { 619 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 620 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * 5 / 100; 621 : } else if( accele_r <= 99 ) { 622 : // 6~99%のとき 623 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * accele_r / 100; 624 : } else { 625 : // 100%のとき( 実 際 は99%を 設 定 ) 626 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * 99 / 100; 627 : } 628 : } 629 : 630 : /************************************************************************/ 631 : /* 前 輪 の 速 度 制 御 */ 632 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 633 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 634 : /* 戻 り 値 なし */ 635 : /************************************************************************/ 636 : void motor_f( int accele_l, int accele_r ) 637 : { 638 : int sw_data; 639 : 640 : sw_data = dipsw_get() + 5; /* ディップスイッチ 読 み 込 み */ 641 : accele_l = accele_l * sw_data / 20; 642 : accele_r = accele_r * sw_data / 20; 643 : 644 : motor2_f( accele_l, accele_r ); 645 : } 646 : 647 : /************************************************************************/ 648 : /* 前 輪 の 速 度 制 御 2 ディップスイッチには 関 係 しないmotor 関 数 */ 649 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 650 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 651 : /* 戻 り 値 なし */ 652 : /* メモ 1~4%は 5%になります */ 653 : /************************************************************************/ 654 : void motor2_f( int accele_l, int accele_r ) 655 : { 656 : /* 左 前 モータ */ 657 : if( accele_l >= 0 ) { 658 : p3_4 = 0; 659 : } else { 660 : p3_4 = 1; 661 : accele_l = -accele_l; 662 : } 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 29

663 : if( accele_l == 0 ) { 664 : // 0%のとき 665 : trcgrb = trcgrb_buff = trcgra; 666 : } else if( accele_l <= 5 ) { 667 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 668 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * 5 / 100; 669 : } else if( accele_l <= 99 ) { 670 : // 6~99%のとき 671 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * accele_l / 100; 672 : } else { 673 : // 100%のとき( 実 際 は99%を 設 定 ) 674 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 675 : } 676 : 677 : /* 右 前 モータ */ 678 : if( accele_r >= 0 ) { 679 : p3_2 = 0; 680 : } else { 681 : p3_2 = 1; 682 : accele_r = -accele_r; 683 : } 684 : if( accele_r == 0 ) { 685 : // 0%のとき 686 : trdgrc0 = trdgrc0_buff = trdgra0; 687 : } else if( accele_r <= 5 ) { 688 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 689 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * 5 / 100; 690 : } else if( accele_r <= 99 ) { 691 : // 6~99%のとき 692 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * accele_r / 100; 693 : } else { 694 : // 100%のとき( 実 際 は99%を 設 定 ) 695 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * 99 / 100; 696 : } 697 : } 698 : 699 : /************************************************************************/ 700 : /* 後 モータ 動 作 (BRAKE= 動 作 とブレーキの 繰 り 返 し FREE=0%のフリー) */ 701 : /* 引 数 左 モータ:FREE or BRAKE, 右 モータ:FREE or BRAKE */ 702 : /* 戻 り 値 なし */ 703 : /* メモ フリーにすると PWM 値 に 関 わらず0%のフリーになります */ 704 : /* モータト ライフ 基 板 TypeSとは 動 作 が 違 いますので 気 を 付 けてください */ 705 : /************************************************************************/ 706 : void motor_mode_r( int mode_l, int mode_r ) 707 : { 708 : if( mode_l ) { 709 : p3_7 = 0; 710 : } else { 711 : p3_7 = 1; 712 : } 713 : if( mode_r ) { 714 : p3_1 = 0; 715 : } else { 716 : p3_1 = 1; 717 : } 718 : } 719 : 720 : /************************************************************************/ 721 : /* 前 モータ 動 作 (BRAKE= 動 作 とブレーキの 繰 り 返 し FREE=0%のフリー) */ 722 : /* 引 数 左 モータ:FREE or BRAKE, 右 モータ:FREE or BRAKE */ 723 : /* 戻 り 値 なし */ 724 : /* メモ フリーにすると PWM 値 に 関 わらず0%のフリーになります */ 725 : /* モータト ライフ 基 板 TypeSとは 動 作 が 違 いますので 気 を 付 けてください */ 726 : /************************************************************************/ 727 : void motor_mode_f( int mode_l, int mode_r ) 728 : { 729 : if( mode_l ) { 730 : p3_5 = 0; 731 : } else { 732 : p3_5 = 1; 733 : } 734 : if( mode_r ) { 735 : p3_3 = 0; 736 : } else { 737 : p3_3 = 1; 738 : } 739 : } 740 : 30

741 : /************************************************************************/ 742 : /* サーボモータ 制 御 */ 743 : /* 引 数 サーボモータPWM:-100~100 */ 744 : /* 0で 停 止 100で 右 に100% -100で 左 に100% */ 745 : /* 戻 り 値 なし */ 746 : /************************************************************************/ 747 : void servopwmout( int pwm ) 748 : { 749 : if( pwm >= 0 ) { 750 : p6_0 = 0; 751 : } else { 752 : p6_0 = 1; 753 : pwm = -pwm; 754 : } 755 : 756 : if( pwm <= 2 ) { 757 : trcgrd = trcgrd_buff = trcgra; 758 : } if( pwm <= 99 ) { 759 : trcgrd_buff = (unsigned long)(trc_motor_cycle-1) * pwm / 100; 760 : } else { 761 : trcgrd_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 762 : } 763 : } 764 : 765 : /************************************************************************/ 766 : /* クロスライン 検 出 処 理 */ 767 : /* 引 数 なし */ 768 : /* 戻 り 値 0:クロスラインなし 1:あり */ 769 : /************************************************************************/ 770 : int check_crossline( void ) 771 : { 772 : unsigned char b; 773 : int ret = 0; 774 : 775 : b = sensor_inp(); 776 : if( b==0x0f b==0x0e b==0x0d b==0x0b b==0x07 ) { 777 : ret = 1; 778 : } 779 : return ret; 780 : } 781 : 782 : /************************************************************************/ 783 : /* サーボ 角 度 取 得 */ 784 : /* 引 数 なし */ 785 : /* 戻 り 値 入 れ 替 え 後 の 値 */ 786 : /************************************************************************/ 787 : int getservoangle( void ) 788 : { 789 : return( ad5 - iangle0 ); 790 : } 791 : 792 : /************************************************************************/ 793 : /* アナログセンサ 値 取 得 */ 794 : /* 引 数 なし */ 795 : /* 戻 り 値 センサ 値 */ 796 : /************************************************************************/ 797 : int getanalogsensor( void ) 798 : { 799 : int ret; 800 : 801 : ret = ad1 - ad2; /* アナログセンサ 情 報 取 得 */ 802 : 803 : if(!crank_mode ) { 804 : /* クランクモードでなければ 補 正 処 理 */ 805 : switch( isensorpattern ) { 806 : case 0: 807 : if( sensor_inp() == 0x04 ) { 808 : ret = -650; 809 : break; 810 : } 811 : if( sensor_inp() == 0x02 ) { 812 : ret = 650; 813 : break; 814 : } 815 : if( sensor_inp() == 0x0c ) { 816 : ret = -700; 817 : isensorpattern = 1; 818 : break; 819 : } 820 : if( sensor_inp() == 0x03 ) { 821 : ret = 700; 822 : isensorpattern = 2; 823 : break; 824 : } 825 : break; 826 : 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 31

827 : case 1: 828 : /* センサ 右 寄 り */ 829 : ret = -700; 830 : if( sensor_inp() == 0x04 ) { 831 : isensorpattern = 0; 832 : } 833 : break; 834 : 835 : case 2: 836 : /* センサ 左 寄 り */ 837 : ret = 700; 838 : if( sensor_inp() == 0x02 ) { 839 : isensorpattern = 0; 840 : } 841 : break; 842 : } 843 : } 844 : 845 : return ret; 846 : } 847 : 848 : /************************************************************************/ 849 : /* サーボモータ 制 御 */ 850 : /* 引 数 なし */ 851 : /* 戻 り 値 グローバル 変 数 iservopwm に 代 入 */ 852 : /************************************************************************/ 853 : void servocontrol( void ) 854 : { 855 : int i, iret, ip, id; 856 : int kp, kd; 857 : 858 : i = getanalogsensor(); /* センサ 値 取 得 */ 859 : kp = 1; /* kpを 増 やしていき ブルブルが */ 860 : kd = 0; /* 大 きくなったらkdを 増 やしてく */ 861 : /* ださい */ 862 : /* サーボモータ 用 PWM 値 計 算 */ 863 : ip = kp * i; /* 比 例 */ 864 : id = kd * (isensorbefore - i ); /* 微 分 ( 目 安 はPの5~10 倍 ) */ 865 : iret = ip - id; 866 : iret /= 64; 867 : 868 : /* PWMの 上 限 の 設 定 */ 869 : if( iret > 50 ) iret = 50; /* マイコンカーが 安 定 したら */ 870 : if( iret < -50 ) iret = -50; /* 上 限 を95くらいにしてください */ 871 : iservopwm = iret; 872 : 873 : isensorbefore = i; /* 次 回 はこの 値 が1ms 前 の 値 となる*/ 874 : } 875 : 876 : /************************************************************************/ 877 : /* 外 輪 のPWMから 内 輪 のPWMを 割 り 出 す ハンドル 角 度 は 現 在 の 値 を 使 用 */ 878 : /* 引 数 外 輪 PWM */ 879 : /* 戻 り 値 内 輪 PWM */ 880 : /************************************************************************/ 881 : int diff( int pwm ) 882 : { 883 : int i, ret; 884 : 885 : i = getservoangle() / 3; /* 1 度 あたりの 増 分 で 割 る */ 886 : if( i < 0 ) i = -i; 887 : if( i > 45 ) i = 45; 888 : ret = revolution_difference[i] * pwm / 100; 889 : 890 : return ret; 891 : } 892 : 893 : /************************************************************************/ 894 : /* end of file */ 895 : /************************************************************************/ 896 : 897 : /* 898 : 改 訂 経 歴 899 : 900 : 2014.06.23 Ver.1.00 作 成 901 : */ 32

5.2 プログラムの 解 説 5.2.1 シンボル 定 義 24 : /*======================================*/ 25 : /* シンボル 定 義 */ 26 : /*======================================*/ 27 : /* 定 数 設 定 */ 28 : #define TRC_MOTOR_CYCLE 20000 /* 左 前, 右 前 モータPWMの 周 期 */ 29 : /* 50[ns] * 20000 = 1.00[ms] */ 30 : #define TRD_MOTOR_CYCLE 20000 /* 左 後, 右 後,サーホ モータPWMの 周 期 */ 31 : /* 50[ns] * 20000 = 1.00[ms] */ 32 : #define FREE 1 /* モータモード フリー */ 33 : #define BRAKE 0 /* モータモード ブレーキ */ 変 数 名 内 容 タイマ RC の PWM 波 形 の 周 期 を 決 める 値 です タイマ RC では 左 前 モータ 右 前 モータ ステアリングモータを 制 御 しています タイマ RC カウントソースは 20MHz の 水 晶 振 動 子 を 使 います 周 期 は 次 のようになります TRC_MOTOR_ CYCLE 1/(20 10 6 )=50.00[ns] 今 回 PWM 周 期 は 1ms にします TRC_MOTOR_CYCLE は 次 のようになります PWM 周 期 /タイマ RC カウントソース=(1 10-3 )/(50 10-9 )=20,000 タイマ RD0 の PWM 波 形 の 周 期 を 決 める 値 です タイマ RD0 では 左 後 モータ 右 後 モー タを 制 御 しています タイマ RD0 カウントソースは 20MHz の 水 晶 振 動 子 を 使 います 周 期 は 次 のようになります TRD_MOTOR_ CYCLE 1/(20 10 6 )=50.00[ns] 今 回 PWM 周 期 は 1ms にします TRD_MOTOR_CYCLE は 次 のようになります PWM 周 期 /タイマ RD0 カウントソース=(1 10-3 )/(50 10-9 )=20,000 motor_mode_r 関 数 motor_mode_f 関 数 で 使 用 する 定 数 です モータをフリー 動 作 にしたい 場 合 は FREE PWM 出 力 時 の"0"の 信 号 をブレーキにしたい 場 合 は BRAKE を 引 数 にセットします FREE BRAKE 例 ) motor_mode_f( BRAKE, FREE); // 左 前 モータはブレーキ 右 前 モータはフリー motor_mode_r( FREE, BRAKE ); // 左 後 モータはフリー 右 後 モータはブレーキ 基 板 マイコンカーVer.2 のフリーは motor_r 関 数 motor_f 関 数 の 値 に 関 係 なく PWM が 0%のフリー 動 作 になります モータドライブ 基 板 TypeS Ver.4 のフリーとは 動 作 が 異 なり ます 33

5.2.2 変 数 の 定 義 58 : /*======================================*/ 59 : /* グローバル 変 数 の 宣 言 */ 60 : /*======================================*/ 61 : int pattern; /* マイコンカー 動 作 パターン */ 62 : int crank_mode; /* 1:クランクモード 0: 通 常 */ 63 : unsigned long cnt1; /* タイマ 用 */ 64 : 65 : /* エンコーダ 関 連 */ 66 : int itimer10; /* 10msカウント 用 */ 67 : long lencodertotal; /* 積 算 値 保 存 用 */ 68 : int iencoder; /* 10ms 毎 の 最 新 値 */ 69 : unsigned int uencoderbuff; /* 計 算 用 割 り 込 み 内 で 使 用 */ 70 : 71 : /* サーボ 関 連 */ 72 : int isensorbefore; /* 前 回 のセンサ 値 保 存 */ 73 : int iservopwm; /* サーボPWM 値 */ 74 : int iangle0; /* 中 心 時 のA/D 値 保 存 */ 75 : 76 : /* センサ 関 連 */ 77 : int isensorpattern; /* センサ 状 態 保 持 用 */ 78 : 79 : /* TRCレジスタのバッファ */ 80 : unsigned int trcgrb_buff; /* TRCGRBのバッファ */ 81 : unsigned int trcgrc_buff; /* TRCGRCのバッファ */ 82 : unsigned int trcgrd_buff; /* TRCGRDのバッファ */ 83 : 84 : /* TRD0レジスタのバッファ */ 85 : unsigned int trdgrb0_buff; /* TRDGRB0のバッファ */ 86 : unsigned int trdgrc0_buff; /* TRDGRC0のバッファ */ 変 数 名 pattern crank_mode cnt1 itimer10 lencodertotal iencoder uencoderbuff isensorbefore 内 容 マイコンカーの 現 在 の 動 作 パターンを 設 定 します アナログセンサ 値 を デジタルセンサを 使 って 補 正 するかしないか 設 定 します 0: 補 正 ON( 通 常 トレース 状 態 ) 1: 補 正 OFF(クロスラインを 検 出 後 とクランクトレースモード 時 など) タイマです 1ms ごとに 増 加 していきます この 変 数 を 使 って 100ms 待 つなど 時 間 のカウ ントをします ロータリエンコーダ 処 理 は タイマ RB の 割 り 込 み 関 数 内 で 行 います 割 り 込 みは 1ms ごと に 発 生 しますが ロータリエンコーダ 処 理 は 10ms ごとです そのため この 変 数 をタイマ RB 割 り 込 み 処 理 で 足 していき 10 になったら 処 理 するようにすれば 10ms ごとに 処 理 する のと 同 じことになります ロータリエンコーダの 積 算 値 が 保 存 されています この 値 で 基 板 マイコンカーVer.2 がス タートしてからの 距 離 が 分 かります 10ms ごとに 更 新 されます 10ms 間 のロータリエンコーダのパルス 値 が 保 存 されます この 値 で 基 板 マイコンカー Ver.2 の 速 度 が 分 かります 10ms ごとに 更 新 されます ロータリエンコーダ 変 数 の 計 算 用 です 通 常 のプログラムでは 使 用 しません 前 回 のアナログセンサ 値 を 保 存 します 通 常 のプログラムでは 使 用 しません 34

iservopwm iangle0 isensorpattern trcgrb_buff trcgrc_buff trcgrd_buff trdgrb0_buff trdgrc0_buff タイマ RB の 割 り 込 み 関 数 内 で 計 算 したサーボモータ 用 の PWM 値 保 存 用 です ステアリング 角 度 0 度 のときのボリューム A/D 値 を 保 存 します アナログセンサの A/D 値 を 取 得 する getanalogsensor 関 数 で 使 用 します アナログセンサ が 中 央 ラインをはずれたときの 対 処 用 です 通 常 のプログラムでは 使 用 しません TRCGRB のバッファとして 使 用 します TRCGRB の 値 は P6_5 端 子 から 出 力 する PWM 波 形 の ON 幅 ( 左 前 モータ)を 設 定 するレジスタです TRCGRB の 値 を 変 えるとき 直 接 このレジスタの 値 を 変 えるのではなく trcgrb_buff 変 数 の 値 を 変 更 します タイマ RC の 割 り 込 み 関 数 で trcgrb_buff 変 数 の 値 を TRCGRB に 設 定 します これは 直 接 TRCGRB の 値 を 変 更 すると PWM 波 形 が 乱 れることがあるためです 詳 しく は 後 述 します TRCGRC のバッファとして 使 用 します TRCGRC の 値 は P6_6 端 子 から 出 力 する PWM 波 形 の ON 幅 ( 左 後 モータ)を 設 定 するレジスタです TRCGRC の 値 を 変 えるとき 直 接 このレジスタの 値 を 変 えるのではなく trcgrc_buff 変 数 の 値 を 変 更 します タイマ RC の 割 り 込 み 関 数 で trcgrc_buff 変 数 の 値 を TRCGRC に 設 定 します これは 直 接 TRCGRC の 値 を 変 更 すると PWM 波 形 が 乱 れることがあるためです 詳 し くは 後 述 します TRCGRD のバッファとして 使 用 します TRCGRD の 値 は P6_7 端 子 から 出 力 する PWM 波 形 の ON 幅 (ステアリングモータ)を 設 定 するレジスタです TRCGRD の 値 を 変 えるとき 直 接 このレジスタの 値 を 変 えるのではなく trcgrd_buff 変 数 の 値 を 変 更 します タイマ RC の 割 り 込 み 関 数 で trcgrd_buff 変 数 の 値 を TRCGRD に 設 定 します これは 直 接 TRCGRD の 値 を 変 更 すると PWM 波 形 が 乱 れることがあるためです 詳 し くは 後 述 します TRDGRB0 のバッファとして 使 用 します TRDGRB0 の 値 は P2_2 端 子 から 出 力 する PWM 波 形 の ON 幅 ( 右 後 モータ)を 設 定 するレジスタです TRDGRB0 の 値 を 変 えるとき 直 接 このレジスタの 値 を 変 えるのではなく trdgrb0_buff 変 数 の 値 を 変 更 します タイマ RD0 の 割 り 込 み 関 数 で trdgrb0_buff 変 数 の 値 を TRDGRB0 に 設 定 します これは 直 接 TRDGRB0 の 値 を 変 更 すると PWM 波 形 が 乱 れることがあるためです 詳 し くは 後 述 します TRDGRC0 のバッファとして 使 用 します TRDGRC0 の 値 は P2_1 端 子 から 出 力 する PWM 波 形 の ON 幅 ( 右 前 モータ)を 設 定 するレジスタです TRDGRC0 の 値 を 変 えるとき 直 接 このレジスタの 値 を 変 えるのではなく trdgrc0_buff 変 数 の 値 を 変 更 します タイマ RD0 の 割 り 込 み 関 数 で trdgrc0_buff 変 数 の 値 を TRDGRC0 に 設 定 します これは 直 接 TRDGRC0 の 値 を 変 更 すると PWM 波 形 が 乱 れることがあるためです 詳 し くは 後 述 します 35

5.2.3 内 輪 差 値 計 算 用 の 配 列 追 加 88 : /* 内 輪 差 値 計 算 用 各 マイコンカーに 合 わせて 再 計 算 して 下 さい */ 89 : const revolution_difference[] = { /* 角 度 から 内 輪 外 輪 回 転 差 計 算 */ 90 : 100, 99, 97, 96, 95, 91 : 93, 92, 91, 89, 88, 92 : 87, 85, 84, 83, 82, 93 : 81, 79, 78, 77, 76, 94 : 74, 73, 72, 71, 70, 95 : 68, 67, 66, 65, 64, 96 : 62, 61, 60, 59, 57, 97 : 56, 55, 53, 52, 51, 98 : 50, 48, 47, 45, 44, 99 : 43 }; revolution_difference という 回 転 の 差 を 計 算 した 配 列 を 追 加 します この 配 列 は const を 先 頭 に 付 けています 値 の 変 更 しない 変 数 や 配 列 は RAM 上 に 配 置 する 必 要 はありません const 型 修 飾 子 を 指 定 するとマイコンの ROM エリアに 配 置 されます 今 回 の R8C/35A マイコンはプログラム ROM が 32KB 内 蔵 RAM が 2.5KB と RAM が 少 ないので RAM の 有 効 活 用 を 考 えて const を 付 けました const を 取 ると RAM エリアに 配 置 されます revolution_difference 配 列 の[ ] 内 に 数 字 を 入 れると 入 れた 数 字 番 目 の 数 値 が 返 ってきます [ ] の 中 に 入 れる 数 字 を 添 字 といいます 添 字 を 入 れたときの 値 を 下 記 に 示 します revolution_difference[ 0] = 100 revolution_difference[ 1] = 99 revolution_difference[ 2] = 97 revolution_difference[45] = 43 添 字 に 46 以 上 の 値 を 設 定 してもエラーにはなりませんが 不 定 な 値 が 返 ってきます 添 字 は 46 以 上 にしないよ うにしてください 値 の 意 味 は 外 輪 の 回 転 を 100 としたとき 添 字 に 現 在 のステアリング 角 度 ( 単 位 : 度 )を 入 れると 内 輪 の 回 転 数 が 返 ってきます 例 えば 添 字 が 2 のとき 97 が 返 ってきます これは 外 輪 100 ステアリング 角 度 が 2 度 のとき 内 輪 の 回 転 数 は 97 ということです ステアリング 角 度 が 0 度 ~45 度 のとき 内 輪 の 値 はあらかじめ 計 算 しておきます 今 回 は 基 板 マ イコンカーVer.2 のホイールベース=0.18 トレッド=0.145 で 計 算 しました 本 プログラムでは 後 輪 の 内 外 輪 差 のみ 計 算 し 前 輪 は 後 輪 の 値 を 使 っています 4 輪 の 内 外 輪 差 を 計 算 した い 場 合 は 7. 4 輪 の 回 転 数 計 算 を 参 考 にして 4 輪 の 配 列 を 作 ると 良 いでしょう 36

5.2.4 init 関 数 のクロックの 選 択 R8C/35A マイコンは 起 動 時 マイコン 内 蔵 の 低 速 オンチップオシレータ( 約 125kHz)で 動 作 します これを P4_6 端 子 P4_7 端 子 に 接 続 されている 20MHz の 水 晶 振 動 子 に 切 り 替 えます 269 : /************************************************************************/ 270 : /* R8C/35A スペシャルファンクションレジスタ(SFR)の 初 期 化 */ 271 : /************************************************************************/ 272 : void init( void ) 273 : { 274 : int i; 275 : 276 : /* クロックをXINクロック(20MHz)に 変 更 */ 277 : prc0 = 1; /* プロテクト 解 除 */ 278 : cm13 = 1; /* P4_6,P4_7をXIN-XOUT 端 子 にする*/ 279 : cm05 = 0; /* XINクロック 発 振 */ 280 : for(i=0; i<50; i++ ); /* 安 定 するまで 少 し 待 つ( 約 10ms) */ 281 : ocd2 = 0; /* システムクロックをXINにする */ 282 : prc0 = 0; /* プロテクトON */ 277~282 行 で 低 速 オンチップオシレータ( 約 125kHz)から 外 付 けの 水 晶 振 動 子 (20MHz)に 切 り 替 えています 詳 しくは マイコン 実 習 マニュアル(R8C/35A 版 ) を 参 照 してください 37

5.2.5 ポートの 入 出 力 設 定 284 : /* ポートの 入 出 力 設 定 */ 285 : /* bit7 bit6 bit5 bit4 286 : bit3 bit2 bit1 bit0 */ 287 : 288 : /* センサテ シ タル 右 端 センサ 左 アナロク センサ 右 アナロク センサテ シ タル 中 心 289 : センサスタートハ ー 角 度 ボリューム 未 接 続 フ ッシュスイッチ(SW2) */ 290 : p0 = 0x00; 291 : prc2 = 1; /* PD0のプロテクト 解 除 */ 292 : pd0 = 0x00; 293 : pu00 = 1; /* p0_0~p0_3プルアップon */ 294 : 295 : /* 未 接 続 未 接 続 RxD0 TxD0 296 : マイコンホ ート のLED3 マイコンホ ート のLED2 マイコンホ ート のLED1 マイコンホ ート のLED0 */ 297 : p1 = 0x0f; 298 : pd1 = 0xdf; 299 : 300 : /* センサテ シ タル 左 端 センサテ シ タル 左 中 センサテ シ タル 右 中 未 接 続 301 : フ ッシュスイッチ(SW4) 右 後 PWM(TRDGRB0) 右 前 PWM(TRDGRC0)エンコーダパルス*/ 302 : p2 = 0x00; 303 : pd2 = 0x06; 304 : pu04 = 1; /* p2_0~p2_3プルアップon */ 305 : 306 : /* 左 後 BREAKorFREE 左 後 方 向 左 前 BREAKorFREE 左 前 方 向 307 : 右 前 BREAKorFREE 右 前 方 向 右 後 BREAKorFREE 右 後 方 向 */ 308 : p3 = 0xaa; 309 : pd3 = 0xff; 310 : 311 : /* XOUT XIN マイコンホ ート DIPSW2 マイコンホ ート DIPSW1 312 : マイコンホ ート DIPSW0 VREF 端 子 無 し 端 子 無 し */ 313 : p4 = 0x00; 314 : pd4 = 0x80; 315 : 316 : /* マイコンホ ート DIPSW3 未 接 続 端 子 無 し 端 子 無 し 317 : 端 子 無 し 端 子 無 し 端 子 無 し 端 子 無 し */ 318 : p5 = 0x00; 319 : pd5 = 0x40; 320 : 321 : /* ステアPWM(TRCGRD) 左 後 PWM(TRCGRC) 左 前 PWM(TRCGRB) フ ッシュスイッチ(SW1) 322 : フ ッシュスイッチ(SW3) 未 接 続 ステアBREAKorFREE ステア 方 向 */ 323 : p6 = 0x02; 324 : pd6 = 0xe3; 325 : pu14 = 1; /* p6_0~p6_3プルアップon */ 326 : pu15 = 1; /* p6_4~p6_7プルアップon */ 327 : 328 : pinsr = 0x08; /* 入 出 力 に 関 係 なく 端 子 レヘ ルを 読 む*/ PD0~PD6 で ポート 0~ポート 6 の 入 出 力 設 定 を 行 います PD0~PD6 の 該 当 ビットを"1"にするとそのビットが 出 力 "0"にすると 入 力 になります 38

(1) ポートの 入 出 力 基 板 マイコンカーVer.2 の 接 続 機 器 に 合 わせてポートの 入 出 力 設 定 を 行 います ポートの 接 続 状 態 を 下 表 に 示 します ポート bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0 デジタル センサ 右 端 入 力 アナログ センサ 左 アナログ 入 力 アナログ センサ 右 アナログ 入 力 デジタル センサ 中 心 入 力 スタートバー 検 出 センサ 入 力 ポテンショメー タ(ステアリング 角 度 検 出 ) アナログ 入 力 未 接 続 タクトスイッチ 2 入 力 内 蔵 プルアップ OFF 内 蔵 プルアップ ON 1 未 接 続 未 接 続 マイコンボード RxD 入 力 マイコンボード TxD 出 力 マイコンボード LED3 出 力 マイコンボード LED2 出 力 マイコンボード LED1 出 力 マイコンボード LED0 出 力 2 3 4 5 6 デジタル センサ 左 端 入 力 左 後 モータ フリー/ブレーキ 出 力 水 晶 振 動 子 (20MHz) 出 力 内 蔵 プルアップ OFF デジタル センサ 左 中 入 力 デジタル センサ 右 中 入 力 内 蔵 プルアップ OFF 左 後 モータ 正 転 / 逆 転 出 力 左 前 モータ フリー/ブレーキ 出 力 内 蔵 プルアップ OFF 水 晶 振 動 子 (20MHz) 入 力 マイコンボード ディップスイッチ 3 未 接 続 入 力 内 蔵 プルアップ OFF ステアリングモータ PWM 出 力 マイコンボード ディップスイッチ 2 入 力 内 蔵 プルアップ OFF 左 後 モータ PWM 出 力 左 前 モータ PWM 出 力 内 蔵 プルアップ ON 表 の 斜 線 の bit は 端 子 がない bit です 未 接 続 ポートは 出 力 設 定 にします リセット 後 は 全 て 入 力 ポートです 未 接 続 左 前 モータ 正 転 / 逆 転 出 力 マイコンボード ディップスイッチ 1 入 力 タクトスイッチ 1 入 力 タクトスイッチ 4 入 力 右 前 モータ フリー/ブレーキ 出 力 マイコンボード ディップスイッチ 0 入 力 内 蔵 プルアップ OFF タクトスイッチ 3 入 力 内 蔵 プルアップ OFF 右 後 モータ PWM 出 力 右 前 モータ PWM 出 力 内 蔵 プルアップ ON 右 前 モータ 正 転 / 逆 転 出 力 右 後 モータ フリー/ブレーキ 出 力 内 蔵 プルアップ OFF Vcc 入 力 未 接 続 ロータリ エンコーダ パルス 入 力 右 後 モータ 正 転 / 逆 転 出 力 ステアリングモータ ステアリングモータ フリー/ブレーキ 正 転 / 逆 転 出 力 出 力 内 蔵 プルアップ ON (2) 端 子 のプルアップ タクトスイッチ 1~4 には プルアップ 抵 抗 が 接 続 されていないので マイコン 内 蔵 のプルアップ 抵 抗 を 使 用 しま す マイコン 内 蔵 のプルアップ 抵 抗 は 例 えば P0_3~P0_0 など 一 部 を 除 いて 複 数 端 子 を ON するか OFF するかし か 選 択 できません タクトスイッチ 以 外 の 端 子 も 内 蔵 プルアップ 抵 抗 を ON にしてしまいますが 内 蔵 プルアップ 抵 抗 は 標 準 値 50kΩ( 最 小 値 :25kΩ 最 大 値 :100kΩ)と 抵 抗 値 が 大 きいので 今 回 の 回 路 には 影 響 ありません 39

5.2.6 A/D コンバータの 設 定 A/D コンバータを 使 い アナログセンサ 左 アナログセンサ 右 ポテンショメータの 各 電 圧 を デジタル 値 に 変 換 します 330 : /* A/D コンバータの 設 定 */ 331 : admod = 0x33; /* 繰 り 返 し 掃 引 モードに 設 定 */ 332 : adinsel = 0x30; /* 入 力 端 子 P0 の 8 端 子 を 選 択 */ 333 : adcon1 = 0x30; /* A/D 動 作 可 能 */ 334 : asm(" nop "); /* φad の 1 サイクルウエイト 入 れる*/ 335 : adcon0 = 0x01; /* A/D 変 換 スタート */ A/D コンバータに 関 するレジスタ 設 定 を 下 記 に 示 します (1) A/D モードレジスタ(ADMOD:A-D mode register)の 設 定 ビット シンボル 説 明 設 定 値 7 adcap1 "0"を 設 定 6 adcap0 "0"を 設 定 5 4 md2 md1 A/D 動 作 モード 選 択 を 設 定 します 000: 単 発 モード 001: 設 定 しないでください 010: 繰 り 返 しモード 0 011: 繰 り 返 しモード 1 3 md0 100: 単 掃 引 モード 101: 設 定 しないでください 110: 繰 り 返 し 掃 引 モード 111: 設 定 しないでください 0x33 2 cks2 クロック 源 選 択 ビットを 設 定 します 0:f1(20MHz)を 選 択 1:fOCO-F( 高 速 オンチップオシレータ)を 選 択 1 0 cks1 cks0 分 周 選 択 ビットを 設 定 します 00:fAD の 8 分 周 (8/20MHz=400ns) 01:fAD の 4 分 周 (4/20MHz=200ns) 10:fAD の 2 分 周 (2/20MHz=100ns) 11:fAD の 1 分 周 (1/20MHz=50ns) fad とは bit2 で 設 定 したクロック 源 のことです このクロックを 何 分 周 で 使 用 するか 選 択 します 40

(2) A/D 入 力 選 択 レジスタ(ADINSEL:A-D input select register) 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル ビット シンボル 説 明 設 定 値 7 adgsel1 6 adgsel0 5 scan1 4 scan0 どのアナログ 入 力 端 子 を A/D 変 換 するか 設 定 します 0000:AN0(P0_7)~AN1(P0_6)の 2 端 子 0001:AN0(P0_7)~AN3(P0_4)の 4 端 子 0010:AN0(P0_7)~AN5(P0_2)の 6 端 子 0011:AN0(P0_7)~AN7(P0_0)の 8 端 子 0100:AN8(P1_0)~AN9(P1_1)の 2 端 子 0101:AN8(P1_0)~AN11(P1_3)の 4 端 子 0x30 3 - "0"を 設 定 2 ch2 "0"を 設 定 1 ch1 "0"を 設 定 0 ch0 "0"を 設 定 今 回 は P0_6 端 子 にアナログセンサ 左 P0_5 端 子 にアナログセンサ 右 P0_2 端 子 にステアリング 角 度 検 出 用 ポ テンショメータが 接 続 されています これらの 端 子 を A/D 入 力 端 子 にします それ 以 外 の 端 子 を A/D 変 換 にしても 問 題 は 無 いので ポート 0 の 8 端 子 を A/D 変 換 する 設 定 にします (3) A/D 制 御 レジスタ 1(ADCON1:A-D control register1) ビット シンボル 説 明 設 定 値 7 adddael "0"を 設 定 6 adddaen "0"を 設 定 A/D スタンバイビットを 設 定 します 0:A/D 動 作 停 止 (スタンバイ) 5 adstby 1:A/D 動 作 可 能 この bit を"0"から"1"にしたときは φa/d の 1 サイクル 以 上 経 過 した 後 に A/D 変 換 を 開 始 します 4 bits 8/10 ビットモード 選 択 ビットを 設 定 します 0:8 ビットモード 1:10 ビットモード 3 - "0"を 設 定 2 - "0"を 設 定 1 - "0"を 設 定 0 adex0 "0"を 設 定 0x30 (4) φad の 1 サイクル 以 上 ウェイトを 入 れる adstby ビットを 設 定 した 後 φa/d の 1 サイクル 以 上 経 過 した 後 に A/D 変 換 を 開 始 しなければいけません その ウェイトを 入 れるため アセンブリ 言 語 の nop 命 令 を 実 行 します C 言 語 ソースプログラム 内 では アセンブリ 言 語 は 実 行 できないため asm 命 令 というアセンブリ 言 語 を 実 行 できる C 言 語 の 命 令 を 使 って nop 命 令 を 実 行 します ち なみに nop は no operation( 何 もしない) 命 令 で この 命 令 を 実 行 するのに 1 サイクル 分 (50ns)の 時 間 がかかりま す asm( " nop "); 41

(5) A/D 制 御 レジスタ 0(ADCON0:A-D control register0) ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 2 - "0"を 設 定 1 - "0"を 設 定 0 adst A/D 変 換 開 始 フラグを 設 定 します 0:A/D 変 換 停 止 1:A/D 変 換 開 始 0x01 5.2.7 タイマ RB の 設 定 タイマ RB を 使 い 1ms ごとに 割 り 込 みを 発 生 させます 337 : /* タイマ RB の 設 定 */ 338 : /* 割 り 込 み 周 期 = 1 / 20[MHz] * (TRBPRE+1) * (TRBPR+1) 339 : = 1 / (20*10^6) * 200 * 100 340 : = 0.001[s] = 1[ms] 341 : */ 342 : trbmr = 0x00; /* 動 作 モード 分 周 比 設 定 */ 343 : trbpre = 200-1; /* プリスケーラレジスタ */ 344 : trbpr = 100-1; /* プライマリレジスタ */ 345 : trbic = 0x05; /* 割 り 込 み 優 先 レベル 設 定 */ 346 : trbcr = 0x01; /* カウント 開 始 */ タイマ RB に 関 するレジスタ 設 定 を 下 記 に 示 します (1) タイマ RB モードレジスタ(TRBMR:Timer RB mode register)の 設 定 ビット シンボル 説 明 設 定 値 7 tckcut_trbmr "0"を 設 定 6 - "0"を 設 定 5 4 tck1_trbmr tck0_trbmr タイマ RB カウントソース 選 択 ビットを 設 定 します 00:f1 (1/20MHz=50ns) 01:f8 (8/20MHz=400ns) 10:タイマ RA のアンダフロー 11:f2 (2/20MHz=100ns) 3 - "0"を 設 定 2 twrc_trbmr "0"を 設 定 0x00 1 tmod1_trbmr 0 tmod0_trbmr タイマ RB 動 作 モード 選 択 ビットを 設 定 します 00:タイマモード 01:プログラマブル 波 形 発 生 モード 10:プログラマブルワンショット 発 生 モード 11:プログラマブルウェイトワンショット 発 生 モード 42

(2) タイマ RB プリスケーラレジスタ(TRBPRE:Timer RB prescaler register)の 設 定 (3) タイマ RB プライマリレジスタ(TRBPR:Timer RB Primary Register)の 設 定 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル ビット シンボル 説 明 設 定 値 割 り 込 み 周 期 を 設 定 します 計 算 式 を 下 記 に 示 します (TRBPRE+1) (TRBPR+1)=タイマ RB 割 り 込 み 要 求 周 期 /タイマ RB カウントソース 今 回 タイマ RB 割 り 込 み 要 求 周 期 は 1ms です タイマ RB カウントソース は TRBMR で 設 定 した 50ns です よって TRBPRE 7~0 - (TRBPRE+1) (TRBPR+1)=1 10-3 /50 10-9 =20,000 200-1 TRBPR 7~0 これを 満 たす TRBPRE TRBPR を 探 します 今 回 は TRBPRE+1=200 TRBPRE=200-1 TRBPR+1=100 TRBPRE=100-1 にします ただし 下 記 を 満 たすようにしてください TRBPRE 255 TRBPR 255 - 上 記 の 計 算 により 100-1 にします 100-1 (4) タイマ RB 割 り 込 み 制 御 レジスタ(TRBIC:Timer RB interrupt control register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 ir_trbic "0"を 設 定 他 の 割 り 込 みが 同 時 に 発 生 した 場 合 どの 割 り 込 みを 優 先 させるか 設 定 し ます レベルの 高 い 割 り 込 みが 優 先 されます 割 り 込 みを 2 つ 以 上 使 う 場 2 ilvl2_trbic 合 どれを 優 先 させるかここで 決 めます 今 回 はタイマ RC 割 り 込 みを 7 タ イマ RD0 割 り 込 みを 6 タイマ RB 割 り 込 みを 5 に 設 定 します 0x05 000:レベル 0 ( 割 り 込 み 禁 止 ) 1 ilvl1_trbic 001:レベル 1 010:レベル 2 011:レベル 3 100:レベル 4 0 ilvl0_trbic 101:レベル 5 110:レベル 6 111:レベル 7 43

(5) タイマ RB 制 御 レジスタ(TRBCR:Timer RB Control Register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 2 tstop_trbcr "0"を 設 定 1 tcstf_trbcr "0"を 設 定 0 tstart_trbcr タイマ RB カウント 開 始 ビットを 設 定 します 0:カウント 停 止 1:カウント 開 始 0x01 5.2.8 タイマ RC の 設 定 348 : /* タイマRC PWMモード 設 定 ( 左 前 モータ 右 前 モータ ステアリンク モータ) */ 349 : trcpsr0 = 0x60; /* TRCIOA 端 子 =なし,B 端 子 =P6_5 */ 350 : trcpsr1 = 0x55; /* TRCIOC 端 子 =P6_6,D 端 子 =P6_7 */ 351 : trcmr = 0x0f; /* PWMモード 選 択 ビット 設 定 */ 352 : trccr1 = 0x8e; /* ソースカウント:f1, 初 期 出 力 の 設 定 */ 353 : trccr2 = 0x00; /* 出 力 レベルの 設 定 */ 354 : trcgra = TRC_MOTOR_CYCLE - 1; /* 周 期 設 定 */ 355 : trcgrb = trcgrb_buff = trcgra; /* P6_5 端 子 のON 幅 ( 右 前 モータ) */ 356 : trcgrc = trcgrc_buff = trcgra; /* P6_6 端 子 のON 幅 ( 右 後 モータ) */ 357 : trcgrd = trcgrd_buff = trcgra; /* P6_7 端 子 のON 幅 (ステアリンク モータ) */ 358 : trcic = 0x07; /* 割 り 込 み 優 先 レベル 設 定 */ 359 : trcier = 0x01; /* IMIAを 許 可 */ 360 : trcoer = 0x01; /* 出 力 端 子 の 選 択 */ 361 : trcmr = 0x80; /* TRCカウント 開 始 */ タイマ RC を 使 うと 同 一 周 期 の PWM 波 形 を 3 本 出 力 することができます ただし ON 幅 を 設 定 するタイミング によっては 波 形 が 乱 れる 場 合 がありますので プログラムで 対 処 が 必 要 です タイマ RC を 使 った PWM 波 形 出 力 の 代 表 的 な 様 子 を 下 図 に 示 します カウントソース TRC TRCGRA 比 較 器 A TRCGRB 比 較 器 B 波 形 制 御 TRCGRC 比 較 器 C PWM_B TRCIOB 端 子 P0_3,P0_4,P0_5,P1_2,P2_0,P6_5 の 1 端 子 を 選 択 TRCGRD 比 較 器 D PWM_C TRCIOC 端 子 P0_7,P1_3,P2_1,P3_4,P6_6 の 1 端 子 を 選 択 PWM_D TRCIOD 端 子 P0_6,P1_0,P2_2,P3_5,P6_7 の 1 端 子 を 選 択 44

今 回 の 設 定 をした PWM 波 形 が 出 力 される 様 子 を 下 図 に 示 します 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル カウントソース 50ns TRC TRCGRA =19999 一 致 で TRC クリア 比 較 器 A 1ms ごとに 割 り 込 み 発 生 TRCGRB 比 較 器 B TRCGRC 比 較 器 C TRCGRD 比 較 器 D =プログラムで ON 幅 を 設 定 波 形 制 御 PWM_B PWM_C PWM_D 1 周 期 =(TRCGRA+1) 50ns=1ms 左 前 モータ 制 御 P6_5 ON 幅 =(TRCGRB+1) 50ns 左 後 モータ 制 御 P6_6 ON 幅 =(TRCGRC+1) 50ns ステアリングモータ 制 御 P6_7 ON 幅 =(TRCGRD+1) 50ns (1) タイマ RC 端 子 選 択 レジスタ 0(TRCPSR0:Timer RC function select register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 trciobsel2 5 trciobsel1 4 trciobsel0 3 - "0"を 設 定 TRCIOB 端 子 選 択 ビットを 設 定 します 000:TRCIOB 端 子 は 使 用 しない 001:P1_2 に 割 り 当 てる 010:P0_3 に 割 り 当 てる 011:P0_4 に 割 り 当 てる 100:P0_5 に 割 り 当 てる 101:P2_0 に 割 り 当 てる 110:P6_5 に 割 り 当 てる 上 記 以 外 : 設 定 しないでください 0x60 2 1 trcioasel2 trcioasel1 TRCIOA/TRCTRG 端 子 選 択 ビットを 設 定 します 000:TRCIOA/TRCTRG 端 子 は 使 用 しない 001:P1_1 に 割 り 当 てる 010:P0_0 に 割 り 当 てる 0 trcioasel0 011:P0_1 に 割 り 当 てる 100:P0_2 に 割 り 当 てる 上 記 以 外 : 設 定 しないでください 45

(2) タイマ RC 端 子 選 択 レジスタ 1(TRCPSR1:Timer RC function select register 1)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 5 trciodsel2 trciodsel1 TRCIOD 端 子 選 択 ビットを 設 定 します 000:TRCIOD 端 子 は 使 用 しない 001:P1_0 に 割 り 当 てる 010:P3_5 に 割 り 当 てる 4 trciodsel0 011:P0_6 に 割 り 当 てる 100:P2_2 に 割 り 当 てる 101:P6_7 に 割 り 当 てる 3 - "0"を 設 定 0x55 2 1 trciocsel2 trciocsel1 TRCIOC 端 子 選 択 ビットを 設 定 します 000:TRCIOC 端 子 は 使 用 しない 001:P1_3 に 割 り 当 てる 010:P3_4 に 割 り 当 てる 0 trciocsel0 011:P0_7 に 割 り 当 てる 100:P2_1 に 割 り 当 てる 101:P6_6 に 割 り 当 てる (3) タイマ RC モードレジスタ(TRCMR:Timer RC mode register)の 設 定 ビット シンボル 説 明 設 定 値 7 6 tstart_trcmr - TRC カウント 開 始 ビットを 設 定 します 0:カウント 停 止 1:カウント 開 始 カウント 開 始 は 最 後 にします 今 回 は"0"を 設 定 します "0"を 設 定 5 bfd_trcmr TRCGRD レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRCGRB レジスタのバッファレジスタ 4 bfc_trcmr TRCGRC レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRCGRA レジスタのバッファレジスタ 3 pwm2_trcmr PWM2 モード 選 択 ビットを 設 定 します 0:PWM2 モード 1:タイマモードまたは PWM モード 0x0f 2 pwmd_trcmr 1 pwmc_trcmr 0 pwmb_trcmr TRCIOD PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード TRCIOC PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード TRCIOB PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード 46

(4) タイマ RC 制 御 レジスタ 1(TRCCR1:Timer RC control register 1)の 設 定 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル ビット シンボル 説 明 設 定 値 7 cclr_trccr1 "1"を 設 定 6 tck2_trccr1 5 tck1_trccr1 4 tck0_trccr1 3 tod_trccr1 2 toc_trccr1 1 tob_trccr1 0 toa_trccr1 "0"を 設 定 カウントソース 選 択 ビットを 設 定 します 000:f1 (1/20MHz=50ns) 001:f2 (2/20MHz=100ns) 010:f4 (4/20MHz=200ns) 011:f8 (8/20MHz=400ns) 100:f32 (32/20MHz=1600ns) 101:TRCCLK 入 力 の 立 ち 上 がりエッジ 110:fOCO40M ( 高 速 オンチップオシレータ 40MHz= 今 回 は 未 接 続 ) 111:fOCO-F ( 高 速 オンチップオシレータを FRA2 で 分 周 したクロック= 今 回 は 未 接 続 ) TRCIOD 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル TRCIOC 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル TRCIOB 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル 0x8e (5) タイマ RC 制 御 レジスタ 2(TRCCR2:Timer RC control register 2)の 設 定 ビット シンボル 説 明 設 定 値 7 tceg1_trccr2 "0"を 設 定 6 tceg0_trccr2 "0"を 設 定 5 cstp_trccr2 "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 PWM モードアウトプットレベル 制 御 ビット D を 設 定 します 2 pold_trccr2 0:TRCIOD の 出 力 レベルは L アクティブ 1:TRCIOD の 出 力 レベルは H アクティブ 0x00 1 polc_trccr2 PWM モードアウトプットレベル 制 御 ビット C を 設 定 します 0:TRCIOC の 出 力 レベルは L アクティブ 1:TRCIOC の 出 力 レベルは H アクティブ 0 polb_trccr2 PWM モードアウトプットレベル 制 御 ビット B を 設 定 します 0:TRCIOB の 出 力 レベルは L アクティブ 1:TRCIOB の 出 力 レベルは H アクティブ 47

(6) タイマ RC ジェネラルレジスタ A(TRCGRA:Timer RC General register A)の 設 定 ビット シンボル 説 明 設 定 値 TRCGRA は PWM 波 形 の 周 期 を 設 定 します 計 算 式 を 下 記 に 示 します TRCGRA=PWM 波 形 の 周 期 /タイマ RC カウンタのカウントソース-1 今 回 タイマ RC の PWM 波 形 の 周 期 は 1ms に 設 定 します タイマ RC カウ ンタのカウントソースは TRCCR1 で 設 定 した 50ns です よって TRCGRA=(1 10-3 )/(50 10-9 )-1 =20000-1 15~0 - となります プログラムでは define 文 を 使 って 28 : #define TRC_MOTOR_CYCLE 20000 /* 左 前, 右 前 モータ PWM の 周 期 */ 29 : /* 50[ns] * 20000 = 1.00[ms] */ とタイマ RC の PWM 波 形 の 周 期 を 記 号 定 数 で 設 定 しています よってプロ グラムでは 19999 354 : trcgra = TRC_MOTOR_CYCLE - 1; /* 周 期 設 定 */ としています (7) タイマ RC ジェネラルレジスタ B(TRCGRB:Timer RC General register B)の 設 定 ビット シンボル 説 明 設 定 値 TRCGRB は P6_5 端 子 の ON 幅 を 設 定 します 今 回 は 左 前 モータの PWM 波 形 の ON 幅 を 設 定 します 計 算 式 を 下 記 に 示 します TRCGRB=PWM 波 形 の ON 幅 /タイマ RC カウンタのカウントソース-1 ただし 設 定 によっては 下 記 のようになります 15~0-1TRCGRB の 値 を TRCGRA と 同 じ 値 にすると ON 幅 は 0%になる 2TRCGRB の 値 を (TRCGRA+1) 以 上 にすると ON 幅 は 100%になる 3TRCGRB を 設 定 するタイミングによっては ON 幅 100%の 波 形 が 1 周 期 出 力 されることがある 3は 1 周 期 ですがモータの 回 転 が 100%になり 問 題 です 設 定 するタイミン グについては 後 述 します ここではまだ ON 幅 は 0%にするので 1の TRCGRA と 同 じ 値 にします 19999 48

(8) タイマ RC ジェネラルレジスタ C(TRCGRC:Timer RC General register C)の 設 定 ビット シンボル 説 明 設 定 値 15~0 - TRCGRC は P6_6 端 子 の ON 幅 を 設 定 します 今 回 は 左 後 モータの PWM 波 形 の ON 幅 を 設 定 します 設 定 内 容 は TRCGRB と 同 じです ここではまだ ON 幅 は 0%にするので TRCGRA と 同 じ 値 にします 19999 (9) タイマ RC ジェネラルレジスタ D(TRCGRD:Timer RC General register D)の 設 定 ビット シンボル 説 明 設 定 値 15~0 - TRCGRD は P6_7 端 子 の ON 幅 を 設 定 します 今 回 は ステアリングモー タの PWM 波 形 の ON 幅 を 設 定 します 設 定 内 容 は TRCGRB と 同 じです ここではまだ ON 幅 は 0%にするので TRCGRA と 同 じ 値 にします 19999 (10) タイマ RC 割 り 込 み 制 御 レジスタ(TRCIC:Timer RC interrupt control register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 ir_trcic "0"を 設 定 他 の 割 り 込 みが 同 時 に 発 生 した 場 合 どの 割 り 込 みを 優 先 させるか 設 定 し ます レベルの 高 い 割 り 込 みが 優 先 されます 割 り 込 みを 2 つ 以 上 使 う 場 2 ilvl2_trcic 合 どれを 優 先 させるかここで 決 めます 今 回 はタイマ RC 割 り 込 みを 7 タ イマ RD0 割 り 込 みを 6 タイマ RB 割 り 込 みを 5 に 設 定 します 0x07 000:レベル 0 ( 割 り 込 み 禁 止 ) 1 ilvl1_trcic 001:レベル 1 010:レベル 2 011:レベル 3 100:レベル 4 0 ilvl0_trcic 101:レベル 5 110:レベル 6 111:レベル 7 49

(11) タイマ RC 割 り 込 み 許 可 レジスタ(TRCIER:Timer RC Interrupt Enable Register)の 設 定 ビット シンボル 説 明 設 定 値 7 ovie_trcier 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 imied_trcier 2 imiec_trcier 1 imieb_trcier オーバフロー 割 り 込 み 許 可 ビットを 設 定 します 0:OVF ビットによる 割 り 込 み(OVI) 禁 止 1:OVF ビットによる 割 り 込 み(OVI) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット D を 設 定 します 0:IMFD ビットによる 割 り 込 み(IMID) 禁 止 1:IMFD ビットによる 割 り 込 み(IMID) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット C を 設 定 します 0:IMFC ビットによる 割 り 込 み(IMIC) 禁 止 1:IMFC ビットによる 割 り 込 み(IMIC) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット B を 設 定 します 0:IMFB ビットによる 割 り 込 み(IMIB) 禁 止 1:IMFB ビットによる 割 り 込 み(IMIB) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット A を 設 定 します 0:IMFA ビットによる 割 り 込 み(IMIB) 禁 止 1:IMFA ビットによる 割 り 込 み(IMIB) 許 可 0x01 0 imiea_trcier TRC と TRCGRA の 値 が 一 致 したら 割 り 込 みを 発 生 させます TRCGRA は PMW 波 形 の 周 期 を 設 定 しているので 今 回 は 1ms ごとに 割 り 込 みが 発 生 することになります タイマ RC の 割 り 込 みプログラムでの 処 理 内 容 は 後 述 します (12) タイマ RC アウトプットマスタ 許 可 レジスタ(TRCOER:Timer RC output master enable register)の 設 定 ビット シンボル 説 明 設 定 値 7 pto_trcoer "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 ed_trcoer TRCIOD 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 (P6_7 端 子 を PWM 出 力 にする) 1: 出 力 禁 止 (TRCIOD 端 子 はプログラマブル 入 出 力 ポート) TRCIOC 出 力 禁 止 ビットを 設 定 します 2 ec_trcoer 0: 出 力 許 可 (P6_6 端 子 を PWM 出 力 にする) 0x01 1: 出 力 禁 止 (TRCIOC 端 子 はプログラマブル 入 出 力 ポート) 1 eb_trcoer TRCIOB 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 (P6_5 端 子 を PWM 出 力 にする) 1: 出 力 禁 止 (TRCIOB 端 子 はプログラマブル 入 出 力 ポート) 0 ea_trcoer TRCIOA 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRCIOA 端 子 はプログラマブル 入 出 力 ポート) 50

(13) タイマ RC モードレジスタ(TRCMR:Timer RC mode register)の 設 定 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル ビット シンボル 説 明 設 定 値 7 tstart_trcmr 6 - 変 更 せず 5 bfd_trcmr 変 更 せず 4 bfc_trcmr 変 更 せず 3 pwm2_trcmr 変 更 せず 2 pwmd_trcmr 変 更 せず 1 pwmc_trcmr 変 更 せず 0 pwmb_trcmr 変 更 せず TRC カウント 開 始 ビットを 設 定 します 0:カウント 停 止 1:カウント 開 始 0x80 で OR (14) 出 力 されるタイミングと 初 期 出 力 アクティブレベルについて タイマ RC 制 御 レジスタ 1(TRCCR1)の 初 期 出 力 を 設 定 するビット(bit3~1)と タイマ RC 制 御 レジスタ 2(TRCCR2) のアクティブレベルを 設 定 するビット(bit2~0)の 関 係 を 下 図 に 示 します TRCCR1 bit3~1 0 初 期 は アクティブで ないレベル 0 初 期 は アクティブで ないレベル 1 初 期 は アクティブな レベル TRCCR2 bit2~0 0 出 力 レベルは "L"アクティブ 1 出 力 レベルは "H"アクティブ 0 出 力 レベルは "L"アクティブ 出 力 波 形 ポートに 出 力 している 値 波 形 TRCMR の bit7="1" (カウント 開 始 ) TRCOER で 出 力 許 可 出 力 波 形 ポートに 出 力 している 値 TRCMR の bit7="1" (カウント 開 始 ) TRCOER で 出 力 許 可 出 力 波 形 ポートに 出 力 している 値 TRCMR の bit7="1" (カウント 開 始 ) TRCOER で 出 力 許 可 1 周 期 目 2 周 期 目 1 周 期 目 2 周 期 目 1 周 期 目 2 周 期 目 51

1 初 期 は アクティブな レベル 1 出 力 レベルは "H"アクティブ 出 力 波 形 ポートに 出 力 している 値 TRCOER で 出 力 許 可 1 周 期 目 2 周 期 目 TRCMR の bit7="1" (カウント 開 始 ) 今 回 の 設 定 は 初 期 はアクティブなレベル 出 力 レベルは"L"アクティブ にしています (15) PWM 波 形 P6_5 端 子 の PWM 波 形 の 様 子 を 例 に 各 レジスタの 値 について 下 図 に 示 します TRC 19999 TRCが 2000 のときに TRCGRB の 値 を 999 に 変 更 TRCGRA= 19999 TRCGRB= 2499 1 2 2 2000 3 TRCSTR bit0 TRCIOB 端 子 (P6_5) 0 "1" "0" "1" "0" 1 時 間 1 周 期 100%になってしまう!! 1 2 3 1TRC=TRCGRB+1 になった 瞬 間 出 力 波 形 は"0"になります 2TRC=TRCGRA+1 になった 瞬 間 "1"になります TRC はこのタイミングで 0 になります PWM 波 形 は 1と2を 繰 り 返 すことにより PWM 波 形 が 出 力 されます ON 幅 を 変 えるときは プログラムで TRCGRB の 値 を 変 えます 例 えば 3のように TRC の 値 が 2000 の とき TRCGRB の 値 を 999 に 変 えた 場 合 1の 波 形 が"0"になるタイミングがなく 1 周 期 100%の 波 形 が 出 力 されてしまいます そこで trcgrb_buff という 変 数 を 作 り プログラムでは trcgrb_buff 変 数 の 値 を 変 更 して TRCGRB の 値 は 直 接 変 更 しません 2のタイミングで 割 り 込 みが 発 生 するようにして 割 り 込 みプログラム 内 で trcgrb_buff 変 数 の 値 を TRCGRB へ 代 入 するようにします TRCGRC TRCGRD も 同 様 です 52

割 り 込 みプログラムを 下 記 に 示 します 447 : /************************************************************************/ 448 : /* タイマRC 割 り 込 み 処 理 */ 449 : /************************************************************************/ 450 : #pragma interrupt /B inttrc(vect=7) 451 : void inttrc( void ) 452 : { 453 : /* タイマRC デューティ 比 の 設 定 */ 454 : trcgrd = trcgrd_buff; /* ステアリンク モータ PWMセット */ 455 : trcgrb = trcgrb_buff; /* 右 前 モータ PWMセット */ 456 : trcgrc = trcgrc_buff; /* 右 後 モータ PWMセット */ 457 : 458 : imfa_trcsr = 0; 459 : } 割 り 込 みプログラムの 処 理 を 含 めた P6_5 端 子 の PWM 波 形 の 様 子 を 下 図 に 示 します TRCGRA= 19999 TRCGRB=2499 trcgrb_buff=2499 2000 TRC 割 り 込 み 発 生 割 り 込 み 発 生 19999 ここで trcgrb_buff の 値 を 999 に 変 更 2 割 り 込 みプログラム 内 で TRCGRB の 値 を trcgrb_buff の 値 (999)に 変 更 3 5 1 TRCSTR bit0 0 "1" "0" 4 時 間 TRCIOB 端 子 (P6_5) "1" "0" 1 2 3 4 5 プログラムでは TRCGRB の 値 ではなく trcgrb_buff 変 数 の 値 を 変 えます TRCGRB の 値 は 変 わっていないため TRC=TRCGRB+1 になり 波 形 は"0"になります タイマ RC の 割 り 込 みプログラム 内 で trcgrb_buff 変 数 を TRCGRB に 代 入 します TRC=TRCGRB+1 になり 波 形 は"0"になります 割 り 込 みは TRC=TRCGRA+1 になった 瞬 間 にかかりますが 下 記 の 理 由 により 代 入 は 若 干 遅 れます 現 在 実 行 している 命 令 (アセンブリ 言 語 レベル)が 終 わるまでに 数 百 ns~ 数 μs の 時 間 がかかります 割 り 込 み 関 数 を 実 行 するまでに 数 μ 秒 の 時 間 がかかります プログラムを 実 行 するのに 数 百 ns~ 数 μs の 時 間 がかかります 例 えば 452 行 を 実 行 する 時 点 で TRC が 500 trcgrb_buff が 200 の 場 合 TRCGRB に 200 を 代 入 しても TRC=TRCGRB+1 が 起 こらず 1 周 期 100%の PWM 波 形 が 出 力 されてしまいます そのため trcgrb_buff 変 数 には 1000 以 上 (5% 以 上 )の 値 を 代 入 してください 0%にするときは TRCGRB に TRCGRA の 値 を 代 入 してください ただし ステアリングモータは マイコンカー 制 御 の 要 なので 400 以 上 (2% 以 上 )として ぎりぎりまで 細 かい 値 を 設 定 できるようにしています 53

5.2.9 タイマ RD0 の 設 定 363 : /* タイマRD0 リセット 同 期 PWMモード 設 定 ( 左 後 モータ 右 後 モータ) */ 364 : trdpsr0 = 0x28; /* TRDIOB0=P2_2,C0=P2_1,D0=なし */ 365 : trdmr = 0x00; /* レジスタは 独 立 動 作 */ 366 : trdpmr = 0x07; /* PWM 端 子 設 定 B0,C0をPMW 端 子 に */ 367 : trdfcr = 0x80; /* アウトフ ットコンヘ ア 機 能 に 設 定 */ 368 : trdcr0 = 0x20; /* ソースカウントの 選 択 :f1 */ 369 : trdgra0 = TRD_MOTOR_CYCLE - 1; /* 周 期 設 定 */ 370 : trdgrb0 = trdgrb0_buff = trdgra0; /* P2_2 端 子 のON 幅 ( 右 後 モータ) */ 371 : trdgrc0 = trdgrc0_buff = trdgra0; /* P2_1 端 子 のON 幅 ( 右 前 モータ) */ 372 : imiea_trdier0 = 1; /* IMFAビットによる 割 り 込 み 許 可 */ 373 : trd0ic = 0x06; /* 割 り 込 み 優 先 レベル 設 定 */ 374 : polb_trdpocr0 = 0; /* TRDIOB0 端 子 出 力 レヘ ルは"L"アクテ ィフ */ 375 : polc_trdpocr0 = 0; /* TRDIOC0 端 子 出 力 レヘ ルは"L"アクテ ィフ */ 376 : tob0_trdocr = 1; /* TRDIOB0 端 子 初 期 はアクテ ィフ レヘ ル*/ 377 : toc0_trdocr = 1; /* TRDIOC0 端 子 初 期 はアクテ ィフ レヘ ル*/ 378 : trdoer1 = 0xf9; /* 出 力 端 子 の 選 択 */ 379 : tstart0_trdstr= 1; /* TRD0カウント 開 始 */ タイマ RD0 を 使 うと 同 一 周 期 の PWM 波 形 を 3 本 出 力 することができます ただし ON 幅 を 設 定 するタイミング によっては 波 形 が 乱 れる 場 合 がありますので プログラムで 対 処 が 必 要 です タイマ RD0 を 使 った PWM 波 形 出 力 の 代 表 的 な 様 子 を 下 図 に 示 します カウントソース TRD0 TRDGRA0 比 較 器 A TRDGRB0 比 較 器 B 波 形 制 御 TRDGRC0 比 較 器 C PWM_B TRDIOB0 端 子 P2_2 TRDGRD0 比 較 器 D PWM_C TRDIOC0 端 子 P2_1 PWM_D TRDIOD0 端 子 P2_0 54

今 回 の 設 定 をした PWM 波 形 が 出 力 される 様 子 を 下 図 に 示 します 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル カウントソース 50ns TRD0 TRDGRA0 =19999 一 致 で TRD0 クリア 比 較 器 A 1ms ごとに 割 り 込 み 発 生 TRDGRB0 比 較 器 B TRDGRC0 比 較 器 C TRDGRD0 比 較 器 D =プログラムで ON 幅 を 設 定 波 形 制 御 PWM_B PWM_C PWM_D 1 周 期 =(TRDGRA0+1) 50ns=1ms 右 後 モータ 制 御 P2_2 ON 幅 =(TRDGRB0+1) 50ns 右 前 モータ 制 御 P2_1 ON 幅 =(TRDGRC0+1) 50ns 今 回 は 未 使 用 P2_0 ON 幅 =(TRDGRD0+1) 50ns (1) タイマ RD 端 子 選 択 レジスタ 0(TRDPSR0:Timer RD function select register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 trdiod0sel0 TRDIOD0 端 子 選 択 ビットを 設 定 します 0:TRDIOD0 端 子 は 使 用 しない 1:P2_3 に 割 り 当 てる 5 trdioc0sel1 TRDIOC0 端 子 選 択 ビットを 設 定 します 00:TRDIOC0 端 子 は 使 用 しない 01: 設 定 しないでください 4 trdioc0sel0 10:P2_1 に 割 り 当 てる 11: 設 定 しないでください TRDIOB0 端 子 選 択 ビットを 設 定 します 3 trdiob0sel1 00:TRDIOB0 端 子 は 使 用 しない 0x28 01: 設 定 しないでください 2 trdiob0sel0 10:P2_2 に 割 り 当 てる 11: 設 定 しないでください 1 - "0"を 設 定 0 trdioa0sel0 TRDIOA0/TRDCLK 端 子 選 択 ビットを 設 定 します 0:TRDIOA0/TRDCLK 端 子 は 使 用 しない 1:P2_0 に 割 り 当 てる 55

(2) タイマ RD モードレジスタ(TRDMR:Timer RD mode register)の 設 定 ビット シンボル 説 明 設 定 値 7 bfd1_trdmr 6 bfc1_trdmr 5 bfd0_trdmr 4 bfc0_trdmr 3 - "0"を 設 定 2 - "0"を 設 定 1 - "0"を 設 定 0 sync_trdmr TRDGRD1 レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRDGRB1 レジスタのバッファレジスタ TRDGRC1 レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRDGRA1 レジスタのバッファレジスタ TRDGRD0 レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRDGRB0 レジスタのバッファレジスタ TRDGRC0 レジスタ 機 能 選 択 ビットを 設 定 します 0:ジェネラルレジスタ 1:TRDGRA0 レジスタのバッファレジスタ タイマ RD 同 期 ビットを 設 定 します 0:TRD0 と TRD1 は 独 立 動 作 1:TRD0 と TRD1 は 同 期 動 作 0x00 (3) タイマ RD PWM モードレジスタ(TRDPMR:Timer RD PWM mode register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 TRDIOD1 PWM モード 選 択 ビットを 設 定 します 6 pwmd1_trdpmr 0:タイマモード 1:PWM モード TRDIOC1 PWM モード 選 択 ビットを 設 定 します 5 pwmc1_trdpmr 0:タイマモード 1:PWM モード 4 pwmb1_trdpmr TRDIOB1 PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード 3 - "0"を 設 定 2 pwmd0_trdpmr TRDIOD0 PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード 1 pwmc0_trdpmr TRDIOC0 PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード 0 pwmb0_trdpmr TRDIOB0 PWM モード 選 択 ビットを 設 定 します 0:タイマモード 1:PWM モード 0x07 56

(4) タイマ RD 機 能 制 御 レジスタ(TRDFCR:Timer RD function control register)の 設 定 ビット シンボル 説 明 設 定 値 7 pwm3_trdfcr 6 stclk_trdfcr 5 - "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 2 - "0"を 設 定 PWM3 モード 選 択 ビットを 設 定 します "1"を 設 定 "1"は PWM3 モードが 無 効 になる 設 定 です 外 部 クロック 入 力 選 択 ビットを 設 定 します 0: 外 部 クロック 入 力 無 効 1: 外 部 クロック 入 力 有 効 1 cmd1_trdfcr コンビネーションモード 選 択 ビットを 設 定 します PWM モードでは 00 (タイマモード PWM モード PWM3 モード)にしてくだ 0 cmd0_trdfcr さい 0x80 (5) タイマ RD 制 御 レジスタ 0(TRDCR0:Timer RD control register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 6 5 cclr2_trdcr0 cclr1_trdcr0 cclr0_trdcr0 TRD0 カウンタクリア 選 択 ビットを 設 定 します PWM モードの 場 合 は "001"(TRDGRA0 とのコンペア 一 致 で TRD0 レジス タクリア)に 設 定 4 ckeg1_trdcr0 3 ckeg0_trdcr0 2 tck2_trdcr0 1 tck1_trdcr0 0 tck0_trdcr0 外 部 クロックエッジ 選 択 ビット( 注 3)を 設 定 します 00: 立 ち 上 がりエッジでカウント 01: 立 ち 下 がりエッジでカウント 10: 両 エッジでカウント 11: 設 定 しないでください 今 回 は 外 部 クロックを 使 わないので "11" 以 外 のどれかを 設 定 します カウントソース 選 択 ビットを 設 定 します 000:f1 (1/20MHz=50ns) 001:f2 (2/20MHz=100ns) 010:f4 (4/20MHz=200ns) 011:f8 (8/20MHz=400ns) 100:f32 (32/20MHz=1600ns) 101:TRDCLK 入 力 ( 注 1)または fc2 ( 注 2) fc2 = 2/XCIN クロック= 今 回 は 未 接 続 110:fOCO40M ( 高 速 オンチップオシレータ 40MHz= 今 回 は 未 接 続 ) 111:fOCO-F( 注 4) ( 高 速 オンチップオシレータを FRA2 で 分 周 したクロック = 今 回 は 未 接 続 ) 注 1. TRDECR レジスタの ITCLK0 ビットが 0 (TRDCLK 入 力 )かつ TRDFCR レジスタの STCLK ビットが 1 ( 外 部 クロック 入 力 有 効 )のとき 有 効 です 注 2. タイマモードで TRDECR レジスタの ITCLK0 ビットが 1 (fc2)のとき 有 効 です 注 3. TCK2~TCK0 ビットが 101 (TRDCLK 入 力 または fc2) TRDECR レジスタの ITCLK0 ビットが 0 (TRDCLK 入 力 ) かつ TRDFCR レジスタの STCLK ビットが 1 ( 外 部 クロック 入 力 有 効 )のとき 有 効 です 注 4. foco-f を 選 択 するとき CPU クロックより 速 いクロック 周 波 数 に foco-f を 設 定 してください 0x20 57

(6) タイマ RD ジェネラルレジスタ A0(TRDGRA0:Timer RD General register A0)の 設 定 ビット シンボル 説 明 設 定 値 TRDGRA0 は PWM 波 形 の 周 期 を 設 定 します 計 算 式 を 下 記 に 示 しま す TRDGRA0=PWM 波 形 の 周 期 /タイマ RD0 カウンタのカウントソース-1 今 回 タイマ RD0 の PWM 波 形 の 周 期 は 1ms に 設 定 します タイマ RD0 カウンタのカウントソースは TRDCR0 で 設 定 した 50ns です よって TRDGRA0=(1 10-3 )/(50 10-9 )-1 =20000-1 15~0 - となります プログラムでは define 文 を 使 って 30 : #define TRD_MOTOR_CYCLE 20000 /* 左 後, 右 後,サーホ モータ PWM の 周 期 */ 31 : /* 50[ns] * 20000 = 1.00[ms] */ 19999 とタイマ RD0 の PWM 波 形 の 周 期 を 記 号 定 数 で 設 定 しています よってプ ログラムでは 369 : trdgra0 = TRD_MOTOR_CYCLE - 1; /* 周 期 設 定 */ としています (7) タイマ RD ジェネラルレジスタ B0(TRDGRB0:Timer RD General register B0)の 設 定 ビット シンボル 説 明 設 定 値 TRDGRB0 は P2_2 端 子 の ON 幅 を 設 定 します 今 回 は 右 後 モータの PWM 波 形 の ON 幅 を 設 定 します 計 算 式 を 下 記 に 示 します TRDGRB0=PWM 波 形 の ON 幅 /タイマ RC カウンタのカウントソース-1 ただし 設 定 によっては 下 記 のようになります 15~0-1TRDGRB0 の 値 を TRDGRA0 と 同 じ 値 にすると ON 幅 は 0%になる 2TRDGRB0 の 値 を (TRDGRA0+1) 以 上 にすると ON 幅 は 100%になる 3TRDGRB0 を 設 定 するタイミングによっては ON 幅 100%の 波 形 が 1 周 期 出 力 されることがある 3は 1 周 期 ですがモータの 回 転 が 100%になり 問 題 です 設 定 するタイミン グについては 後 述 します ここではまだ ON 幅 は 0%にするので 1の TRDGRA0 と 同 じ 値 にします 19999 58

(8) タイマ RD ジェネラルレジスタ C0(TRDGRC0:Timer RD General register C0)の 設 定 ビット シンボル 説 明 設 定 値 15~0 - TRDGRC0 は P2_1 端 子 の ON 幅 を 設 定 します 今 回 は 右 前 モータの PWM 波 形 の ON 幅 を 設 定 します 設 定 内 容 は TRDGRB0 と 同 じです ここではまだ ON 幅 は 0%にするので TRDGRA0 と 同 じ 値 にします 19999 (9) タイマ RD 割 り 込 み 許 可 レジスタ 0(TRDIER0:Timer RD interrupt enable register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 オーバフロー/アンダフロー 割 り 込 み 許 可 ビットを 設 定 します 4 ovie_trdier0 0:OVF ビットによる 割 り 込 み(OVI) 禁 止 1:OVF ビットによる 割 り 込 み(OVI) 許 可 3 imied_trdier0 2 imiec_trdier0 1 imieb_trdier0 0 imiea_trdier0 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット D を 設 定 します 0:IMFD ビットによる 割 り 込 み(IMID) 禁 止 1:IMFD ビットによる 割 り 込 み(IMID) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット C を 設 定 します 0:IMFC ビットによる 割 り 込 み(IMIC) 禁 止 1:IMFC ビットによる 割 り 込 み(IMIC) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット B を 設 定 します 0:IMFB ビットによる 割 り 込 み(IMIB) 禁 止 1:IMFB ビットによる 割 り 込 み(IMIB) 許 可 インプットキャプチャ/コンペア 一 致 割 り 込 み 許 可 ビット A を 設 定 します 0:IMFA ビットによる 割 り 込 み(IMIA) 禁 止 1:IMFA ビットによる 割 り 込 み(IMIA) 許 可 bit0= "1" (10) タイマ RD0 割 り 込 み 制 御 レジスタ(TRD0IC:Timer RD0 interrupt control register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 ir_trd0ic "0"を 設 定 他 の 割 り 込 みが 同 時 に 発 生 した 場 合 どの 割 り 込 みを 優 先 させるか 設 定 し ます レベルの 高 い 割 り 込 みが 優 先 されます 割 り 込 みを 2 つ 以 上 使 う 場 2 ilvl2_trd0ic 合 どれを 優 先 させるかここで 決 めます 今 回 はタイマ RC 割 り 込 みを 7 タ イマ RD0 割 り 込 みを 6 タイマ RB 割 り 込 みを 5 に 設 定 します 0x06 000:レベル 0 ( 割 り 込 み 禁 止 ) 1 ilvl1_trd0ic 001:レベル 1 010:レベル 2 011:レベル 3 100:レベル 4 0 iilvl0_trd0ic 101:レベル 5 110:レベル 6 111:レベル 7 59

(11) タイマ RD PWM モードアウトプットレベル 制 御 レジスタ 0(TRDPOCR0:Timer RD PWM mode output level control register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 2 pold_trdpocr0 1 polc_trdpocr0 0 polb_trdpocr0 PWM モードアウトプットレベル 制 御 ビット D を 設 定 します 0:TRDIOD0 の 出 力 レベルは L アクティブ 1:TRDIOD0 の 出 力 レベルは H アクティブ PWM モードアウトプットレベル 制 御 ビット C を 設 定 します 0:TRDIOC0 の 出 力 レベルは L アクティブ 1:TRDIOC0 の 出 力 レベルは H アクティブ PWM モードアウトプットレベル 制 御 ビット B を 設 定 します 0:TRDIOB0 の 出 力 レベルは L アクティブ 1:TRDIOB0 の 出 力 レベルは H アクティブ bit1="0" bit0="0" (12) タイマ RD アウトプット 制 御 レジスタ(TRDOCR:Timer RD output control register)の 設 定 ビット シンボル 説 明 設 定 値 7 tod1_trdocr TRDIOD1 初 期 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル TRDIOC1 初 期 出 力 レベル 選 択 ビットを 設 定 します 6 toc1_trdocr 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル 5 tob1_trdocr TRDIOB1 初 期 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル 4 - "0"を 設 定 3 tod0_trdocr TRDIOD0 初 期 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル bit2="1" bit1="1" 2 toc0_trdocr TRDIOC0 初 期 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル 1 tob0_trdocr TRDIOB0 初 期 出 力 レベル 選 択 ビットを 設 定 します 0: 初 期 出 力 はアクティブでないレベル 1: 初 期 出 力 はアクティブレベル 0 - "0"を 設 定 60

(13) タイマ RD アウトプットマスタ 許 可 レジスタ 1(TRDOER1:Timer RD output master enable register 1)の 設 定 ビット シンボル 説 明 設 定 値 7 ed1_trdoer1 TRDIOD1 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOD1 端 子 はプログラマブル 入 出 力 ポート) 6 ec1_trdoer1 TRDIOC1 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOC1 端 子 はプログラマブル 入 出 力 ポート) 5 eb1_trdoer1 4 - "1"を 設 定 3 ed0_trdoer1 2 ec0_trdoer1 TRDIOB1 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOB1 端 子 はプログラマブル 入 出 力 ポート) TRDIOD0 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOD0 端 子 はプログラマブル 入 出 力 ポート) TRDIOC0 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOC0 端 子 はプログラマブル 入 出 力 ポート) 0xf9 TRDIOC0 を 出 力 許 可 に 設 定 すると P2_1 端 子 から PWM 信 号 が 出 力 され ます 1 eb0_trdoer1 TRDIOB0 出 力 禁 止 ビットを 設 定 します 0: 出 力 許 可 1: 出 力 禁 止 (TRDIOB0 端 子 はプログラマブル 入 出 力 ポート) 0 - "1"を 設 定 TRDIOB0 を 出 力 許 可 に 設 定 すると P2_2 端 子 から PWM 信 号 が 出 力 され ます (14) タイマ RD スタートレジスタ(TRDSTR:Timer RD start register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 TRD1 カウント 動 作 選 択 ビットを 設 定 します 3 csel1_trdstr 0:TRDGRA1 レジスタとのコンペア 一 致 でカウント 停 止 1:TRDGRA1 レジスタとのコンペア 一 致 後 もカウント 継 続 2 csel0_trdstr TRD0 カウント 動 作 選 択 ビットを 設 定 します 0:TRDGRA0 レジスタとのコンペア 一 致 でカウント 停 止 1:TRDGRA0 レジスタとのコンペア 一 致 後 もカウント 継 続 bit0= "1" 1 tstart1_trdstr 0 tstart0_trdstr TRD1 カウント 開 始 フラグを 設 定 します 0:カウント 停 止 1:カウント 開 始 TRD0 カウント 開 始 フラグを 設 定 します 0:カウント 停 止 1:カウント 開 始 61

(15) 出 力 されるタイミングと 初 期 出 力 アクティブレベルについて タイマ RD アウトプット 制 御 レジスタ(TRDOCR)の 初 期 出 力 を 設 定 するビット(bit3~1)と タイマ RD PWM モードア ウトプットレベル 制 御 レジスタ 0(TRDPOCR0)のアクティブレベルを 設 定 するビット(bit2~0)の 関 係 を 下 図 に 示 しま す TRDOCR bit3~1 0 初 期 は アクティブで ないレベル 0 初 期 は アクティブで ないレベル 1 初 期 は アクティブな レベル 1 初 期 は アクティブな レベル TRDPOCR0 bit2~0 0 出 力 レベルは "L"アクティブ 1 出 力 レベルは "H"アクティブ 0 出 力 レベルは "L"アクティブ 1 出 力 レベルは "H"アクティブ 波 形 ポートに 出 力 している 値 1 周 期 目 2 周 期 目 出 力 波 形 TRDSTR の bit0="1" (カウント 開 始 ) TRDOER1 で 出 力 許 可 ポートに 出 力 している 値 1 周 期 目 2 周 期 目 出 力 波 形 TRDSTR の bit0="1" (カウント 開 始 ) TRDOER1 で 出 力 許 可 ポートに 出 力 している 値 1 周 期 目 2 周 期 目 出 力 波 形 TRDSTR の bit0="1" (カウント 開 始 ) TRDOER1 で 出 力 許 可 ポートに 出 力 している 値 1 周 期 目 2 周 期 目 出 力 波 形 TRDSTR の bit0="1" (カウント 開 始 ) TRDOER1 で 出 力 許 可 今 回 の 設 定 は 初 期 はアクティブなレベル 出 力 レベルは"L"アクティブ にしています 62

(16) PWM 波 形 P2_2 端 子 の PWM 波 形 の 様 子 を 例 に 各 レジスタの 値 について 下 図 に 示 します TRDGRA0= 19999 TRDGRB0= 2499 TRD0 1 19999 2 TRD0 が 2000 のときに TRDGRB0 の 値 を 999 に 変 更 2 2000 3 TRDSTR bit0 0 "1" "0" 1 時 間 TRDIOB0 端 子 (P2_2) "1" "0" 1 周 期 100%になってしまう!! 1 2 3 1TRD0=TRDGRB0+1 になった 瞬 間 出 力 波 形 は"0"になります 2TRD0=TRDGRA0+1 になった 瞬 間 "1"になります TRD0 はこのタイミングで 0 になります PWM 波 形 は 下 記 の1と2を 繰 り 返 すことにより PWM 波 形 が 出 力 されます ON 幅 を 変 えるときは プログラムで TRDGRB0 の 値 を 変 えます このとき 図 3のように TRDGRB0 の 値 を 変 えてしまった 場 合 1の 波 形 が"0"になるタイミングがなく 1 周 期 100%の 波 形 が 出 力 されてしまいま す そこで trdgrb0_buff という 変 数 を 作 り プログラムでは trdgrb0_buff 変 数 の 値 を 変 更 して TRDGRB0 の 値 は 直 接 変 更 しません 2のタイミングで 割 り 込 みが 発 生 するようにして 割 り 込 みプログラム 内 で trdgrb0_buff 変 数 の 値 を TRDGRB0 へ 代 入 するようにします TRDGRC0 も 同 様 です 63

割 り 込 みプログラムを 下 記 に 示 します 459 : /************************************************************************/ 460 : /* タイマRD0 割 り 込 み 処 理 タイマ RD0 割 り 込 み 処 理 実 行 中 に タイマ RD0 */ 割 り 込 み 461 : /************************************************************************/ 処 理 より 優 先 順 位 の 高 い 割 り 込 みが 発 生 した 場 合 その 462 : #pragma interrupt inttrd0(vect=8) 463 : void inttrd0( void ) 割 り 込 み 処 理 に 移 ります 今 回 は タイマ RC 割 り 込 みが 発 生 した 場 合 タイマ RC 割 り 込 みに 移 ります 464 : { 465 : asm(" fset I "); /* タイマRD0 以 上 の 割 り 込 み 許 可 */ 466 : 467 : /* タイマRD0 デューティ 比 の 設 定 */ 468 : trdgrb0 = trdgrb0_buff; /* 左 前 モータ PWMセット */ 469 : trdgrc0 = trdgrc0_buff; /* 左 後 モータ PWMセット */ 470 : 471 : imfa_trdsr0 = 0; 472 : } 割 り 込 みプログラムの 処 理 を 含 めた P2_2 端 子 の PWM 波 形 の 様 子 を 下 図 に 示 します TRDGRA0= 19999 TRDGRB0=2499 trdgrb0_buff=2499 TRD0 割 り 込 み 発 生 割 り 込 み 発 生 19999 ここで trdgrb0_buff の 値 を 999 に 変 更 2 割 り 込 みプログラム 内 で TRDGRB0 の 値 を trdgrb0_buff の 値 (999)に 変 更 3 2000 5 1 TRDSTR bit0 0 "1" "0" 4 時 間 TRDIOB0 端 子 (P2_2) "1" "0" 1 2 3 4 5 プログラムでは TRDGRB0 の 値 ではなく trdgrb0_buff 変 数 の 値 を 変 えます TRDGRB0 の 値 は 変 わっていないため TRD0=TRDCGRB0+1 になり 波 形 は"0"になります タイマ RD0 の 割 り 込 みプログラム 内 で trdgrb0_buff 変 数 を TRDGRB0 に 代 入 します TRD0=TRDGRB0+1 になり 波 形 は"0"になります 割 り 込 みは TRD0=TRDGRA0+1 になった 瞬 間 にかかりますが 下 記 の 理 由 により 代 入 は 若 干 遅 れます 現 在 実 行 している 命 令 (アセンブリ 言 語 レベル)が 終 わるまでに 数 百 ns~ 数 μs の 時 間 がかかります 割 り 込 み 関 数 を 実 行 するまでに 数 μ 秒 の 時 間 がかかります プログラムを 実 行 するのに 数 百 ns~ 数 μs の 時 間 がかかります 例 えば 468 行 を 実 行 する 時 点 で TRD0 が 500 trdgrb0_buff が 200 の 場 合 TRDGRB0 に 200 を 代 入 し ても TRD0=TRDGRB0+1 が 起 こらず 1 周 期 100%の PWM 波 形 が 出 力 されてしまいます そのため trdgrb0_buff 変 数 には 1000 以 上 (5% 以 上 )の 値 を 代 入 してください 0%にするときは TRDGRB0 に TRDGRA0 の 値 を 代 入 してください 64

5.2.10 タイマ RD1 の 設 定 381 : /* タイマRD1 外 部 入 力 (ロータリエンコーダのパルスカウント) */ 382 : trdioa0sel0 = 1; /* TRDCLK 端 子 :P2_0に 設 定 */ 383 : stclk_trdfcr = 1; /* 外 部 クロック 入 力 有 効 に 設 定 */ 384 : trdcr1 = 0x15; /* TRDCLK 端 子 両 エッジカウント */ 385 : tstart1_trdstr= 1; /* TRD1カウント 開 始 */ タイマ RD1 を 外 部 クロック 入 力 にして ロータリエンコーダのパルスを 入 力 します 今 回 のタイマ RD1 の 設 定 を 下 図 に 示 します タイマ RD1 タイマ RD 制 御 レジスタ 1 bit2~0 ロータリエンコーダの パルス P2_0 f1(50ns) f2(100ns) f4(200ns) f8(400ns) f32(1600ns) TRD1 TRDCLK 端 子 (1) タイマ RD 端 子 選 択 レジスタ 0(TRDPSR0:Timer RD function select register 0)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 TRDIOD0 端 子 選 択 ビットを 設 定 します 6 trdiod0sel0 0:TRDIOD0 端 子 は 使 用 しない 1:P2_3 に 割 り 当 てる 5 trdioc0sel1 4 trdioc0sel0 TRDIOC0 端 子 選 択 ビットを 設 定 します 00:TRDIOC0 端 子 は 使 用 しない 01: 設 定 しないでください 10:P2_1 に 割 り 当 てる 11: 設 定 しないでください 3 2 trdiob0sel1 trdiob0sel0 TRDIOB0 端 子 選 択 ビットを 設 定 します 00:TRDIOB0 端 子 は 使 用 しない 01: 設 定 しないでください 10:P2_2 に 割 り 当 てる 11: 設 定 しないでください 1 - "0"を 設 定 0 trdioa0sel0 TRDIOA0/TRDCLK 端 子 選 択 ビットを 設 定 します 0:TRDIOA0/TRDCLK 端 子 は 使 用 しない 1:P2_0 に 割 り 当 てる ここでは P2_0 端 子 を TRDIOA0 出 力 端 子 /TRDCLK 入 力 端 子 します ど ちらの 機 能 にするかは この 後 で 設 定 します bit0= "1" 65

(2) タイマ RD 機 能 制 御 レジスタ(TRDFCR:Timer RD function control register)の 設 定 ビット シンボル 説 明 設 定 値 7 pwm3_trdfcr 6 stclk_trdfcr PWM3 モード 選 択 ビットを 設 定 します "1"を 設 定 "1"は PWM3 モードが 無 効 になる 設 定 です 外 部 クロック 入 力 選 択 ビットを 設 定 します 0: 外 部 クロック 入 力 無 効 1: 外 部 クロック 入 力 有 効 5 - "0"を 設 定 4 - "0"を 設 定 3 - "0"を 設 定 2 - "0"を 設 定 この 設 定 で P2_0 端 子 をタイマ RD の 外 部 クロック 入 力 端 子 にします 1 cmd1_trdfcr コンビネーションモード 選 択 ビットを 設 定 します PWM モードでは 00 (タイマモード PWM モード PWM3 モード)にしてく 0 cmd0_trdfcr ださい bit6= "1" (3) タイマ RD 制 御 レジスタ 1(TRDCR1:Timer RD control register 1)の 設 定 ビット シンボル 説 明 設 定 値 7 cclr2_trdcr1 6 cclr1_trdcr1 5 cclr0_trdcr1 4 ckeg1_trdcr0 3 ckeg0_trdcr0 2 tck2_trdcr0 1 tck1_trdcr0 0 tck0_trdcr0 TRD1 カウンタクリア 選 択 ビットを 設 定 します 000:クリア 禁 止 (フリーランニング 動 作 ) 001:TRDGRAi のコンペア 一 致 でクリア 010:TRDGRBi のコンペア 一 致 でクリア 011: 同 期 クリア( 他 のタイマ RDi のカウンタと 同 時 にクリア)( 注 4) 100: 設 定 しないでください 101:TRDGRCi のコンペア 一 致 でクリア 110:TRDGRDi のコンペア 一 致 でクリア 111: 設 定 しないでください 外 部 クロックエッジ 選 択 ビット( 注 3)を 設 定 します 00: 立 ち 上 がりエッジでカウント 01: 立 ち 下 がりエッジでカウント 10: 両 エッジでカウント 11: 設 定 しないでください 今 回 は ロータリエンコーダのパルスを 立 ち 上 がり 立 ち 下 がりの 両 方 で カウントするようにします カウントソース 選 択 ビットを 設 定 します 000:f1 (1/20MHz=50ns) 001:f2 (2/20MHz=100ns) 010:f4 (4/20MHz=200ns) 011:f8 (8/20MHz=400ns) 100:f32 (32/20MHz=1600ns) 101:TRDCLK 入 力 ( 注 1)または fc2 ( 注 2) fc2 = 2/XCIN クロック= 今 回 は 未 接 続 110:fOCO40M ( 高 速 オンチップオシレータ 40MHz= 今 回 は 未 接 続 ) 111:fOCO-F( 注 4) ( 高 速 オンチップオシレータを FRA2 で 分 周 したクロック = 今 回 は 未 接 続 ) 0x15 66

注 1. TRDECR レジスタの ITCLK0 ビットが 0 (TRDCLK 入 力 )かつ TRDFCR レジスタの STCLK ビットが 1 ( 外 部 クロック 入 力 有 効 )のとき 有 効 です 注 2. タイマモードで TRDECR レジスタの ITCLK0 ビットが 1 (fc2)のとき 有 効 です 注 3. TCK2~TCK0 ビットが 101 (TRDCLK 入 力 または fc2) TRDECR レジスタの ITCLK0 ビットが 0 (TRDCLK 入 力 ) かつ TRDFCR レジスタの STCLK ビットが 1 ( 外 部 クロック 入 力 有 効 )のとき 有 効 です 注 4. foco-f を 選 択 するとき CPU クロックより 速 いクロック 周 波 数 に foco-f を 設 定 してください (4) タイマ RD スタートレジスタ(TRDSTR:Timer RD start register)の 設 定 ビット シンボル 説 明 設 定 値 7 - "0"を 設 定 6 - "0"を 設 定 5 - "0"を 設 定 4 - "0"を 設 定 TRD1 カウント 動 作 選 択 ビットを 設 定 します 3 csel1_trdstr 0:TRDGRA1 レジスタとのコンペア 一 致 でカウント 停 止 1:TRDGRA1 レジスタとのコンペア 一 致 後 もカウント 継 続 2 csel0_trdstr TRD0 カウント 動 作 選 択 ビットを 設 定 します 0:TRDGRA0 レジスタとのコンペア 一 致 でカウント 停 止 1:TRDGRA0 レジスタとのコンペア 一 致 後 もカウント 継 続 bit1= "1" 1 tstart1_trdstr 0 tstart0_trdstr TRD1 カウント 開 始 フラグを 設 定 します 0:カウント 停 止 1:カウント 開 始 TRD0 カウント 開 始 フラグを 設 定 します 0:カウント 停 止 1:カウント 開 始 67

5.2.11 タイマ RB の 1ms ごとの 割 り 込 みプログラム 388 : /************************************************************************/ 389 : /* タイマRB 割 り 込 み 処 理 */ 390 : /************************************************************************/ 391 : #pragma interrupt inttrb(vect=24) 392 : void inttrb( void ) 393 : { 394 : unsigned int i; 395 : 396 : asm(" fset I "); /* タイマRB 以 上 の 割 り 込 み 許 可 */ 397 : 398 : cnt1++; 399 : 400 : /* サーボモータ 制 御 */ 401 : servocontrol(); 396 行 タイマ RB 割 り 込 み 以 上 のレベルの 割 り 込 みがあったときに 割 り 込 み 処 理 に 移 るよう 割 り 込 みを 許 可 しておきます 割 り 込 みプログラムが 実 行 された 時 点 で NMI 割 り 込 み 以 外 の 割 り 込 みが 禁 止 され るので 割 り 込 みプログラム 内 で 割 り 込 みを 許 可 する 場 合 は 改 めて 割 り 込 みを 許 可 しておかなけ れば 行 けません 今 回 は タイマ RD0 割 り 込 み タイマ RC 割 り 込 みが 発 生 した 場 合 それぞれの 割 り 込 み 処 理 に 移 り ます 398 行 cnt1 変 数 の 値 を 1 つ 増 やします よって cnt1 は 1ms ごとに 増 加 していきます 401 行 ステアリングモータの PWM 値 を 計 算 します 403 : /* 10 回 中 1 回 実 行 する 処 理 */ 404 : itimer10++; 405 : switch( itimer10 ) { 406 : case 1: 407 : /* エンコーダ 制 御 */ 408 : i = trd1; 409 : iencoder = i - uencoderbuff; 410 : lencodertotal += iencoder; 411 : uencoderbuff = i; 412 : break; 中 略 438 : case 10: 439 : /* itimer10 変 数 の 処 理 */ 440 : itimer10 = 0; 441 : break; 442 : } 404 行 itimer10 変 数 の 値 を 1 つ 増 やします 405~ 442 行 itimer10 変 数 の 値 に 応 じて 分 岐 させます case 文 は 1~10 まであり itimer10 変 数 は 1ms ごとに 増 えていくので 10ms ごとに 1 回 case 文 が 順 番 に 実 行 されることになります 440 行 itimer10 変 数 を 0 にして 次 の 1ms 後 の 割 り 込 みで case 1 の 部 分 が 実 行 されるようにします 68

ロータリエンコーダに 関 する 変 数 処 理 です タイマ RD1 カウンタ(TRD1)の 値 が ロータリエンコーダの 積 算 パルス 数 です 範 囲 は 0~65535 で 65535 の 次 は 0 になります iencoder 10ms 間 のロータリエンコーダのパルス 数 を 入 力 します lencodertotal ロータリエンコーダの 積 算 値 を 入 力 します long 型 なので 約 21 億 パルスまでカウ ントできます iencoder 値 は 次 の 計 算 で 求 めます iencoder= 現 在 の TRD1 の 値 (i 変 数 )-10ms 前 の TRD1 の 値 (uencoderbuff 変 数 ) 計 算 の 様 子 を 下 図 に 示 します 10ms 前 今 TRD1 の 値 542 = 876 = uencoderbuff i i- uencoderbuff の 値 が 最 新 の 10ms 間 のエンコーダパルス 値 となる 408~ 411 行 lencodertotal 変 数 は 10ms ごとに iencoder の 値 を 加 えていきます 408 行 で 現 在 の TRD1 の 値 (i 変 数 )を uencoderbuff 変 数 に 代 入 します 10ms 後 は uencoderbuff 変 数 の 値 が 10ms 前 の 値 になっています 今 回 i 変 数 に TRD1 の 値 を 一 度 コピーしてから 10ms 前 の 値 の 差 分 を 計 算 して iencoder に 代 入 し ています 下 記 のプログラムのように TRD1 の 値 を 直 接 使 った 方 が 分 かりやすいですが そうして いません 1 : iencoder = trd1; 2 : trd1 = 0; 3 : lencodertotal += iencoder; これは 1 行 目 が 終 わってから 2 行 目 の TRD1 の 値 をクリアするまでのわずかな 間 に パルスがカウ ントされてしまった 場 合 カウント 洩 れが 起 きてしまうためです それを 防 ぐためにちょっと 複 雑 です が 今 回 のようなプログラムにしています TRD1 の 上 限 である 65535 を 超 えた 場 合 はどうなるのでしょうか 10ms 前 今 TRD1 の 値 65530 = 2 = uencoderbuff i i- uencoderbuff の 値 が 最 新 の 10ms 間 のエンコーダパルス 値 となる iencoder = 現 在 の TRG の 値 (i 変 数 )-10ms 前 の TRG の 値 (uencoderbuff 変 数 ) iencoder = 2-65530 = -62228 この 値 を 16 進 数 で 表 すと 0xffff0008 となります 変 数 の 型 は 符 号 無 し 16bit 幅 なので 下 位 の 16bit のみ 有 効 となり 0x0008=8となります カウント 回 数 としては 165531 265532 365533 465534 565535 60 71 82 の 8 カウント 分 となり 計 算 結 果 と 一 致 します 69

5.2.12 アナログセンサ 基 板 TypeS Ver.2 のデジタルセンサ 値 読 み 込 み 474 : /************************************************************************/ 475 : /* アナログセンサ 基 板 TypeS Ver.2のデジタルセンサ 値 読 み 込 み */ 476 : /* 引 数 なし */ 477 : /* 戻 り 値 左 端 左 中 右 中 右 端 のデジタルセンサ 0: 黒 1: 白 */ 478 : /************************************************************************/ 479 : unsigned char sensor_inp( void ) 480 : { 481 : unsigned char sensor; 482 : 483 : sensor = (p2_7<<3) (p2_6<<2) (p2_5<<1) p0_7; 484 : sensor = ~sensor; 485 : sensor &= 0x0f; 486 : 487 : return sensor; 488 : } アナログセンサ 基 板 TypeS Ver.2 のデジタルセンサ 4 個 を 読 み 込 む 関 数 です デジタルセンサは 黒 で"1" 白 で "0"なのでポートから 読 み 込 むときに ~ (チルダ)をつけて 反 転 させます アナログセンサ 基 板 TypeS Ver.2 76543210 戻 り 値 00000011 中 心 のデジタルセンサ 値 を 読 み 込 む 関 数 は center_inp 関 数 です 70

5.2.13 アナログセンサ 基 板 TypeS Ver.2 の 中 心 デジタルセンサ 読 み 込 み 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 490 : /************************************************************************/ 491 : /* アナログセンサ 基 板 TypeS Ver.2の 中 心 デジタルセンサ 読 み 込 み */ 492 : /* 引 数 なし */ 493 : /* 戻 り 値 中 心 デジタルセンサ 0: 黒 1: 白 */ 494 : /************************************************************************/ 495 : unsigned char center_inp( void ) 496 : { 497 : unsigned char sensor; 498 : 499 : sensor = ~p0_4 & 0x01; 500 : 501 : return sensor; 502 : } アナログセンサ 基 板 TypeS Ver.2 の 中 心 デジタルセンサ 1 個 を 読 み 込 む 関 数 です アナログセンサ 基 板 TypeS Ver.2 76543210 戻 り 値 00000001 中 心 以 外 のデジタルセンサ 値 を 読 み 込 む 関 数 は sensor_inp 関 数 です 71

5.2.14 アナログセンサ 基 板 TypeS Ver.2 のスタートバー 検 出 センサ 読 み 込 み 504 : /************************************************************************/ 505 : /* アナログセンサ 基 板 TypeS Ver.2のスタートバー 検 出 センサ 読 み 込 み */ 506 : /* 引 数 なし */ 507 : /* 戻 り 値 0:スタートバーなし 1:スタートバーあり */ 508 : /************************************************************************/ 509 : unsigned char startbar_get( void ) 510 : { 511 : unsigned char sensor; 512 : 513 : sensor = ~p0_3 & 0x01; 514 : 515 : return sensor; 516 : } アナログセンサ 基 板 TypeS Ver.2 のスタートバー 検 出 センサの 状 態 を 読 み 込 む 関 数 です スタートバーあり スタートバーなし アナログセンサ 基 板 アナログセンサ 基 板 76543210 戻 り 値 00000001 76543210 戻 り 値 00000000 72

5.2.15 RMC-R8C35A マイコンボード 上 のディップスイッチ 値 読 み 込 み 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 518 : /************************************************************************/ 519 : /* マイコンボード 上 のディップスイッチ 値 読 み 込 み */ 520 : /* 引 数 なし */ 521 : /* 戻 り 値 スイッチ 値 0~15 */ 522 : /************************************************************************/ 523 : unsigned char dipsw_get( void ) 524 : { 525 : unsigned char sw; 526 : 527 : sw = (p5_7<<3) (p4_5<<2) (p4_4<<1) p4_3; 528 : 529 : return sw; 530 : } RMC-R8C35A マイコンボードのディップスイッチの 値 を 読 み 込 む 関 数 です 戻 り 値 は 0~15 (2 4-1)です "1" "0" 戻 り 値 76543210 00001111 73

5.2.16 基 板 マイコンカーVer.2 上 のプッシュスイッチ 値 読 み 込 み 532 : /************************************************************************/ 533 : /* 基 板 マイコンカー 上 のプッシュスイッチ 値 読 み 込 み(SW1~4) */ 534 : /* 引 数 なし */ 535 : /* 戻 り 値 スイッチ 値 bit3:sw1 bit2:sw2 bit1:sw3 bit0:sw4 0:OFF 1:ON */ 536 : /************************************************************************/ 537 : unsigned char pushsw_get( void ) 538 : { 539 : unsigned char sw; 540 : 541 : sw = (p6_4<<3) (p0_0<<2) (p6_3<<1) p2_3; 542 : sw = ~sw; 543 : sw &= 0x0f; 544 : 545 : return sw; 546 : } 基 板 マイコンカーVer.2 上 のプッシュスイッチの 値 を 読 み 込 む 関 数 です 74

5.2.17 RMC-R8C35A マイコンボード 上 の LED 制 御 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 548 : /************************************************************************/ 549 : /* マイコンボード 上 のLED 制 御 */ 550 : /* 引 数 4 個 のLED 制 御 0:OFF 1:ON */ 551 : /* 戻 り 値 なし */ 552 : /************************************************************************/ 553 : void led_out( unsigned char led ) 554 : { 555 : unsigned char d; 556 : 557 : d = p1 & 0xf0; 558 : p1 = d (~led & 0x0f); 559 : } RMC-R8C35A マイコンボード 上 の LED を 4 個 制 御 する 関 数 です 引 数 76543210 00000000 引 数 の bit が"1"なら 同 じ bit の LED が 点 灯 します 引 数 の bit が"0"なら 同 じ bit の LED が 消 灯 します l 3 2 1 0 75

5.2.18 後 輪 の 速 度 制 御 (ディップスイッチによる PWM 減 速 あり) 561 : /************************************************************************/ 562 : /* 後 輪 の 速 度 制 御 */ 563 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 564 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 565 : /* 戻 り 値 なし */ 566 : /************************************************************************/ 567 : void motor_r( int accele_l, int accele_r ) 568 : { 569 : int sw_data; 570 : 571 : sw_data = dipsw_get() + 5; /* ディップスイッチ 読 み 込 み */ 572 : accele_l = accele_l * sw_data / 20; 573 : accele_r = accele_r * sw_data / 20; 574 : 575 : motor2_r( accele_l, accele_r ); motor2_r 関 数 については 次 の 説 明 を 参 照 してください 576 : } 基 板 マイコンカーVer.2 の 後 輪 モータ 2 個 を 制 御 する 関 数 です 右 前 右 後 進 行 方 向 左 前 左 後 使 い 方 を 下 記 に 示 します motor_r( 左 後 モータの PWM, 右 後 モータの PWM ); 左 後 モータの PWM 右 後 モータの PWM の 値 は 下 記 を 設 定 することができます 0 停 止 1~ 100 正 転 の 割 合 100 が 一 番 速 い -1~-100 逆 転 の 割 合 100 が 一 番 速 い 76

モータへの 出 力 は motor_r 関 数 で 設 定 した 割 合 がそのままモータに 出 力 されるのではなく 下 記 の 計 算 結 果 がモータに 出 力 されます 実 際 のモータに 出 力 される 割 合 = 引 数 (マイコンボードのディップスイッチの 値 +5) 20 例 えば ディップスイッチの 値 が 10 で 下 記 プログラムを 実 行 したとします motor_r( 50, 100 ); 左 後 モータに 出 力 される 割 合 =プログラムの 割 合 (ディップスイッチの 値 +5) 20 =50 (10+5) 20 =37.5 37 ( 小 数 点 以 下 は 切 り 捨 てです) 右 後 モータに 出 力 される 割 合 =プログラムの 割 合 (ディップスイッチの 値 +5) 20 =100 (10+5) 20 =75 3 2 1 0 10 進 数 計 算 実 際 に 出 力 され る PWM の 割 合 bit3 bit2 bit1 bit0 0 0 0 0 0 5/20 25% 0 0 0 1 1 6/20 30% 0 0 1 0 2 7/20 35% 0 0 1 1 3 8/20 40% 0 1 0 0 4 9/20 45% 0 1 0 1 5 10/20 50% 0 1 1 0 6 11/20 55% 0 1 1 1 7 12/20 60% 1 0 0 0 8 13/20 65% 1 0 0 1 9 14/20 70% 1 0 1 0 10 15/20 75% 1 0 1 1 11 16/20 80% 1 1 0 0 12 17/20 85% 1 1 0 1 13 18/20 90% 1 1 1 0 14 19/20 95% 1 1 1 1 15 20/20 100% 77

5.2.19 後 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 ) 578 : /************************************************************************/ 579 : /* 後 輪 の 速 度 制 御 2 ディップスイッチには 関 係 しないmotor 関 数 */ 580 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 581 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 582 : /* 戻 り 値 なし */ 583 : /* メモ 1~4%は 5%になります */ 584 : /************************************************************************/ 585 : void motor2_r( int accele_l, int accele_r ) 586 : { 587 : /* 左 後 モータ */ 588 : if( accele_l >= 0 ) { 589 : p3_6 = 0; 590 : } else { 591 : p3_6 = 1; 592 : accele_l = -accele_l; 593 : } 594 : if( accele_l == 0 ) { 595 : // 0%のとき 596 : trcgrc = trcgrc_buff = trcgra; 597 : } else if( accele_l <= 5 ) { 598 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 599 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * 5 / 100; 600 : } else if( accele_l <= 99 ) { 601 : // 6~99%のとき 602 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * accele_l / 100; 603 : } else { 604 : // 100%のとき( 実 際 は99%を 設 定 ) 605 : trcgrc_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 606 : } 607 : 608 : /* 右 後 モータ */ 609 : if( accele_r >= 0 ) { 610 : p3_0 = 0; 611 : } else { 612 : p3_0 = 1; 613 : accele_r = -accele_r; 614 : } 615 : if( accele_r == 0 ) { 616 : // 0%のとき 617 : trdgrb0 = trdgrb0_buff = trdgra0; 618 : } else if( accele_r <= 5 ) { 619 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 620 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * 5 / 100; 621 : } else if( accele_r <= 99 ) { 622 : // 6~99%のとき 623 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * accele_r / 100; 624 : } else { 625 : // 100%のとき( 実 際 は99%を 設 定 ) 626 : trdgrb0_buff = (unsigned long)(trd_motor_cycle-1) * 99 / 100; 627 : } 628 : } motor_r 関 数 は ディップスイッチの 設 定 でモータに 出 力 する 割 合 をさらに 落 としましたが motor2_r 関 数 は プロ 78

グラムの 引 数 どおりの 割 合 をモータに 出 力 します 右 後 モータのプログラムを 解 説 します 609 行 ~ 614 行 右 後 モータに 設 定 する PWM 値 がプラスなら P3_0 端 子 を"0"にして 右 後 モータの 回 転 を 正 転 マイ ナスなら P3_0 端 子 を"1"にして 右 後 モータの 回 転 を 逆 転 させます 右 後 モータに 設 定 する PWM が 0%なら TRDGRB0 に TRDGRA0( 周 期 を 設 定 するレジスタ)と 同 じ 値 を 設 定 し PWM を 0%にします 下 図 のように 波 形 を"1"にするタイミングと"0"にするタイミングが 同 時 に 起 こります この 場 合 "0" にするタイミングが 優 先 されるため 波 形 が"0"になり 続 け モータに 出 力 する PWM が 0%になりま す TRDGRA0=19999 TRD0 TRD0=TRDGRB0+1 で 波 形 が"0"になる TRD0=TRDGRA0+1 で 波 形 1TRD0=TRDGRB0+1 で 波 形 が"0"になる が"1"になり TRD0 が 0 になる 2TRD0=TRDGRA0+1 で 波 形 が"1"になる が 同 時 に 起 こると 1が 優 先 される すなわち 波 形 が"0"になる 615 行 ~ 617 行 TRDGRB0=2499 trdgrb0_buff=2499 TRDGRB0 と trdgrb0_buff を 19999 にする 0 時 間 TRDSTR bit0 "1" "0" 618 行 ~ 620 行 TRDIOB0 端 子 "1" (P2_2) "0" 右 後 モータに 設 定 する PWM が 1~5%の 場 合 PWM の 設 定 は interrupt inttrd0 割 り 込 みで 設 定 し ているので PWM 値 が 1~5%だと 割 り 込 みプログラムで 設 定 しようとしている 最 中 に 波 形 が"0"にな るってしまいます よって 最 小 値 は 5%にすることとして PWM を 1~5%にするときは 5%の 値 を 設 定 し ます 最 小 値 5%は 割 り 込 みが 発 生 してから 468 行 469 行 が 実 行 されるまでの 時 間 を 実 測 して 決 めま した 右 後 モータに 設 定 する PWM が 6~99%なら trdgrb0_buff に TRDGRB0 に 設 定 する 値 を 計 算 して 設 定 します 実 際 に TRDGRB0 に 設 定 されるのは 割 り 込 みプログラム 内 で 行 われ 下 図 のように PWM 波 形 が 出 力 されます TRDGRA0=19999 TRD0 19999 割 り 込 み 発 生 割 り 込 み 発 生 ここで trdgrb0_buff の 値 を 999 に 変 更 割 り 込 みプログラム 内 で TRDGRB0 の 値 を trdgrb0_buff の 値 (999)に 変 更 621 行 ~ 623 行 TRDGRB0=2499 trdgrb0_buff=2499 2000 数 十 μs 遅 れる 0 時 間 TRDSTR bit0 "1" "0" TRDIOB0 端 子 "1" (P2_2) "0" 79

624 行 ~ 626 行 設 定 する PWM が 100%なら 波 形 を 常 に"1"にしますが 今 回 FET ドライバに IR2302 という IC を 使 っています この IC は PWM を 加 えないと 動 作 しなくなるため PWM100%にすることはできませ ん 今 回 は 99%を 上 限 に 設 定 します 左 後 モータについても 同 様 の 考 え 方 なので 説 明 は 省 略 します 5.2.20 前 輪 の 速 度 制 御 (ディップスイッチによる PWM 減 速 あり) 630 : /************************************************************************/ 631 : /* 前 輪 の 速 度 制 御 */ 632 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 633 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 634 : /* 戻 り 値 なし */ 635 : /************************************************************************/ 636 : void motor_f( int accele_l, int accele_r ) 637 : { 638 : int sw_data; 639 : 640 : sw_data = dipsw_get() + 5; /* ディップスイッチ 読 み 込 み */ 641 : accele_l = accele_l * sw_data / 20; 642 : accele_r = accele_r * sw_data / 20; 643 : 644 : motor2_f( accele_l, accele_r ); 645 : } 基 板 マイコンカーVer.2 の 前 輪 モータ 2 個 を 制 御 する 関 数 です 右 前 右 後 進 行 方 向 左 前 左 後 使 い 方 は motor_r 関 数 と 同 様 です motor_r 関 数 部 分 を 参 照 してください 80

5.2.21 前 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 ) 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 647 : /************************************************************************/ 648 : /* 前 輪 の 速 度 制 御 2 ディップスイッチには 関 係 しないmotor 関 数 */ 649 : /* 引 数 左 モータ:-100~100, 右 モータ:-100~100 */ 650 : /* 0で 停 止 100で 正 転 100% -100で 逆 転 100% */ 651 : /* 戻 り 値 なし */ 652 : /* メモ 1~4%は 5%になります */ 653 : /************************************************************************/ 654 : void motor2_f( int accele_l, int accele_r ) 655 : { 656 : /* 左 前 モータ */ 657 : if( accele_l >= 0 ) { 658 : p3_4 = 0; 659 : } else { 660 : p3_4 = 1; 661 : accele_l = -accele_l; 662 : } 663 : if( accele_l == 0 ) { 664 : // 0%のとき 665 : trcgrb = trcgrb_buff = trcgra; 666 : } else if( accele_l <= 5 ) { 667 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 668 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * 5 / 100; 669 : } else if( accele_l <= 99 ) { 670 : // 6~99%のとき 671 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * accele_l / 100; 672 : } else { 673 : // 100%のとき( 実 際 は99%を 設 定 ) 674 : trcgrb_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 675 : } 676 : 677 : /* 右 前 モータ */ 678 : if( accele_r >= 0 ) { 679 : p3_2 = 0; 680 : } else { 681 : p3_2 = 1; 682 : accele_r = -accele_r; 683 : } 684 : if( accele_r == 0 ) { 685 : // 0%のとき 686 : trdgrc0 = trdgrc0_buff = trdgra0; 687 : } else if( accele_r <= 5 ) { 688 : // 1~5%のときは プログラム 的 な 仕 様 で5%とする 689 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * 5 / 100; 690 : } else if( accele_r <= 99 ) { 691 : // 6~99%のとき 692 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * accele_r / 100; 693 : } else { 694 : // 100%のとき( 実 際 は99%を 設 定 ) 695 : trdgrc0_buff = (unsigned long)(trd_motor_cycle-1) * 99 / 100; 696 : } 697 : } motor_f 関 数 は ディップスイッチの 設 定 でモータに 出 力 する 割 合 をさらに 落 としましたが motor2_f 関 数 は プロ 81

グラムの 引 数 どおりの 割 合 をモータに 出 力 します 動 作 原 理 は motor2_r 関 数 と 同 様 です motor2_r 関 数 の 説 明 を 参 照 してください 5.2.22 後 モータ 停 止 動 作 (ブレーキ フリー) 設 定 699 : /************************************************************************/ 700 : /* 後 モータ 動 作 (BRAKE= 動 作 とブレーキの 繰 り 返 し FREE=0%のフリー) */ 701 : /* 引 数 左 モータ:FREE or BRAKE, 右 モータ:FREE or BRAKE */ 702 : /* 戻 り 値 なし */ 703 : /* メモ フリーにすると PWM 値 に 関 わらず0%のフリーになります */ 704 : /* モータト ライフ 基 板 TypeSとは 動 作 が 違 いますので 気 を 付 けてください */ 705 : /************************************************************************/ 706 : void motor_mode_r( int mode_l, int mode_r ) 707 : { 708 : if( mode_l ) { 709 : p3_7 = 0; 710 : } else { 711 : p3_7 = 1; 712 : } 713 : if( mode_r ) { 714 : p3_1 = 0; 715 : } else { 716 : p3_1 = 1; 717 : } 718 : } 後 モータの 停 止 状 態 を ブレーキにするかフリーにするかを 設 定 する 関 数 です フリーとブレーキの 違 いを 下 図 に 示 します 回 路 ブレーキ 1 2 M 無 接 続 フリー 1 2 M 無 接 続 動 作 モータの 端 子 間 に 電 圧 を 加 えると 軸 が 回 転 します 逆 に 軸 を 回 転 させると 端 子 間 に 電 圧 が 発 生 します 軸 が 回 転 している 状 態 では 端 子 間 に 電 圧 が 発 生 しますが 端 子 間 をショートさせると 端 子 間 に 大 電 流 が 流 れます この 電 流 によって モータの 軸 には 回 転 を 止 める 方 向 に 回 転 力 が 発 生 します これがブレーキのような 動 作 になります モータの 軸 が 回 っている 状 態 で 端 子 を 無 接 続 にすると モータの 軸 の 回 転 は 惰 性 で 遅 くなっていきます これをフ リーといいます モータを PWM60%で 正 転 させたときの ブレーキとフリーの 違 いを 下 表 に 示 します BRAKE にしたときの 動 作 FREE にしたときの 動 作 基 板 マイコンカーVer.2 60% 正 転 40%ブレーキを 繰 り 返 しま す PWM の 割 合 にかかわらず 100%フリ ー 動 作 になります モータドライブ 基 板 TypeS Ver.4 60% 正 転 40%ブレーキを 繰 り 返 しま す 60% 正 転 40%フリーを 繰 り 返 します 基 板 マイコンカーVer.2 のフリーは PWM 値 に 関 わらずフリー100%になります モータドライブ 基 板 TypeS Ver.4 のプログラムとは 動 作 が 違 うので 移 植 する 場 合 は 気 をつけてください 82

5.2.23 前 モータ 停 止 動 作 (ブレーキ フリー) 設 定 720 : /************************************************************************/ 721 : /* 前 モータ 動 作 (BRAKE= 動 作 とブレーキの 繰 り 返 し FREE=0%のフリー) */ 722 : /* 引 数 左 モータ:FREE or BRAKE, 右 モータ:FREE or BRAKE */ 723 : /* 戻 り 値 なし */ 724 : /* メモ フリーにすると PWM 値 に 関 わらず0%のフリーになります */ 725 : /* モータト ライフ 基 板 TypeSとは 動 作 が 違 いますので 気 を 付 けてください */ 726 : /************************************************************************/ 727 : void motor_mode_f( int mode_l, int mode_r ) 728 : { 729 : if( mode_l ) { 730 : p3_5 = 0; 731 : } else { 732 : p3_5 = 1; 733 : } 734 : if( mode_r ) { 735 : p3_3 = 0; 736 : } else { 737 : p3_3 = 1; 738 : } 739 : } 前 モータを 回 すとき 停 止 の 状 態 をブレーキにするかフリーにするか 選 択 します 他 は motor_mode_r 関 数 と 同 じです 5.2.24 ステアリングモータの PWM 設 定 741 : /************************************************************************/ 742 : /* サーボモータ 制 御 */ 743 : /* 引 数 サーボモータPWM:-100~100 */ 744 : /* 0で 停 止 100で 右 に100% -100で 左 に100% */ 745 : /* 戻 り 値 なし */ 746 : /************************************************************************/ 747 : void servopwmout( int pwm ) 748 : { 749 : if( pwm >= 0 ) { 750 : p6_0 = 0; 751 : } else { 752 : p6_0 = 1; 753 : pwm = -pwm; 754 : } 755 : 756 : if( pwm <= 2 ) { 757 : trcgrd = trcgrd_buff = trcgra; 758 : } if( pwm <= 99 ) { 759 : trcgrd_buff = (unsigned long)(trc_motor_cycle-1) * pwm / 100; 760 : } else { 761 : trcgrd_buff = (unsigned long)(trc_motor_cycle-1) * 99 / 100; 762 : } 763 : } 基 板 マイコンカーVer.2 のステアリングモータに PWM を 設 定 する 関 数 です 83

749 行 ~ 754 行 756 行 ~ 757 行 758 行 ~ 759 行 760 行 ~ 761 行 ステアリングモータに 設 定 する PWM 値 が プラスなら P6_0 端 子 を"0"にしてステアリングモータを 正 転 マイナスなら P6_0 端 子 を"1"にしてステアリングモータを 逆 転 させます 設 定 する PWM が 0~2%の 場 合 PWM を 0%として 設 定 します 設 定 内 容 について 詳 しくは 5.2.19 後 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 ) を 参 照 してください 設 定 する PWM が 3~100%の 場 合 PWM 値 を 計 算 して trcgrd_buff 変 数 に 値 を 設 定 します この 変 数 は 1ms ごとの 割 り 込 み 関 数 inttrc 関 数 で TRCGRD へ 代 入 されます 100%を 設 定 したときは trcgrd_buff = (unsigned long)(trc_motor_cycle-2) * pwm / 100 = (20000-2) * 100 / 100 = 19998 を 設 定 します これは TRC の 1 カウント 分 の 50ns だけ"0"になりますが 50ns/1ms=0.005% なの で ほぼ 100%と 見 なして 問 題 ありません 設 定 内 容 について 詳 しくは 5.2.19 後 輪 の 速 度 制 御 2(ディップスイッチには 関 係 しない motor 関 数 ) を 参 照 してください 設 定 する PWM が 100%なら 波 形 を 常 に"1"にしますが 今 回 FET ドライバに IR2302 という IC を 使 っています この IC は PWM を 加 えないと 動 作 しなくなるため PWM100%にすることはできませ ん 今 回 は 99%を 上 限 に 設 定 します 使 い 方 を 下 記 に 示 します servopwmout( ステアリングモータの PWM ); ステアリングモータの PWM の 値 は 下 記 を 設 定 することができます 0 停 止 1~100 右 回 転 の 割 合 100 が 一 番 速 い -1~-100 左 回 転 の 割 合 100 が 一 番 速 い 今 回 のプログラムは 引 数 を 正 の 数 にすると 右 へ 負 の 数 にすると 左 へステアリングが 回 ります 正 の 数 ステアリングモータ 進 行 方 向 負 の 数 84

5.2.25 クロスラインの 検 出 処 理 765 : /************************************************************************/ 766 : /* クロスライン 検 出 処 理 */ 767 : /* 引 数 なし */ 768 : /* 戻 り 値 0:クロスラインなし 1:あり */ 769 : /************************************************************************/ 770 : int check_crossline( void ) 771 : { 772 : unsigned char b; 773 : int ret = 0; 774 : 775 : b = sensor_inp(); 776 : if( b==0x0f b==0x0e b==0x0d b==0x0b b==0x07 ) { 777 : ret = 1; 778 : } 779 : return ret; 780 : } センサの 状 態 をチェックして クロスラインかどうか 判 断 する 関 数 です アナログセンサ 基 板 TypeS Ver.2 の 中 心 を 除 くデジタルセンサ 4 つの 内 3 つ 以 上 が 白 を 検 出 するとクロスラインと 判 断 します 戻 り 値 は クロスラインを 検 出 したら"1" クロスラインなしは"0"が 返 ってきます 11 11 11 10 11 01 10 11 01 11 85

5.2.26 ステアリングモータ 角 度 の 取 得 782 : /************************************************************************/ 783 : /* サーボ 角 度 取 得 */ 784 : /* 引 数 なし */ 785 : /* 戻 り 値 入 れ 替 え 後 の 値 */ 786 : /************************************************************************/ 787 : int getservoangle( void ) 788 : { 789 : return( ad5 - iangle0 ); 790 : } ステアリングモータの 角 度 は AN5(P0_2) 端 子 に 接 続 されているポテンショメータ(ボリューム)の 値 で 分 かります iangle0 は 0 度 のときの A/D 変 換 値 を 入 れておきます 例 えば 角 度 が 0 度 のとき A/D 変 換 値 が 456 なら iangle0 変 数 に 456 を 代 入 すると 戻 り 値 は 下 記 のようになります 戻 り 値 =A/D 変 換 値 -0 度 のときの A/D 変 換 値 =456-456 =0 基 板 マイコンカーVer.2 は 実 測 で 左 右 40 度 ずつハンドルが 切 れました 中 心 と 左 右 最 大 にハンドルを 切 ったと きの 電 圧 を 測 ります テスタでポテンショメータの 電 圧 (CN3 の 1 ピンと 3 ピン 間 )を 計 った 結 果 左 いっぱい 2.85V 中 心 2.23V 右 いっぱい 1.61V となりました( 下 左 図 ) 5.00V( 電 源 電 圧 )が 1023 なので それぞれの 電 圧 を A/D 値 に 変 換 すると 左 いっぱい 2.85/5*1023=683 中 心 2.23/5*1023=456 右 いっぱい 1.61/5*1023=329 となります( 下 中 図 ) 787 行 の iangle0 変 数 には 0 度 のときの A/D 値 を 入 れておきます iangle0 変 数 に 456 の 値 を 入 れると 左 いっぱい +127 中 心 0 右 いっぱい -127 となります( 下 右 図 ) 2.23V 456 0 2.85V 1.61V 583 329 +127-127 40 40 40 40 40 40 電 圧 A/D 値 中 心 を0とすると (iangle0 = 456 を 代 入 すると) 86

5.2.27 アナログセンサ 値 の 取 得 792 : /************************************************************************/ 793 : /* アナログセンサ 値 取 得 */ 794 : /* 引 数 なし */ 795 : /* 戻 り 値 センサ 値 */ 796 : /************************************************************************/ 797 : int getanalogsensor( void ) 798 : { 799 : int ret; 800 : 801 : ret = ad1 - ad2; /* アナログセンサ 情 報 取 得 */ 802 : 803 : if(!crank_mode ) { 804 : /* クランクモードでなければ 補 正 処 理 */ 805 : switch( isensorpattern ) { 806 : case 0: 807 : if( sensor_inp() == 0x04 ) { 808 : ret = -650; 809 : break; 810 : } 811 : if( sensor_inp() == 0x02 ) { 812 : ret = 650; 813 : break; 814 : } 815 : if( sensor_inp() == 0x0c ) { 816 : ret = -700; 817 : isensorpattern = 1; 818 : break; 819 : } 820 : if( sensor_inp() == 0x03 ) { 821 : ret = 700; 822 : isensorpattern = 2; 823 : break; 824 : } 825 : break; 826 : 827 : case 1: 828 : /* センサ 右 寄 り */ 829 : ret = -700; 830 : if( sensor_inp() == 0x04 ) { 831 : isensorpattern = 0; 832 : } 833 : break; 834 : 835 : case 2: 836 : /* センサ 左 寄 り */ 837 : ret = 700; 838 : if( sensor_inp() == 0x02 ) { 839 : isensorpattern = 0; 840 : } 841 : break; 842 : } 843 : } 844 : 845 : return ret; 846 : } アナログセンサ 左 (P0_6 端 子 に 接 続 )とアナログセンサ 右 (P0_5 端 子 に 接 続 )の 差 分 を 計 算 して コース 中 心 から のずれを 検 出 します 801 行 で アナログセンサ 左 -アナログセンサ 右 の 計 算 をしています それ 以 降 の 行 は 急 87

カーブのときにステアリングが 反 応 しきれずに 中 心 線 を 大 きくはずれてしまった 場 合 デジタルセンサを 使 用 して 補 正 させる 処 理 を 行 っています その 処 理 を 805 行 から 842 行 まで 行 っています センサが"0100"になると センサ 値 を 強 制 的 に-650 とします 0 1 0 0 1 1 0 0 デジタルセンサが"1100"になる と センサ 値 を 強 制 的 に-700 とし ます この 状 態 をデジタルセンサ が"0100"になるまで 保 持 します 1 0 0 0 更 にはずれてもデジタルセンサ が"0100"になるまで-700 の 値 を 保 持 し 続 けます この 状 態 になる と アナログセンサは 両 方 とも 黒 色 ですので 差 分 をとっても 0 となりま す 補 正 がなければ この 状 態 を 中 心 と 認 識 してしまいます このように アナログセンサだけでは 追 従 しきれない 場 合 を 想 定 して デジタルセンサを 使 いアナログセンサの 値 を 補 正 しています 逆 のずれも 考 え 方 は 同 じです 803 行 目 で crank_mode 変 数 の 値 をチェックしています これは クロスラインを 検 出 したときや 直 角 を 検 出 するとき にデジタルセンサの 補 正 を 行 わないよう 補 正 機 能 を OFF にするための 変 数 です crank_mode が 0 なら if の{ } 内 は 実 行 しません 例 えば 下 図 のようなときはクロスライン 検 出 状 態 です センサの 反 応 は"1100"となり 補 正 するとセンサ 値 は -700 となってしまいます もう 少 し 進 み "1110"や"1111"になったらクロスラインと 判 断 して すぐに crank_mode を 1 にしてデジタルセンサの 補 正 を 停 止 します 補 正 を 停 止 しないと 急 カーブと 判 断 してしまい ハンドルを 切 って 脱 輪 します ちなみに "1100"から"1111"に 変 化 するまでの 間 は 急 カーブと 判 断 してしまいますが 非 常 に 短 い 時 間 なので ほとんど 影 響 はありません 11 00 88

5.2.28 ステアリングモータ 制 御 848 : /************************************************************************/ 849 : /* サーボモータ 制 御 */ 850 : /* 引 数 なし */ 851 : /* 戻 り 値 グローバル 変 数 iservopwm に 代 入 */ 852 : /************************************************************************/ 853 : void servocontrol( void ) 854 : { 855 : int i, iret, ip, id; 856 : int kp, kd; 857 : 858 : i = getanalogsensor(); /* センサ 値 取 得 */ 859 : kp = 1; /* kp を 増 やしていき ブルブルが */ 860 : kd = 0; /* 大 きくなったら kd を 増 やしてく */ 861 : /* ださい */ 862 : /* サーボモータ 用 PWM 値 計 算 */ 863 : ip = kp * i; /* 比 例 */ 864 : id = kd * (isensorbefore - i ); /* 微 分 ( 目 安 は P の 5~10 倍 ) */ 865 : iret = ip - id; 866 : iret /= 64; 867 : 868 : /* PWM の 上 限 の 設 定 */ 869 : if( iret > 50 ) iret = 50; /* マイコンカーが 安 定 したら */ 870 : if( iret < -50 ) iret = -50; /* 上 限 を 95 くらいにしてください */ 871 : iservopwm = iret; 872 : 873 : isensorbefore = i; /* 次 回 はこの 値 が 1ms 前 の 値 となる*/ 874 : } この 関 数 で コースの 中 心 線 からセンサがどれだけずれているかを 検 出 して ステアリングモータの PWM 値 を 計 算 します ステアリングモータ 制 御 の 要 (かなめ)の 部 分 です (1) PID 制 御 とは? 自 動 制 御 方 式 の 中 でもっとも 良 く 使 われる 制 御 方 式 に PID 制 御 という 方 式 があります この PID とは P:Proportinal( 比 例 ) I:Integral( 積 分 ) D:Differential( 微 分 ) の 3 つの 組 み 合 わせで 制 御 する 方 式 で きめ 細 かくステアリングモータの PWM を 調 整 してスムーズな 制 御 を 行 う ことができます PID 制 御 についての 詳 細 は ホームページや 書 籍 が 多 数 出 ていますのでそちらを 参 照 してください 今 回 ステアリングモータの 制 御 は 比 例 制 御 と 微 分 制 御 を 行 います PD 制 御 と 呼 びます 89

(2) P( 比 例 ) 制 御 比 例 制 御 とは 目 標 値 からのずれに 対 して 比 例 した 制 御 量 P を 与 えます P を 計 算 する 式 を 下 記 に 示 します 制 御 量 P=kp p kp p = = = = = 定 数 現 在 の 値 現 在 のアナログセンサ 値 getanalogsensor() getanalogsensor() - - - 目 標 の 値 目 標 のアナログセンサ 値 0 目 標 のアナログセンサ 値 は ちょうどコースの 中 心 の 値 である 0 になります 制 御 としては 早 く 目 標 値 に 近 づけたいので ずれが 大 きいほどステアリングモータの PWM を 多 くします そのた め 目 標 値 に 到 達 しても 速 度 を 落 としきれず 目 標 値 をいったりきたりと 振 動 してしまいます 制 御 量 目 標 値 時 間 90

(3) D( 微 分 ) 制 御 を 加 える 微 分 制 御 とは 瞬 間 的 な 変 化 量 を 計 算 して 比 例 制 御 を 押 さえるような 働 きをします 微 分 制 御 量 D を 計 算 する 式 を 下 記 に 示 します 制 御 量 D=kd d kd d = = = 定 数 過 去 のアナログセンサ 値 isensorbefore - - 現 在 のアナログセンサ 値 getanalogsensor() 過 去 のアナログセンサ 値 を isensorbefore というグローバル 変 数 に 保 存 しておきます 比 例 制 御 のみで 振 動 していても 微 分 量 を 加 えると 振 動 を 抑 えることができます ただし 比 例 制 御 を 押 さえる 働 きをしますので 目 標 値 に 近 づく 時 間 は 長 くなります 時 間 は 数 ms~ 数 十 ms のレベルです それが 実 際 の 走 り に 対 して どう 影 響 するかは 検 証 する 必 要 があります 制 御 量 Δt 比 例 のみで 計 算 比 例 と 微 分 で 計 算 目 標 値 Δx: 微 分 制 御 量 時 間 (4) 最 終 制 御 量 ステアリングモータに 加 える 制 御 量 を 計 算 する 式 を 下 記 に 示 します 最 終 制 御 量 = P 値 - D 値 プログラムでは 最 終 制 御 量 に 定 数 をかけて PWM 値 に 調 整 します 最 後 に ステアリングモータに 大 きい PWM を 加 えるとステアリング 部 のギヤが 壊 れてしまうので PWM の 上 限 を 設 けます サンプルプログラムは 50% 以 上 にならないようにしています この 数 値 を 小 さくしすぎると せっかくの PD 制 御 も 上 限 制 限 されてしまうので 反 応 が 遅 くなります 大 きすぎると 万 が 一 大 きい PWM をかけてしまった 場 合 ギヤが 壊 れます 50%の 設 定 は 最 初 だけとして コーストレースが 安 定 したら 90% 程 度 にしてください 今 回 のプログラムでは P 値 D 値 は 下 記 のように 設 定 しています P 制 御 の 定 数 = 1 859 行 D 制 御 の 定 数 = 0 860 行 P 値 D 値 をそれぞれ 調 整 して ステアリング 部 分 がばたつかず 滑 らかに かつ 力 強 く 中 心 線 をトレースするよう に 調 整 してください 力 が 弱 いと S 字 カーブでステアリングを 左 右 どちらかに 曲 げた 直 後 逆 に 曲 げるようとした ときに 中 心 を 追 従 しません 91

5.2.29 内 輪 PWM 値 計 算 876 : /************************************************************************/ 877 : /* 外 輪 のPWMから 内 輪 のPWMを 割 り 出 す ハンドル 角 度 は 現 在 の 値 を 使 用 */ 878 : /* 引 数 外 輪 PWM */ 879 : /* 戻 り 値 内 輪 PWM */ 880 : /************************************************************************/ 小 数 点 は 使 わないでください 881 : int diff( int pwm ) 882 : { 小 数 点 にしたい 場 合 は かけ 算 と 割 り 算 を 組 み 合 わせて ください 例 ) / 3.5 * 7 / 2 883 : int i, ret; 884 : 885 : i = getservoangle() / 3; /* 1 度 あたりの 増 分 で 割 る */ 886 : if( i < 0 ) i = -i; 887 : if( i > 45 ) i = 45; 888 : ret = revolution_difference[i] * pwm / 100; 889 : 890 : return ret; 891 : } diff 関 数 は 引 数 に 外 輪 ( 多 く 回 るタイヤ 側 )の PWM 値 を 入 れて 呼 び 出 すと 内 輪 ( 少 なく 回 るタイヤ 側 )の PWM 値 が 返 って 来 るという 関 数 です 885 行 で 現 在 の 角 度 を 取 得 します getservoangle 関 数 の 戻 り 値 は A/D 値 なので 度 に 直 す 必 要 がありま す ハンドルを±40 度 動 かしたときの A/D 値 を 下 記 に 示 します 0 +127-127 40 40 左 右 に 40 度 ステアリングを 動 かしたときの A/D 値 の 変 化 量 は±127 でした 左 40 度 のとき A/D 値 は 127 なの で 1 度 あたりの A/D 値 は 下 記 のようになります 1 度 あたりの A/D 値 = 左 40 度 のときの A/D 値 左 40 度 =127 40 =3.175 3 値 は 四 捨 五 入 して 整 数 にします よって A/D 値 3 が 約 1 度 となります 886 行 は 負 の 数 を 正 の 数 に 変 換 しています 887 行 は 45 度 以 上 の 角 度 のときは 45 度 にしておきます これは 次 に 説 明 する 配 列 の 設 定 が 45 度 までしか 無 いためです 888 行 は 左 タイヤと 右 タイヤの 回 転 差 を 計 算 します まず 外 輪 の 回 転 数 を 100 と 考 えて 内 輪 の 回 転 数 を 計 算 します 例 えば 現 在 の 角 度 が 25 度 のとき 添 字 部 分 に 25 が 入 り 内 輪 の 回 転 数 が 戻 り 値 となります ret = revolution_difference[i] = revolution_difference[ 25 ] = 68 92

外 輪 100%のとき 内 輪 は 戻 り 値 である 68%であることが 分 かります 次 に 外 輪 が 100%で 無 い 場 合 を 計 算 します 内 輪 は 外 輪 の 回 転 に 比 例 しますので 割 合 をかければ 内 輪 の PWM 値 が 分 かります 例 えば 外 輪 が 60%なら 内 輪 は 次 の 計 算 で 求 めることができます ret = 68 * 外 輪 の PWM 値 / 100 = 68 * 60 / 100 = 40.8 40 小 数 点 は 扱 えないので 切 り 捨 てられます ステアリング 角 度 が 25 度 外 輪 が 60%のとき 下 記 プログラムを 実 行 すると kakudo 変 数 には 40 が 代 入 されます kakudo = diff( 60 ); 5.2.30 main 関 数 - 初 期 化 101 : /************************************************************************/ 102 : /* メインプログラム */ 103 : /************************************************************************/ 104 : void main( void ) 105 : { 106 : int i; 107 : unsigned char b; 108 : 109 : /* マイコン 機 能 の 初 期 化 */ 110 : init(); /* 初 期 化 */ 111 : asm(" fset I "); /* 全 体 の 割 り 込 み 許 可 */ 112 : 113 : /* マイコンカーの 状 態 初 期 化 */ 114 : motor_mode_f( BRAKE, BRAKE ); /* 基 板 マイコンカーのFREEは */ 115 : motor_mode_r( BRAKE, BRAKE ); /* PWM 値 に 関 係 なく 必 ずフリーになる */ 116 : motor_f( 0, 0 ); 117 : motor_r( 0, 0 ); 118 : servopwmout( 0 ); main 関 数 では 最 初 に R8C/35A マイコンの 内 蔵 周 辺 機 能 の 初 期 化 割 り 込 みの 許 可 モータを 停 止 状 態 にしま す 93

5.2.31 パターン 処 理 マイコンカーの 状 態 は pattern 変 数 で 管 理 しています 通 称 パターン 処 理 と 呼 ぶことにします pattern が 0 でス タート 待 ち 11 で 通 常 トレースなど それぞれの 状 態 に 応 じてパターンを 変 えて 処 理 内 容 を 変 えていきます 現 在 のモード (pattern) 状 態 pattern 変 数 が 変 わる 条 件 0 プッシュスイッチ 押 下 待 ち プッシュスイッチを 押 したら 1 へ 1 スタートバー 開 待 ち スタートバーが 開 いたら 11 へ 11 通 常 トレース クロスラインを 検 出 したら 21 へ 21 クロスライン 通 過 処 理 200ms たったら 22 へ 22 クロスライン 後 のトレース 直 角 検 出 処 理 右 クランクを 見 つけたら 31 へ 左 クランクを 見 つけたら 41 へ 31 右 クランク 処 理 曲 げ 終 わりを 検 出 すると 32 へ 32 少 し 時 間 がたつまで 待 つ 100ms たったら 11 へ 41 左 クランク 処 理 曲 げ 終 わりを 検 出 すると 42 へ 42 少 し 時 間 がたつまで 待 つ 100ms たったら 11 へ その 他 0 へ 5.2.32 パターン 0:スタート 待 ち 120 : while( 1 ) { 121 : 122 : switch( pattern ) { 123 : case 0: 124 : /* プッシュスイッチ(SW4) 押 下 待 ち */ 125 : servopwmout( 0 ); 126 : if( pushsw_get() == 0x01 ) { 127 : cnt1 = 0; 128 : pattern = 1; 129 : break; 130 : } 131 : i = (cnt1/200) % 2 + 1; 132 : if( startbar_get() ) { 133 : i += ((cnt1/100 ) % 2 + 1) << 2; 134 : } 135 : led_out( i ); /* LED 点 滅 処 理 */ 136 : break; プッシュスイッチ(SW4) 押 下 待 ちです プッシュスイッチを 押 すまでの 間 LED 4 個 中 2 個 を 点 滅 させプッシュスイ ッチが 押 されるまで 待 ちます また スタートバー 検 出 センサが 反 応 すると さらに 2 個 ( 合 計 4 個 )の LED を 点 滅 さ せスタートバー 閉 を 検 出 していることを 選 手 に 分 かりやすく 知 らせます プッシュスイッチ(SW4)を 押 すと パターン 1 へ 移 ります 94

5.2.33 パターン 1:スタートバー 開 待 ち 138 : case 1: 139 : /* スタートバー 開 待 ち */ 140 : servopwmout( iservopwm / 2 ); 141 : if(!startbar_get() ) { 142 : iangle0 = getservoangle(); /* 0 度 の 位 置 記 憶 */ 143 : led_out( 0x0 ); 144 : cnt1 = 0; 145 : pattern = 11; 146 : break; 147 : } 148 : led_out( 1 << (cnt1/50) % 4 ); 149 : break; パターン 1 は スタートバーが 開 かれるのを 待 っている 状 態 です 140 行 でステアリングモータ 制 御 を 行 っています iservopwm 変 数 がステアリングモータに 加 える PWM 値 です 割 り 込 みプログラム 内 で 1ms ごとに 自 動 で 更 新 されていきます スタート 時 ステアリング 部 分 がブルブル 震 えない ように PWM 値 を 半 分 にしています スタートバーが 開 かれると 現 在 の 角 度 を getservoangle 関 数 で 読 み 込 み その 値 を iangle0 変 数 にセットして この 状 態 を 0 度 とします その 後 パターン 11 に 移 行 します 95

5.2.34 パターン 11: 通 常 トレース 151 : case 11: 152 : /* 通 常 トレース */ 153 : servopwmout( iservopwm ); 154 : i = getservoangle(); 155 : if( i > 110 ) { 156 : motor_f( 0, 0 ); 157 : motor_r( 0, 0 ); 158 : } else if( i > 15 ) { 159 : motor_f( diff(80), 80 ); 160 : motor_r( diff(80), 80 ); 161 : } else if( i < -110 ) { 162 : motor_f( 0, 0 ); 163 : motor_r( 0, 0 ); 164 : } else if( i < -15 ) { 165 : motor_f( 80, diff(80) ); 166 : motor_r( 80, diff(80) ); 167 : } else { 168 : motor_f( 100, 100 ); 169 : motor_r( 100, 100 ); 170 : } 171 : if( check_crossline() ) { /* クロスラインチェック */ 172 : cnt1 = 0; 173 : crank_mode = 1; 174 : pattern = 21; 175 : } 176 : break; 153 行 でステアリングモータ 制 御 を 行 っています 次 に 154 行 でステアリング 角 度 を 取 得 します 角 度 に 応 じて 左 右 回 転 数 の 設 定 をしています サンプルプログラムは ハンドル 角 度 と 駆 動 モータの 関 係 を 下 記 のようにしま す A/D 値 角 度 に 変 換 A/D 値 3.18 左 モータ PWM 右 モータ PWM 111 以 上 35 以 上 0 0 16~110 5~35 diff(80) 80-111 以 下 -35 以 下 0 0-16~-110-5~-35 80 diff(80) それ 以 外 (-15~15) -5~5 100 100 171 行 でクロスラインチェックを 行 います クロスラインを 検 出 すると crank_mode に 1 を 代 入 して アナログセンサ 値 を 取 得 する getanalogsensor 関 数 内 でデジタルセンサ 補 正 を 行 わないようにします パターンは 21 へ 移 ります 96

5.2.35 パターン 21:クロスライン 検 出 処 理 178 : case 21: 179 : /* クロスライン 通 過 処 理 */ 180 : servopwmout( iservopwm ); 181 : led_out( 0x3 ); 182 : motor_f( 0, 0 ); 183 : motor_r( 0, 0 ); 184 : if( cnt1 >= 100 ) { 185 : cnt1 = 0; 186 : pattern = 22; 187 : } 188 : break; クロスラインを 見 つけるとブレーキをかけながら ステアリングモータ 制 御 を 行 います 100ms の 間 にクロスラインを 通 過 させ 100ms 後 にはパターン 22 へ 移 行 します クロスラインを 通 過 しきる 前 にパターン 22 に 移 ってしまうと ク ロスラインを 直 角 と 見 間 違 ってしまうことがあります 0 0 0 0 100ms 後 の 位 置 1 1 1 1 クロスライン 発 見! 97

5.2.36 パターン 22:クロスライン 後 のトレース 直 角 検 出 処 理 190 : case 22: 191 : /* クロスライン 後 のトレース 直 角 検 出 処 理 */ 192 : servopwmout( iservopwm ); 193 : if( iencoder >= 11 ) { /* エンコーダによりスピード 制 御 */ 194 : motor_f( 0, 0 ); 195 : motor_r( 0, 0 ); 196 : } else { 197 : motor2_f( 70, 70 ); 198 : motor2_r( 70, 70 ); 199 : } 200 : 201 : if( (sensor_inp()&0x01) == 0x01 ) { /* 右 クランク? */ 202 : led_out( 0x1 ); 203 : cnt1 = 0; 204 : pattern = 31; 205 : break; 206 : } 207 : if( (sensor_inp()&0x08) == 0x08 ) { /* 左 クランク? */ 208 : led_out( 0x2 ); 209 : cnt1 = 0; 210 : pattern = 41; 211 : break; 212 : } 213 : break; クロスライン 通 過 後 の 処 理 を 行 います 193~199 行 でロータリエンコーダによる 速 度 制 御 を 行 っています サンプルプログラムは 1m/s 以 上 なら PWM0% 以 下 なら PWM70%で 走 行 します 201 行 目 で いちばん 右 のデジタルセンサのみをチェック 反 応 すれば 右 クランクと 判 断 しパターン 31 へ 移 りま す 207 行 目 で いちばん 左 のデジタルセンサのみをチェック 反 応 すれば 左 クランクと 判 断 しパターン 41 へ 移 りま す 98

1 いちばん 右 のセンサが 反 応 したら パタ ーン3 1 へ! 00 00 は"0" "1"どちらでも 良 い 1 いちばん 左 のセンサが 反 応 したら パタ ーン4 1 へ! は"0" "1"どちらでも 良 い 00 00 99

5.2.37 パターン 31: 右 クランク 処 理 215 : case 31: 216 : /* 右 クランク 処 理 */ 217 : servopwmout( 50 ); /* 振 りが 弱 いときは 大 きくする */ 218 : motor_f( 60, 35 ); /* この 部 分 は 角 度 計 算 (4WD 時 ).xls */ 219 : motor_r( 48, 24 ); /* で 計 算 */ 220 : if( sensor_inp() == 0x04 ) { /* 曲 げ 終 わりチェック */ 221 : cnt1 = 0; 222 : isensorpattern = 0; 223 : crank_mode = 0; 224 : pattern = 32; 225 : } 226 : break; パターン 31 は 右 にハンドルを 曲 げて 曲 げ 終 わりかどうかチェックしている 状 態 です ステアリングモータの PWM 値 はセンサ 状 態 に 関 係 なく 右 に 50% 回 転 させています ステアリングモータの 動 きが 遅 い 場 合 は PWM 値 を 大 きくします ただし ステアリング 部 分 が 約 40 度 になり 車 体 にぶつかると ステアリングモ ータがロックして 大 電 流 が 流 れ モータの 性 能 が 劣 化 したり ギヤがかけたりすることがあります 40 度 弱 の 角 度 に なったら PWM 値 を 小 さくするプログラムを 追 加 すると 良 いでしょう いつまで 続 けるかというのが 220 行 です 中 心 以 外 のデジタルセンサをチェックして "0100"ならパターン 32 に 移 ります 移 る 前 に クランクが 終 わったので crank_mode 変 数 を 0 に 戻 します 1 2 1 3 0 0 0 1 00 00 1.いちばん 右 のデジタルセンサが"1"になったので 右 クランクと 判 断 しステアリングモータを 50% 左 前 モータを 60% 右 前 モータを 35% 左 後 モータを 48% 右 後 モータを 24%で 回 します 左 右 回 転 差 は ステアリング 角 度 40 度 で 計 算 しています 2.デジタルセンサが"0100"になるまで 待 ちます まだです 3.デジタルセンサが"0100"になりました パターン 32 へ 移 ります 100

5.2.38 パターン 32: 右 クランク 処 理 後 少 し 時 間 がたつまで 待 つ 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 228 : case 32: 229 : /* 少 し 時 間 が 経 つまで 待 つ */ 230 : servopwmout( iservopwm ); 231 : motor2_r( 80, 80 ); 232 : motor2_f( 80, 80 ); 233 : if( cnt1 >= 100 ) { 234 : led_out( 0x0 ); 235 : pattern = 11; 236 : } 237 : break; センサが 中 心 線 に 到 達 してもすぐにパターン 11 に 戻 らずに 100ms 間 は 駆 動 モータを 80%にします これはパタ ーン 32 に 移 ってきたときは ステアリングをかなり 曲 げています この 状 態 でパターン 11 に 戻 ると ポテンショメータ の A/D 値 が-111 以 下 なので 駆 動 モータの PWM 値 が 0%になってしまいます これを 防 ぐために 100ms 間 ステア リング 角 度 に 関 係 なく 駆 動 モータの PWM を 80%にして 少 し 進 ませます この 間 に 角 度 が 浅 くなりパターン 11 に 戻 ったときの 角 度 でさらに 進 んでいきます 5.2.39 パターン 41: 左 クランク 処 理 239 : case 41: 240 : /* 左 クランク 処 理 */ 241 : servopwmout( -50 ); /* 振 りが 弱 いときは 大 きくする */ 242 : motor_f( 35, 60 ); /* この 部 分 は 角 度 計 算 (4WD 時 ).xls */ 243 : motor_r( 24, 48 ); /* で 計 算 */ 244 : if( sensor_inp() == 0x02 ) { /* 曲 げ 終 わりチェック */ 245 : cnt1 = 0; 246 : isensorpattern = 0; 247 : crank_mode = 0; 248 : pattern = 42; 249 : } 250 : break; パターン 31 と 同 様 の 考 え 方 です デジタルセンサが"0010"になると パターン 42 へ 移 ります 5.2.40 パターン 42: 左 クランク 処 理 後 少 し 時 間 がたつまで 待 つ 252 : case 42: 253 : /* 少 し 時 間 が 経 つまで 待 つ */ 254 : servopwmout( iservopwm ); 255 : motor2_f( 80, 80 ); 256 : motor2_r( 80, 80 ); 257 : if( cnt1 >= 100 ) { 258 : led_out( 0x0 ); 259 : pattern = 11; 260 : } 261 : break; パターン 32 と 同 様 の 考 え 方 です 101

6. 4 輪 の 回 転 数 計 算 6. 4 輪 の 回 転 数 計 算 角 度 計 算 (4WD 時 ).xls で 下 記 計 算 ができます 6.1 センターピボット 方 式 4 輪 の 回 転 数 計 算 センターピボット 方 式 の 4 輪 の 回 転 数 の 計 算 方 法 を 説 明 します( 下 図 ) 左 に30 度 ハンドルを 切 ったマイコンカー まっすぐ 向 いた マイコンカー r4 θ W=0.18m rb r2 W θ=30 =π/6 T=0.145m r1 ra r3 T=トレッド 左 右 輪 の 中 心 線 の 距 離 ( 基 板 マイコンカーVer.2 では 0.145[m]です) W=ホイールベース 前 輪 と 後 輪 の 間 隔 ( 基 板 マイコンカーVer.2 では 0.18[m]です) 図 のように 後 輪 部 の 底 辺 ra 高 さ W 角 度 θの 三 角 形 の 関 係 は 次 のようです tanθ=w/ra 角 度 θ W が 分 かっていますので ra が 分 かります ra=w/tanθ=0.18/tan(π/6)=0.312[m] 後 輪 内 輪 の 半 径 は r1=ra-t/2=0.312-0.0725=0.2395 [m] 102

6. 4 輪 の 回 転 数 計 算 後 輪 外 輪 の 半 径 は r3=ra+t/2=0.312+0.0725=0.3845 [m] また 前 輪 部 の 底 辺 rb 高 さ W 角 度 θの 三 角 形 の 関 係 は 次 のようです sinθ=w/rb 角 度 θ W が 分 かっていますので rb が 分 かります rb=w/sinθ=0.18/sin(π/6)=0.360[m] 前 輪 内 輪 の 半 径 は r2=rb-t/2=0.360-0.0725=0.2875 [m] 前 輪 外 輪 の 半 径 は r4=rb+t/2=0.360+0.0725=0.4325 [m] 一 番 回 転 する r4 を 100 としたときのそれぞれの 回 転 数 は r1 : r2 : r3 : r4 =0.2395 : 0.2875 : 0.3845 : 0.4325 =0.2395 100/0.4325 : 0.2875 100/0.4325 :0.3845 100/0.4325 : 0.4325 100/0.4325 =55 : 66 : 89 : 100 ハンドル 角 度 30 度 前 輪 外 輪 が 100 回 転 するとき 後 輪 外 輪 は 89 回 転 前 輪 内 輪 は 66 回 転 後 輪 内 輪 は 55 回 転 することになります 103

6. 4 輪 の 回 転 数 計 算 6.2 アッカーマン 方 式 4 輪 の 回 転 数 計 算 基 板 マイコンカーVer.2 は センターピポット 方 式 なので アッカーマン 方 式 は 必 要 ありませんが 参 考 までに 掲 載 しておきます アッカーマン 方 式 とは 通 常 の 車 のようにハンドルを 切 る 方 法 です 左 タイヤ 右 タイヤの 切 れ 角 は 実 は 同 じでは ありません もし 同 じ 切 れ 角 ならどうなるのでしょうか( 下 図 ) ここを 支 点 にタイヤの 角 度 が 変 わる ナックルアーム タイロッド 半 径 が 同 じため いずれ 重 なるような 角 度 になる タイヤに 無 理 がかかる ナックルアームと 呼 ばれる 部 分 をタイヤと 平 行 に 取 り 付 けると ハンドルを 切 ったとき 内 輪 と 外 輪 の 切 れ 角 が 同 じ になり 軌 跡 を 見 ると 交 差 してしまいます タイヤの 幅 は 常 に 一 定 のため タイヤに 無 理 がかかります 104

6. 4 輪 の 回 転 数 計 算 この 問 題 を 解 決 したのが ドイツ 人 のアッカーマン 及 びフランス 人 のジャントで この 機 構 をアッカーマン ジャン ト 方 式 または 単 にアッカーマン 方 式 と 呼 びます( 下 図 ) ここを 支 点 にタイヤの 角 度 が 変 わる ナックル 開 き 角 リヤタイヤの 中 心 部 分 で 交 わるように 中 心 点 が 同 じなため 間 隔 は 常 に 同 じになる タイヤに 角 度 を 与 える 左 右 のナックルアームに 開 き 角 を 付 けていれば サーボによりタイロッドが 左 右 に 動 くとナ ックルアームの 動 きに 差 が 出 て コーナ 内 側 のタイヤが 大 きな 角 度 になります 105

6. 4 輪 の 回 転 数 計 算 ナックルアームの 開 き 角 度 は リアタイヤの 中 心 部 分 で 交 わるようにします ホイールベース トレッドにより 変 わっ てくるので マイコンカーに 合 わせて 角 度 を 決 める 必 要 があります 左 に30 度 ハンドルを 切 ったマイコンカー まっすぐ 向 いた マイコンカー r4 W=0.18m r2 θ=30 =π/6 W W 1 2 T=0.145m r1 r3 T=トレッド 左 右 輪 の 中 心 線 の 距 離 ( 基 板 マイコンカーVer.2 では 0.145[m]です) W=ホイールベース 前 輪 と 後 輪 の 間 隔 ( 基 板 マイコンカーVer.2 では 0.18[m]です) 角 度 θは 前 輪 内 側 タイヤの 切 れ 角 です 1 実 際 はホイールベースより 短 いですが ほとんど 変 わらないので W とします 2 実 際 はホイールベースより 長 いですが ほとんど 変 わらないので W とします 図 のように 後 輪 部 の 底 辺 r1 高 さ W 角 度 θの 三 角 形 の 関 係 は 次 のようです tanθ=w/r1 角 度 θ W が 分 かっていますので 後 輪 内 輪 r1 が 分 かります r1=w/tanθ=0.18/tan(π/6)=0.312[m] 後 輪 外 輪 の 半 径 は r3=r1+t=0.312+0.145=0.457[m] また 前 輪 内 径 r2 高 さ W 角 度 θの 三 角 形 の 関 係 は 次 のようです sinθ=w/r2 106

角 度 θ W が 分 かっていますので 前 輪 内 輪 r2 が 分 かります 基 板 マイコンカー 製 作 キット Ver.2 プログラム 解 説 マニュアル 6. 4 輪 の 回 転 数 計 算 r2=w/sinθ=0.18/sin(π/6)=0.360[m] 前 輪 外 輪 の 半 径 r4 は 底 辺 と 高 さが 分 かっているので ピタゴラスの 定 理 より r4= (r3 2 +W 2 ) = (0.457 2 +0.18 2 ) =0.491[m] 一 番 回 転 する r4 を 100 としたときのそれぞれの 回 転 数 は r1 : r2 : r3 : r4 =0.312 : 0.360 : 0.457 : 0.491 =0.312 100/0.491 : 0.360 100/0.491 : 0.457 100/0.491 : 0.491 100/0.491 =64 : 73 : 93 : 100 ハンドル 角 度 30 度 前 輪 外 輪 が 100 回 転 するとき 後 輪 外 輪 は 93 回 転 前 輪 内 輪 は 74 回 転 後 輪 内 輪 は 64 回 転 することになります 107

7. ステアリングモータの 角 度 指 定 7. ステアリングモータの 角 度 指 定 今 までのステアリング 制 御 は センサ 基 板 が 常 にコースの 中 心 にくるような 制 御 をしていました ラジコンサーボの ように 右 に 何 度 曲 げたい 左 に 何 度 曲 げたいというように 制 御 したい 場 合 どうすればよいのでしょうか 7.1 PD 制 御 アナログセンサを PD 制 御 したとき アナログセンサの 値 が 0 になるようにステアリングモータを 制 御 していました これを 角 度 (ポテンショメータの A/D 値 )にすれば 良 いだけです 比 例 制 御 微 分 制 御 アナログセンサの 値 にするとき 制 御 量 P=kp p kp = 定 数 p = 現 在 のアナログセンサ 値 - 目 標 のアナログセンサ 値 =getanalogsensor()-0 =getanalogsensor() 制 御 量 D=kd d kd = 定 数 d = 過 去 のアナログセンサ 値 - 現 在 のアナログセンサ 値 =isensorbefore-getanalogsensor() 角 度 の 値 にするとき 制 御 量 P=kp p kp = 定 数 p = 現 在 の 角 度 - 目 標 の 角 度 =getservoangle ()-isetangle 目 標 の 角 度 を isetangle 変 数 に 入 れます 制 御 量 D=kd d kd = 定 数 d = 過 去 の 角 度 - 現 在 の 角 度 =ianglebefore2-getservoangle() 7.2 プログラム 7.2.1 グローバル 変 数 の 追 加 グローバル 変 数 を 追 加 します /* サーボ 関 係 2 */ int isetangle; /* 設 定 したい 角 度 (AD 値 ) */ int ianglebefore2; /* 前 回 の 角 度 保 存 */ int iservopwm2; /* サーボPWM 値 */ 108

7. ステアリングモータの 角 度 指 定 7.2.2 関 数 の 追 加 ステアリングモータの 角 度 指 定 用 の servocontrol2 関 数 を 追 加 します 関 数 を 追 加 したので プロトタイプ 宣 言 もしておきましょう 今 回 は 比 例 定 数 10 微 分 定 数 50 にしています この 値 は ギヤのガタなどで 違 ってきますので 各 自 調 整 してく ださい また PWM 上 限 の 50%も ステアリング 動 作 が 安 定 したら 95% 程 度 に 増 やしてください /************************************************************************/ /* モジュール 名 servocontrol2 */ /* 処 理 概 要 サーボモータ 制 御 角 度 指 定 用 */ /* 引 数 なし */ /* 戻 り 値 グローバル 変 数 ioutpwm2 に 代 入 */ /************************************************************************/ void servocontrol2( void ) { int i, j, iret, ip, id; i = isetangle; /* 設 定 したい 角 度 */ j = getservoangle(); /* 現 在 の 角 度 */ /* サーボモータ 用 PWM 値 計 算 */ ip = 10 * (j - i); /* 比 例 */ id = 50 * (ianglebefore2 - j); /* 微 分 */ iret = ip - id; iret /= 2; if( iret > 50 ) iret = 50; /* マイコンカーが 安 定 したら */ if( iret < -50 ) iret = -50; /* 上 限 を95くらいにしてください */ iservopwm2 = iret; } ianglebefore2 = j; 7.2.3 割 り 込 みプログラムの 追 加 割 り 込 みプログラムに servocontrol2 関 数 を 追 加 して 1ms ごとに 実 行 するようにします /************************************************************************/ /* タイマ RB 割 り 込 み 処 理 */ /************************************************************************/ #pragma interrupt inttrb(vect=24) void inttrb( void ) { unsigned int i; 以 下 略 asm(" fset I "); /* タイマ RB 以 上 の 割 り 込 み 許 可 */ cnt1++; /* サーボモータ 制 御 */ servocontrol(); servocontrol2(); 追 加 109

7. ステアリングモータの 角 度 指 定 7.2.4 使 い 方 main 関 数 内 で 使 用 するときは isetangle 変 数 に ステアリングモータで 角 度 を 指 定 したい A/D 値 を 代 入 します プログラムは servopwmout( iservopwm2 ); を 実 行 します servopwmout( iservopwm ); とすると センサ 基 板 がコースの 中 心 になるようなステアリング 制 御 になります 2 が 付 くか 付 かないかの 違 いです 下 記 に main プログラムの 最 初 で 角 度 指 定 した 例 を 示 します このプログラムできちんと 角 度 指 定 できているか isetangle 変 数 の 値 を 変 えて 実 験 してみましょう なお 元 々のプログラムの iangle0 変 数 の 設 定 は 走 行 開 始 直 前 なので iangle0 の 設 定 をいちばん 最 初 にしてい ます /************************************************************************/ /* メインプログラム */ /************************************************************************/ void main( void ) { int i; 以 下 略 /* マイコン 機 能 の 初 期 化 */ init(); /* 初 期 化 */ asm(" fset I "); /* 全 体 の 割 り 込 み 許 可 */ /* マイコンカーの 状 態 初 期 化 */ motor_mode_f( BRAKE, BRAKE ); /* 基 板 マイコンカーの FREE は */ motor_mode_r( BRAKE, BRAKE ); /* PWM 値 に 関 係 なく 必 ずフリーになる */ motor_f( 0, 0 ); motor_r( 0, 0 ); servopwmout( 0 ); cnt1 = 0; while( cnt1 <= 10 ); iangle0 = getservoangle(); /* 0 度 の 位 置 記 憶 */ isetangle = 32; /* 1 度 当 たり 3.18 なので 32 で 約 10 度 */ while( 1 ) { servopwmout( iservopwm2 ); } 角 度 指 定 が 正 しくできたことを 確 認 できたら 実 際 の 走 行 プログラムに 組 み 込 んでみましょう 下 記 プログラムは 新 しくパターン 52 を 作 り A/D 値 が-50 になるような 位 置 にステアリングモータを 移 動 させる 例 です case 52: isetangle = -50; servopwm( iservopwm2 ); break; 110

8. プログラムの 調 整 ポイント 8. プログラムの 調 整 ポイント 本 プログラムは ゆっくり(1m/s 程 度 )で 走 行 できるようになっています(レーンチェンジ 部 分 は 除 く) 速 度 を 上 げ たときの 調 整 ポイントを 解 説 します 行 内 容 説 明 89~99 内 輪 の PWM 値 今 回 のプログラムは 後 輪 駆 動 として 内 輪 差 を 計 算 しています 基 板 マイコンカーVer.2 は 4 輪 駆 動 なので 角 度 計 算 (4WD 時 ).xls を 使 用 して 4 輪 の PWM 値 を 計 算 して motor 関 数 で 設 定 すると 4 輪 が 角 度 に 合 った 回 転 数 になります 155~ 170 ステアリング 角 度 と 駆 動 モータの PWM 値 今 回 のプログラムは 角 度 が135 以 上 25~35 3-35 以 下 4-5 ~-35 4それ 以 外 (-5~5) で 駆 動 モータの PWM を 調 整 していま す もっと 細 かく 調 整 してみましょう また 速 度 が 速 いときの 5~10 度 遅 いときの 5~10 度 というように 速 度 も 使 って PWM 値 を 調 整 してみましょう 193 217 241 218,219 242,243 869,870 クロスライン 検 出 後 の スピード 右 クランク 検 出 時 のステアリ ングを 曲 げる PWM 値 左 クランク 検 出 時 のステアリ ングを 曲 げる PWM 値 右 クランククリア 時 の PWM 値 左 クランククリア 時 の PWM 値 ステアリングモータに 加 える PWM の 上 限 設 定 今 回 のプログラムでは 1m/s にしています それ 以 上 速 くても 直 角 を 曲 がれるか 実 験 して 曲 がれるならその 速 度 にしてみましょう また 1m/s 以 上 の 速 度 なら PWM を 0%にしていますが クロスラインか ら 直 角 までの 距 離 が 50cm だと 減 速 しきれません PWM 値 をマイナス にして 逆 転 ブレーキをかけてみましょう 右 クランク 検 出 時 右 にステアリングを 曲 げる PWM 値 を 設 定 します 今 回 は 50%です 弱 いと 曲 げるスピードが 遅 くなり 外 側 にふくらんで 脱 輪 してしまいます また40 度 になるとステアリング 部 分 が 車 体 にぶつか って ステアリングモータがロックしてしまいます ぶつかる 直 前 にステ アリングモータの PWM を 弱 めましょう 左 クランク 検 出 時 も 同 様 です 計 算 値 では 左 前 :60% 右 前 :35% 左 後 :48% 右 後 :24%ですが 実 際 は 違 う 値 の 方 が 右 クランクが 曲 がりやすいかもしれません いろいろ な PWM を 試 してみましょう 例 えば 内 輪 の 後 輪 の PWM を 小 さくした 方 が 曲 がりやすいかもしれません 左 クランククリア 時 も 同 様 です ステアリングモータに 加 える PWM の 上 限 を 設 定 しています サンプル プログラムは 50% 以 上 にならないようにしています この 数 値 が 小 さい と せっかくの PD 制 御 もこの 部 分 で 制 限 されてしまうのでステアリング モータの 反 応 が 遅 くなってしまいます 大 きすぎると 万 が 一 ステアリン グ 部 分 が 本 体 にぶつかってロックしてしまったときにステアリングモータ に 大 電 流 が 流 れてしまいます 最 初 は 50%として ライントレースが 安 定 したら 90% 程 度 にしてください 例 ) 869 : if( iret > 90 ) iret = 90; 870 : if( iret < -90 ) iret = -90; 111

9. 参 考 文 献 9. 参 考 文 献 ルネサス エレクトロニクス( 株 ) R8C/35C グループ ハードウェアマニュアル Rev.1.00 ルネサス エレクトロニクス( 株 ) M16C シリーズ,R8C ファミリ 用 C/C++コンパイラパッケージ V.6.00 C/C++コンパイラユーザーズマニュアル Rev.1.00 ルネサス エレクトロニクス( 株 ) High-performance Embedded Workshop V.4.09 ユーザーズマニュアル Rev.1.00 ルネサス 半 導 体 トレーニングセンター C 言 語 入 門 コーステキスト 第 1 版 電 波 新 聞 社 マイコン 入 門 講 座 大 須 賀 威 彦 著 第 1 版 ソフトバンク( 株 ) 新 C 言 語 入 門 シニア 編 林 晴 比 古 著 初 版 共 立 出 版 ( 株 ) プログラマのための ANSI C 全 書 L.Ammeraal 著 吉 田 敬 一 竹 内 淑 子 吉 田 恵 美 子 訳 初 版 マイコンカーラリー 販 売 部 品 についての 詳 しい 情 報 は マイコンカーラリー 販 売 サイトをご 覧 ください https://www2.himdx.net/mcr/ R8C マイコンについての 詳 しい 情 報 は ルネサス エレクトロニクス( 株 )のホームページをご 覧 ください http://japan.renesas.com/ の 製 品 情 報 にある マイコン R8C でご 覧 頂 けます 112