SlideShare a Scribd company logo
1 of 8
ARM Cortex-M 韌體設計
119
I2
C 主控端同步串列通訊:BH1750 照度計控制應用
I2
C 同步串列通訊
,
是一種應用於晶片之間資料交換
,
主
(Master)
、
從
(Slave)
架構的通訊協定。硬體電路設計是採用雙向兩線式串列通訊匯流排,由 SCL 與
SDA 兩條訊號線
,
實現串列資料同步傳輸
。
傳輸速度通常是 100K bps 或 400K bps。
嵌入式系統的 MCU 通常會是 I2
C 的主控端(SCL 的控制訊號是由主控端控制輸
出)
。這個單元將會與與 BH1750FVI 實作 I2
C 通訊。這個單位練習需要兩個層面
的知識:
1. BH1750FVI 的通訊控制程序
2. I2
C 底層通訊的規範
BH1750 BH1750FVI 內部方塊圖
BH1750 連接 WengNano
120
BH1750FVI 量測處理程序
BH1750FVI 指令表
像 BH1750FVI 這類型,具有特定功能的模組;通常會有一些選項設定可以
提供使用者,有不同的使用方式。因此 BH1750FVI 的指令表中,也提供了多種
量測模式及不同的解析度,供使用者選擇。簡單來說:使用者必頇以 I2
C 的通訊
送出使用 BH1750 的操作命令,並依照 datasheet 的步驟取得量測結果。
121
在這個單元需要學習如何看懂很多的規格並能夠找到使用方法。而我們比較
感興趣的是如何取得 BH1750 量測結果。所以,我們先從 H-Resolution mode 的
範例著手:
Write instruction Read measurement result
我們詴著用紅色框線與青藍色框線來標式、區分,一個量測的操作是由 I2
C
的 寫(Write instruction) 、 等待 、 讀(Read measurement result) 等操作
步驟完成的。範例的操作過程有三個步驟:
1. Write instruction:這是 I2
C 寫操作,MCU 送出控制命令給 BH1750FVI。
2. 等待 BH1750FVI 完成量測的時間 180mS。
3. Read measurement result :這是 I2
C 讀操作,MCU 讀取量測結果。
著手設計 BH1750FVI 的驅動程式之前,先了解 H-Resolution mode 範例的圖例:
這個圖例是 MCU 在輸出資料(灰色底色)
這個圖例是 MCU 在讀取資料(白色底色)
125
BH1759 模組接腳與 GPIO 的關係對照表
這個單元的練習會分成兩個部份來設計:一是 I2C 底層驅動程式,二是
BH1750FVI 操作程序。
I2C 底層驅動程式,至少需要有四個函式:
1. i2c_start()
2. i2c_stop()
3. i2c_write()
4. i2c_read()
新增 I2C.c:
#include "Nano100Series.h"
#include "MyAPP.h"
#define ACK 0
#define NACK 1
#define RD 1
#define WR 0
#define DEVID 0x46
#define DIROD(p,b) GPIO_SetMode(p, (b), GPIO_PMD_OPEN_DRAIN)
#define DIROUT(p,b) GPIO_SetMode(p, (b), GPIO_PMD_OUTPUT)
#define DIRIN(p,b) GPIO_SetMode(p, (b), GPIO_PMD_INPUT)
建立一個共用型態的資料類型,在位元操作時會用到:
typedef union{
unsigned char v;
struct{
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
};
}TPU8;
126
增加 delay()
static void delay(int n){
int i;
for(i=0;i<n;i++){}
}
加入 i2c_start():這是 I2
C 通訊開始的階習,先將 GPIO 設定為 Open Drain 模式,
並且開啟提昇電阻的功能
void i2c_start(void){
DIR_OD(PF,4); DIR_OD(PF,5);
PF->PUEN |= BIT4+BIT5;
if(SDA==0){
SCL=0; delay(50);
}
SDA=1; delay(50);
SCL=1; delay(50);
SDA=0; delay(50);
SCL=0; delay(50);
}
增加 i2c_stop()
void i2c_stop(void){
SDA=0; delay(50);
SCL=1; delay(50);
SDA=1; delay(50);
}
增加 i2c_write()
uint8_t i2c_write(uint8_t d){
TPU8 r;
r.v = d;
SDA=r.b7; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b6; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b5; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b4; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b3; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b2; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b1; delay(0); SCL=1; delay(0); SCL=0;
SDA=r.b0; delay(0); SCL=1; delay(0); SCL=0;
//--- ACK
131
SPI 主控端同步串列通訊:無線通訊模組操作
#include "Nano100Series.h"
#pragma anon_unions
void TMR0_delaymS( volatile unsigned int n);
#define DIR_OUT(p, n) p->PMD = (p->PMD & ~(3<<(n<<1)))|(1<<(n<<1))
#define DIR_IN(p,n) p->PMD = (p->PMD & ~(3<<(n<<1)))
#define CE PA13
#define CS PA12
#define SCLK PC11
#define MOSI PC10
#define MISO PE12
#define IRQ PE11
//--- SPI
static uint8_t spi(uint8_t data){
union{
unsigned char v;
struct{
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
};
}r,d;
d.v = data;
//---
MOSI=d.b7; SCLK=1; r.b7=MISO; SCLK=0;
MOSI=d.b6; SCLK=1; r.b6=MISO; SCLK=0;
MOSI=d.b5; SCLK=1; r.b5=MISO; SCLK=0;
132
MOSI=d.b4; SCLK=1; r.b4=MISO; SCLK=0;
MOSI=d.b3; SCLK=1; r.b3=MISO; SCLK=0;
MOSI=d.b2; SCLK=1; r.b2=MISO; SCLK=0;
MOSI=d.b1; SCLK=1; r.b1=MISO; SCLK=0;
MOSI=d.b0; SCLK=1; r.b0=MISO; SCLK=0;
//---
return r.v;
}
//--- SETREG
static void setreg(uint8_t addr, uint8_t data){
CS=0;
spi(0x20 | addr);
spi(data);
CS=1;
}
//--- GETREG
static uint8_t getreg(uint8_t addr){
uint8_t r;
CS=0;
spi(addr);
r = spi(0);
CS=1;
return r;
}
//--- SEND PACKAGE
void send_pkg(char *p, int len){
int r,i;
CE=0;
//--- Payload
CS=0;
spi(0xA0); //Write Payload
for(i=0;i<len;i++){ spi(*p++); }
CS=1;
//---
CE=1;
TMR0_delaymS(1);
CE=0;
}

More Related Content

Similar to 節錄_ARM Cortex-M 韌體開發設計

物聯網技術分享 使用ESP8266
物聯網技術分享 使用ESP8266物聯網技術分享 使用ESP8266
物聯網技術分享 使用ESP8266Power Wu
 
HC 05藍芽模組連線
HC 05藍芽模組連線HC 05藍芽模組連線
HC 05藍芽模組連線Chen-Hung Hu
 
基于嵌入式系统的Avs P10编码系统设计
基于嵌入式系统的Avs P10编码系统设计基于嵌入式系统的Avs P10编码系统设计
基于嵌入式系统的Avs P10编码系统设计Hengyi
 
智慧家庭 簡報
智慧家庭 簡報智慧家庭 簡報
智慧家庭 簡報艾鍗科技
 
Sy03091说明书
Sy03091说明书Sy03091说明书
Sy03091说明书guest8f3690
 
嵌入式inux應用專題文件-智慧家庭系統
嵌入式inux應用專題文件-智慧家庭系統嵌入式inux應用專題文件-智慧家庭系統
嵌入式inux應用專題文件-智慧家庭系統艾鍗科技
 
20170415- 智慧空調通訊系統實務_柯大
20170415- 智慧空調通訊系統實務_柯大20170415- 智慧空調通訊系統實務_柯大
20170415- 智慧空調通訊系統實務_柯大MAKERPRO.cc
 
181201_CoAP_coding365
181201_CoAP_coding365181201_CoAP_coding365
181201_CoAP_coding365Peter Yi
 
第三章Ti msp430平台介紹 v3
第三章Ti msp430平台介紹 v3第三章Ti msp430平台介紹 v3
第三章Ti msp430平台介紹 v3冠宇 陳
 
Ch2 80x86计算机组织结构
Ch2 80x86计算机组织结构Ch2 80x86计算机组织结构
Ch2 80x86计算机组织结构bitistu
 
IEC104规约介绍
IEC104规约介绍IEC104规约介绍
IEC104规约介绍Chen Ray
 

Similar to 節錄_ARM Cortex-M 韌體開發設計 (20)

物聯網技術分享 使用ESP8266
物聯網技術分享 使用ESP8266物聯網技術分享 使用ESP8266
物聯網技術分享 使用ESP8266
 
Ch2 1
Ch2 1Ch2 1
Ch2 1
 
Arduino基礎IO控制
Arduino基礎IO控制Arduino基礎IO控制
Arduino基礎IO控制
 
HC 05藍芽模組連線
HC 05藍芽模組連線HC 05藍芽模組連線
HC 05藍芽模組連線
 
基于嵌入式系统的Avs P10编码系统设计
基于嵌入式系统的Avs P10编码系统设计基于嵌入式系统的Avs P10编码系统设计
基于嵌入式系统的Avs P10编码系统设计
 
系統程式 -- 第 2 章
系統程式 -- 第 2 章系統程式 -- 第 2 章
系統程式 -- 第 2 章
 
AMA 中級術科實作III
AMA 中級術科實作IIIAMA 中級術科實作III
AMA 中級術科實作III
 
Plc4
Plc4Plc4
Plc4
 
智慧家庭 簡報
智慧家庭 簡報智慧家庭 簡報
智慧家庭 簡報
 
Godson x86
Godson x86Godson x86
Godson x86
 
Sy03091说明书
Sy03091说明书Sy03091说明书
Sy03091说明书
 
嵌入式inux應用專題文件-智慧家庭系統
嵌入式inux應用專題文件-智慧家庭系統嵌入式inux應用專題文件-智慧家庭系統
嵌入式inux應用專題文件-智慧家庭系統
 
20170415- 智慧空調通訊系統實務_柯大
20170415- 智慧空調通訊系統實務_柯大20170415- 智慧空調通訊系統實務_柯大
20170415- 智慧空調通訊系統實務_柯大
 
Arduino序列通訊應用
Arduino序列通訊應用Arduino序列通訊應用
Arduino序列通訊應用
 
nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論
 
nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論nodeMCU IOT教學03 - NodeMCU導論
nodeMCU IOT教學03 - NodeMCU導論
 
181201_CoAP_coding365
181201_CoAP_coding365181201_CoAP_coding365
181201_CoAP_coding365
 
第三章Ti msp430平台介紹 v3
第三章Ti msp430平台介紹 v3第三章Ti msp430平台介紹 v3
第三章Ti msp430平台介紹 v3
 
Ch2 80x86计算机组织结构
Ch2 80x86计算机组织结构Ch2 80x86计算机组织结构
Ch2 80x86计算机组织结构
 
IEC104规约介绍
IEC104规约介绍IEC104规约介绍
IEC104规约介绍
 

節錄_ARM Cortex-M 韌體開發設計

  • 2. 119 I2 C 主控端同步串列通訊:BH1750 照度計控制應用 I2 C 同步串列通訊 , 是一種應用於晶片之間資料交換 , 主 (Master) 、 從 (Slave) 架構的通訊協定。硬體電路設計是採用雙向兩線式串列通訊匯流排,由 SCL 與 SDA 兩條訊號線 , 實現串列資料同步傳輸 。 傳輸速度通常是 100K bps 或 400K bps。 嵌入式系統的 MCU 通常會是 I2 C 的主控端(SCL 的控制訊號是由主控端控制輸 出) 。這個單元將會與與 BH1750FVI 實作 I2 C 通訊。這個單位練習需要兩個層面 的知識: 1. BH1750FVI 的通訊控制程序 2. I2 C 底層通訊的規範 BH1750 BH1750FVI 內部方塊圖 BH1750 連接 WengNano
  • 3. 120 BH1750FVI 量測處理程序 BH1750FVI 指令表 像 BH1750FVI 這類型,具有特定功能的模組;通常會有一些選項設定可以 提供使用者,有不同的使用方式。因此 BH1750FVI 的指令表中,也提供了多種 量測模式及不同的解析度,供使用者選擇。簡單來說:使用者必頇以 I2 C 的通訊 送出使用 BH1750 的操作命令,並依照 datasheet 的步驟取得量測結果。
  • 4. 121 在這個單元需要學習如何看懂很多的規格並能夠找到使用方法。而我們比較 感興趣的是如何取得 BH1750 量測結果。所以,我們先從 H-Resolution mode 的 範例著手: Write instruction Read measurement result 我們詴著用紅色框線與青藍色框線來標式、區分,一個量測的操作是由 I2 C 的 寫(Write instruction) 、 等待 、 讀(Read measurement result) 等操作 步驟完成的。範例的操作過程有三個步驟: 1. Write instruction:這是 I2 C 寫操作,MCU 送出控制命令給 BH1750FVI。 2. 等待 BH1750FVI 完成量測的時間 180mS。 3. Read measurement result :這是 I2 C 讀操作,MCU 讀取量測結果。 著手設計 BH1750FVI 的驅動程式之前,先了解 H-Resolution mode 範例的圖例: 這個圖例是 MCU 在輸出資料(灰色底色) 這個圖例是 MCU 在讀取資料(白色底色)
  • 5. 125 BH1759 模組接腳與 GPIO 的關係對照表 這個單元的練習會分成兩個部份來設計:一是 I2C 底層驅動程式,二是 BH1750FVI 操作程序。 I2C 底層驅動程式,至少需要有四個函式: 1. i2c_start() 2. i2c_stop() 3. i2c_write() 4. i2c_read() 新增 I2C.c: #include "Nano100Series.h" #include "MyAPP.h" #define ACK 0 #define NACK 1 #define RD 1 #define WR 0 #define DEVID 0x46 #define DIROD(p,b) GPIO_SetMode(p, (b), GPIO_PMD_OPEN_DRAIN) #define DIROUT(p,b) GPIO_SetMode(p, (b), GPIO_PMD_OUTPUT) #define DIRIN(p,b) GPIO_SetMode(p, (b), GPIO_PMD_INPUT) 建立一個共用型態的資料類型,在位元操作時會用到: typedef union{ unsigned char v; struct{ unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; unsigned b5:1; unsigned b6:1; unsigned b7:1; }; }TPU8;
  • 6. 126 增加 delay() static void delay(int n){ int i; for(i=0;i<n;i++){} } 加入 i2c_start():這是 I2 C 通訊開始的階習,先將 GPIO 設定為 Open Drain 模式, 並且開啟提昇電阻的功能 void i2c_start(void){ DIR_OD(PF,4); DIR_OD(PF,5); PF->PUEN |= BIT4+BIT5; if(SDA==0){ SCL=0; delay(50); } SDA=1; delay(50); SCL=1; delay(50); SDA=0; delay(50); SCL=0; delay(50); } 增加 i2c_stop() void i2c_stop(void){ SDA=0; delay(50); SCL=1; delay(50); SDA=1; delay(50); } 增加 i2c_write() uint8_t i2c_write(uint8_t d){ TPU8 r; r.v = d; SDA=r.b7; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b6; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b5; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b4; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b3; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b2; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b1; delay(0); SCL=1; delay(0); SCL=0; SDA=r.b0; delay(0); SCL=1; delay(0); SCL=0; //--- ACK
  • 7. 131 SPI 主控端同步串列通訊:無線通訊模組操作 #include "Nano100Series.h" #pragma anon_unions void TMR0_delaymS( volatile unsigned int n); #define DIR_OUT(p, n) p->PMD = (p->PMD & ~(3<<(n<<1)))|(1<<(n<<1)) #define DIR_IN(p,n) p->PMD = (p->PMD & ~(3<<(n<<1))) #define CE PA13 #define CS PA12 #define SCLK PC11 #define MOSI PC10 #define MISO PE12 #define IRQ PE11 //--- SPI static uint8_t spi(uint8_t data){ union{ unsigned char v; struct{ unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b4:1; unsigned b5:1; unsigned b6:1; unsigned b7:1; }; }r,d; d.v = data; //--- MOSI=d.b7; SCLK=1; r.b7=MISO; SCLK=0; MOSI=d.b6; SCLK=1; r.b6=MISO; SCLK=0; MOSI=d.b5; SCLK=1; r.b5=MISO; SCLK=0;
  • 8. 132 MOSI=d.b4; SCLK=1; r.b4=MISO; SCLK=0; MOSI=d.b3; SCLK=1; r.b3=MISO; SCLK=0; MOSI=d.b2; SCLK=1; r.b2=MISO; SCLK=0; MOSI=d.b1; SCLK=1; r.b1=MISO; SCLK=0; MOSI=d.b0; SCLK=1; r.b0=MISO; SCLK=0; //--- return r.v; } //--- SETREG static void setreg(uint8_t addr, uint8_t data){ CS=0; spi(0x20 | addr); spi(data); CS=1; } //--- GETREG static uint8_t getreg(uint8_t addr){ uint8_t r; CS=0; spi(addr); r = spi(0); CS=1; return r; } //--- SEND PACKAGE void send_pkg(char *p, int len){ int r,i; CE=0; //--- Payload CS=0; spi(0xA0); //Write Payload for(i=0;i<len;i++){ spi(*p++); } CS=1; //--- CE=1; TMR0_delaymS(1); CE=0; }