---
# System prepended metadata

title: 介面lab02

---

# 介面lab02
##### 助教疑問
- 用邏輯分析儀測量訊號![](https://i.imgur.com/iEl13xr.jpg)

- 說明TWI 另外名稱是什麼?原理?
    - 另外名稱:I²C，之所以改名為 Two Wire Interface (TWI) 是為了規避 I2C Bus 專利
    - 原理:透過SDA、SCL線，讓掛在這兩條線上的主裝置及僕裝置能夠「逐一位元」進行資料讀寫交換。
- M128TWI Slave 同時能很多個嗎?
    - (說明若可以是為什麼 不行又是為什麼)
    - 可以，TWI通訊協定中有一主多僕通訊架構，以及位址解碼功能，總共提供128個位址給不同的僕裝置
- 你還有一顆IC TCA9534A 沒做?
    - 已完成
- 告訴你現在bit rate傳送速率多少?
    - 287.5Kbps

## 工作日誌
* 7/15開始閱讀講義
* 7/29複習中斷
* 8/3硬體配線完成
## 程式碼
####    TCA9534
### 1. TCA9534A輸出七節管
```c
#include "c4mlib.h"
#define F_CPU 11059200UL

int main()
{
	C4M_DEVICE_set();
	
	char SLA=56;//Slave(僕)裝置的TWI ID
	char SevenSegTable[]={0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101,0b00000111,0b01111111,0b01101111};
		
	//---TWI串列通訊埠旗標群設定REGFPT---//
	REGFPT(&TWSR, 0x03, 0, 0);//設定TWI通訊工作時脈
	REGFPT(&TWCR, 0x01, 0, 1);//致能TWI通訊
	REGFPT(&TWCR, 0x04, 2, 1);//致能TWI中斷
	REGFPT(&TWAR, 0xFE, 1, SLA);//設定TWI編號 依據接線設定地址ADD
	REGFPT(&TWAR, 0x01, 0, 0);//選擇擴播關閉
	REGFPT(&DDRD, 0x03, 0, 3);//檢察並設定TWI通訊接腳為輸出
	
	//---TWI串列通訊埠暫存器設定REGPUT---//
	REGPUT(&TWBR, 1, 12);//設定TWI通訊工作時脈 TWBR預設值12
	
	//---設定TCA9534A暫存器參數TWIM_trm---//
	TWIM_trm(5, SLA, 0x02, 1, 0b00000000, 10);//設定極性反轉設定
	TWIM_trm(5, SLA, 0x03, 1, 0b00000000, 10);//設定輸出入方向設定
	
	while (1)
	{
		for (int i=0;i<10;i++)
		{
			printf("i=%d\n",i);
			TWIM_ftm(5, SLA, 0x01, 0xFF, 0, &SevenSegTable[i], 10);//輸出資料
			_delay_ms(700);
		}
		
	}
}


```
###    2.TCA9534A輸入
```c
#include "c4mlib.h"
#define F_CPU 11059200UL

int main()
{
	C4M_DEVICE_set();
	
	char SLA=56;//Slave(僕)裝置的TWI ID
	char InData;
		
	//---TWI串列通訊埠旗標群設定REGFPT---//
	REGFPT(&TWSR, 0x03, 0, 0);//設定TWI通訊工作時脈
	REGFPT(&TWCR, 0x01, 0, 1);//致能TWI通訊
	REGFPT(&TWCR, 0x04, 2, 1);//致能TWI中斷
	REGFPT(&TWAR, 0xFE, 1, SLA);//設定TWI編號 依據接線設定地址ADD
	REGFPT(&TWAR, 0x01, 0, 0);//選擇擴播關閉
	REGFPT(&DDRD, 0x03, 0, 3);//檢察並設定TWI通訊接腳為輸出
	
	//---TWI串列通訊埠暫存器設定REGPUT---//
	REGPUT(&TWBR, 1, 12);//設定TWI通訊工作時脈 TWBR預設值12
	
	//---設定TCA9534A暫存器參數TWIM_trm---//
	TWIM_trm(5, SLA, 0x02, 1, 0b00000000, 10);//設定極性反轉設定
	TWIM_trm(5, SLA, 0x03, 1, 0b00000000, 10);//設定輸出入方向設定
	
	while (1)
	{
		for (int i=0;i<10;i++)
		{
			TWIM_frc(5, SLA, 0x00, 0xFF, 0, &InData, 10);
			printf("InData=%d\n",InData);
			_delay_ms(700);
		}
	}
}


```
####    TMP175
### 1. 休眠模式下單發量測溫度
```c
#include "c4mlib.h"
#define F_CPU 11059200UL

uint8_t temp[2];//廣域2位元組讀值變數
	
int main()
{
	C4M_DEVICE_set();
	
	char SLA=72;//Slave(僕)裝置的TWI ID

	uint8_t Htemp[2]={30, 0};//高溫門檻設定[0]整數[1]小數
	uint8_t Ltemp[2]={28, 0};//低溫門檻設定[0]整數[1]小數
	uint8_t SD=0;//休眠模式設定旗標
	uint8_t TM=0;//溫度量測模式設定旗標
	uint8_t POL=1;//警告極性設定旗標(與TM旗標共同決定警告的波形)
	uint8_t F1F0=1;//警告延遲設定選擇旗標群
	uint8_t R1R0=0;//解析度設定選擇旗標群
	uint8_t OS=1;//單發控制旗標
	
	//---TWI串列通訊埠旗標群設定REGFPT---//
	REGFPT(&TWSR, 0x03, 0, 0);//設定TWI通訊工作時脈
	REGFPT(&TWCR, 0x01, 0, 1);//致能TWI通訊
	REGFPT(&TWCR, 0x04, 2, 1);//致能TWI中斷
	REGFPT(&TWAR, 0xFE, 1, SLA);//設定TWI編號 依據接線設定地址ADD
	REGFPT(&TWAR, 0x01, 0, 0);//選擇擴播關閉
	REGFPT(&DDRD, 0x03, 0, 3);//檢察並設定TWI通訊接腳為輸出
	
	//---TWI串列通訊埠暫存器設定REGPUT---//
	REGPUT(&TWBR, 1, 12);//設定TWI通訊工作時脈 TWBR預設值12
	
	//---TMP175暫存器旗標群參數設定TWIM_ftm---//
	TWIM_ftm(5, SLA, 0x01, 0x01, 0, &SD, 10);//設定休眠模式
	TWIM_ftm(5, SLA, 0x01, 0x60, 5, &R1R0, 10);//設定量測解析度0.5度C 9bits
	
	while (1)
	{
		TWIM_ftm(5, SLA, 0x01, 0x80, 7, &OS, 10);//設定單發模式量測溫度
		TWIM_rec(5, SLA, 0, 2, temp, 10);//讀取溫度
		printf("%d.%d C\n", temp[0], temp[1]*10/256);
		_delay_ms(1000);
	}
	
}
```
### 2. 比較模式下過溫度中斷警告
```c
#include "c4mlib.h"
#define F_CPU 11059200UL
uint8_t Interrupt=0;//中斷旗標
uint8_t temp[2];//廣域2位元組讀值變數

int main()
{
	C4M_DEVICE_set();
	
	char SLA=72;//Slave(僕)裝置的TWI ID
	uint8_t Htemp[2]={30, 0};//高溫門檻設定[0]整數[1]小數
	uint8_t Ltemp[2]={28, 0};//低溫門檻設定[0]整數[1]小數
	uint8_t SD=0;//休眠模式設定旗標
	uint8_t TM=0;//溫度量測模式設定旗標
	uint8_t POL=1;//警告極性設定旗標(與TM旗標共同決定警告的波形)
	uint8_t F1F0=1;//警告延遲設定選擇旗標群
	uint8_t R1R0=0;//解析度設定選擇旗標群
	uint8_t OS=0;//單發控制旗標
	
	
	//---TWI串列通訊埠旗標群設定REGFPT---//
	REGFPT(&TWSR, 0x03, 0, 0);//設定TWI通訊工作時脈
	REGFPT(&TWCR, 0x01, 0, 1);//致能TWI通訊
	REGFPT(&TWCR, 0x04, 2, 1);//致能TWI中斷
	REGFPT(&TWAR, 0xFE, 1, SLA);//設定TWI編號 依據接線設定地址ADD
	REGFPT(&TWAR, 0x01, 0, 0);//選擇擴播關閉
	REGFPT(&DDRD, 0x03, 0, 3);//檢察並設定TWI通訊接腳為輸出
	
	//---TWI串列通訊埠暫存器設定REGPUT---//
	REGPUT(&TWBR, 1, 12);//設定TWI通訊工作時脈 TWBR預設值12
	
	//---設定TMP175暫存器參數TWIM_trm---//
	TWIM_trm(5, SLA, 0x02, 2, Ltemp, 10);//設定低溫門檻
	TWIM_trm(5, SLA, 0x03, 2, Htemp, 10);//設定高溫門檻
	TWIM_rec(5, SLA, 0x02, 2, Ltemp, 10);
	TWIM_rec(5, SLA, 0x03, 2, Htemp, 10);
	printf("Ltemp=%d C\n",Ltemp[0]);
	printf("Htemp=%d C\n",Htemp[0]);
	
	//---TMP175暫存器旗標群參數設定TWIM_ftm---//
	TWIM_ftm(5, SLA, 0x01, 0x01, 0, &SD, 10);//設定休眠模式
	TWIM_ftm(5, SLA, 0x01, 0x02, 1, &TM, 10);//設定溫度比較模式TM=0
	TWIM_ftm(5, SLA, 0x01, 0x04, 2, &POL, 10);//設定Alert極性 POL HI
	TWIM_ftm(5, SLA, 0x01, 0x18, 3, &F1F0, 10);//設定延遲次數2
	TWIM_ftm(5, SLA, 0x01, 0x60, 5, &R1R0, 10);//設定量測解析度0.5度C 9bits
	
	//----外部中斷硬體設定----//
	REGFPT(&DDRE, 0x80, 7, 0);//設定外部中斷觸發源Port E7為輸入
	REGFPT(&EICRB, 0xC0, 6, 3);//設定上緣觸發
	REGFPT(&EIMSK, 0x80, 7, 1);//設定外部中斷致能
	sei();//致能中斷

	
	while (1)
	{
		TWIM_rec(5, SLA, 0, 2, temp, 10);//讀取溫度
		printf("Current temperature is %d.%d C\n", temp[0], temp[1]*10/256);
		if (Interrupt==1)
		{
			if (temp[0]<Htemp[0])
			{
				Interrupt=0;
			}
		}
		_delay_ms(500);
	}
}

ISR(INT7_vect)
{
	Interrupt=1;
	printf("High temperature alert\n");
}

```

### 3. 量測模式下固定週期量測並顯示
```c
#include "c4mlib.h"
#define F_CPU 11059200UL

uint8_t Interrupt=0;//中斷旗標
uint8_t temp[2];//廣域2位元組讀值變數
char SLA=72;//Slave(僕)裝置的TWI ID

int main()
{
	C4M_DEVICE_set();
	
	uint8_t Htemp[2]={30, 0};//高溫門檻設定[0]整數[1]小數
	uint8_t Ltemp[2]={28, 0};//低溫門檻設定[0]整數[1]小數
	uint8_t SD=0;//休眠模式設定旗標
	uint8_t TM=1;//溫度量測模式設定旗標
	uint8_t POL=1;//警告極性設定旗標(與TM旗標共同決定警告的波形)
	uint8_t F1F0=1;//警告延遲設定選擇旗標群
	uint8_t R1R0=0;//解析度設定選擇旗標群
	uint8_t OS=0;//單發控制旗標
	
	//---TWI串列通訊埠旗標群設定REGFPT---//
	REGFPT(&TWSR, 0x03, 0, 0);//設定TWI通訊工作時脈
	REGFPT(&TWCR, 0x01, 0, 1);//致能TWI通訊
	REGFPT(&TWCR, 0x04, 2, 1);//致能TWI中斷
	REGFPT(&TWAR, 0xFE, 1, SLA);//設定TWI編號 依據接線設定地址ADD
	REGFPT(&TWAR, 0x01, 0, 0);//選擇擴播關閉
	REGFPT(&DDRD, 0x03, 0, 3);//檢察並設定TWI通訊接腳為輸出
	
	//---TWI串列通訊埠暫存器設定REGPUT---//
	REGPUT(&TWBR, 1, 12);//設定TWI通訊工作時脈 TWBR預設值12
	
	//---設定TMP175暫存器參數TWIM_trm---//
	TWIM_trm(5, SLA, 0x02, 2, Ltemp, 10);//設定低溫門檻
	TWIM_trm(5, SLA, 0x03, 2, Htemp, 10);//設定高溫門檻
	
	//---TMP175暫存器旗標群參數設定TWIM_ftm---//
	TWIM_ftm(5, SLA, 0x01, 0x01, 0, &SD, 10);//設定休眠模式
	TWIM_ftm(5, SLA, 0x01, 0x02, 1, &TM, 10);//設定溫度比較模式TM=1
	TWIM_ftm(5, SLA, 0x01, 0x04, 2, &POL, 10);//設定Alert極性 POL HI
	TWIM_ftm(5, SLA, 0x01, 0x18, 3, &F1F0, 10);//設定延遲次數2
	TWIM_ftm(5, SLA, 0x01, 0x60, 5, &R1R0, 10);//設定量測解析度0.5度C 9bits
	
	//----計時中斷硬體設定----//
	REGFPT(&TCCR2,0x48,3,1);//TIME2波形模式選擇方波
	REGFPT(&TCCR2,0x07,0,5);//TIME2FreqDivide除頻值設定(除頻Clk/1024)
	REGFPT(&TCCR2,0x30,4,1);//TIME2WareOut波形輸出致能
	REGFPT(&TIMSK,0x80,7,1);//設定TIM2接腳輸出
	uint16_t Data=215;//OCR2=215 Focn=25 Hz
	REGPUT(&OCR2,1,Data);//set OCR2
	sei();//致能中斷
	
	while (1)
	{
		if (Interrupt==1)
		{
			
			if (temp[0]>=Htemp[0])
			{
				printf("High temperature alert\n");
			}
			else if (temp[0]<Ltemp[0])
			{
				printf("Low temperature alert\n");
			}
			Interrupt=0;
			
		}
		_delay_ms(500);
	}
	
}

ISR(TIMER2_COMP_vect)//40ms
{
	TWIM_rec(5, SLA, 0, 2, temp, 10);//讀取溫度
	printf("Current temperature is %d.%d C\n", temp[0], temp[1]*10/256);
	Interrupt=1;
}


```



## 流程圖
####      TCA9534A
###    1.TCA9534A輸出
![](https://i.imgur.com/xiiGiNk.png)

###    2.TCA9534A輸入
![](https://i.imgur.com/U5IQCbU.png)

####    TMP175
### 1. 休眠模式下單發量測溫度
![](https://i.imgur.com/LUXm7XX.png)

### 2. 比較模式下過溫度中斷警告
![](https://i.imgur.com/nMEqse8.png)

### 3. 量測模式下固定週期量測並顯示
![](https://i.imgur.com/L1nMkDE.png)



## 實驗數據
####      TCA9534A
###    1.TCA9534A輸出
![](https://i.imgur.com/pxqQvbv.jpg)
![](https://i.imgur.com/1NpDu3S.jpg)
![](https://i.imgur.com/9aGrXRM.jpg)

###    2.TCA9534A輸入
![](https://i.imgur.com/nLkL4mJ.jpg)
![](https://i.imgur.com/5Urrwtl.jpg)

####    TMP175
### 1. 休眠模式下單發量測溫度
#### 文字人機截圖![](https://i.imgur.com/89Oz2lK.jpg)

### 2. 比較模式下過溫度中斷警告
#### 文字人機截圖![](https://i.imgur.com/Vhgxjna.jpg)

### 3. 量測模式下固定週期量測並顯示
#### 文字人機截圖![](https://i.imgur.com/dvMeZYK.jpg)

#### 示波器量測ALERT波形
[請點我(觀看影片中3~4秒處)](https://ncu365-my.sharepoint.com/:v:/g/personal/oreo900930_office365_ncu_edu_tw/Ef7R6xVIIFBLunDGxIjY2W8BTAPnLte0QZTl6uJvfgkx-A?e=ZAfZp3)
## 驗收
### 驗收題目
* 將TMP175實時溫度顯示在七節管，到小數點第一位，並且可以單位F(華氏切換),C(攝氏)，用一顆按鈕接TCA9534a。
* 並且量測模式超過設定值，然後傳到matlab劃出兩條單位溫度曲線，且可以用matlab傳OFF訊息回MCU將七段顯示器，歸為單位C顯示0度溫度。
* 除頻值設置16，最後須達到bit rate 約138K左右
    * ![](https://i.imgur.com/EdgRtwH.png)
    * 根據計算 TWPS設為2 TWBR設為2

* 且請用邏輯分析儀或示波器顯示結果

    * ![](https://i.imgur.com/R78Bjub.png)


    
### 驗收成果

### 遭遇問題&問題解決
1. TCA9534A輸出至七節管 P3 P4腳位無法拉到HIGH
    * 測試從輸出0~9
    ![](https://i.imgur.com/9NDer2U.png)
    ```
    SevenSegTable[]={0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101,0b00000111,0b01111111,0b01101111};
    ```
    * 改輸出0b1111 1111
    ![](https://i.imgur.com/khKfXlc.png)
    * TCA9534A輸出至七節管 P3 P4腳位還是無法拉到HIGH
    * SDA/SCL通訊正常 是TCA9534A暫存器設定參數問題
2. 除頻值設置按照講義計算錯誤
    * 參考原始datasheet重新計算
    * ![](https://i.imgur.com/4dlbrex.png)

