---
# System prepended metadata

title: 介面實驗二

---

# 介面實驗二   
## 工作日誌
> [time=Tue, Jul 26, 2022 11:10 PM]
1. 研究DATASHEET和TWI多日，今天總算透過TCA9534A了解TWI運作原理，也知道如何傳送接收資料了，像是下面的遭遇問題裡提到的，原本只設定0X01暫存器，然後直接輸出DATA當作他們的輸出入是錯的，透過同學提醒以及重讀DATASHEET了解需要先透過0X03暫存器設定接腳的輸出入，再看要讀或寫資料去做設定。接下來要讀TMP175這顆IC去做出實驗的需求。
> [time=Thu, Jul 28, 2022 1:29 AM]
2. 已做完TMP175休眠模式，程式碼後續補上。
> [time=Thu, Jul 28, 2022 5:45 PM]
3. 已做完比較與中斷模式，程式碼也都補上了，剩下流程圖，今晚畫完明天驗收。
## 實驗目的
* 了解TWI原理
* 透過TCA9534A這顆IC理解如何透過TWI接收或傳送資料
* 利用TMP175執行溫度感測
## 實驗步驟
1. 讀各IC的datasheet
2. 使用TCA9534A控制，了解TWI如何運作
3. TMP175做出溫度感測
## 流程圖
1. TWI傳送資料
![](https://i.imgur.com/bNJDmJR.jpg)
2. 接收資料
![](https://i.imgur.com/ud98PPF.jpg)
![](https://i.imgur.com/UtAanLe.jpg)
3. TCA9534A運作流程
![](https://i.imgur.com/U0hJISS.jpg)
4. TMP175單發量測模式
![](https://i.imgur.com/PQGAPxy.jpg)
5. TMP175比較模式
![](https://i.imgur.com/4GXlBEG.jpg)
6. TMP175中斷模式
![](https://i.imgur.com/sQVzbSY.jpg)

## 程式碼
1. C語言->TCA9534A接收資訊與傳送資訊
```C=
#include "c4mlib.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "TWI.cfg"

void TWI_STOP();
void TWI_START();
void TWI_sent_byte(unsigned char data);
void data_write(int clc);
unsigned char TWI_Receive_ACK();
unsigned char TWI_Receive_NACK();
void data_read();
//  Status Code for Master Transmitter
#define MT_START            0x08           // Start condition has been transmitted
#define MT_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MT_SLA_W_ACK        0x18           // SLA+W has been transmitted and ACK has been received
#define MT_SLA_W_NACK       0x20           // SLA+W has been transmitted and NOT ACK has been received
#define MT_DATA_ACK         0x28           // Data byte has been transmitted and ACK has been received
#define MT_DATA_NACK        0x30           // Data byte has been transmitted and NOT ACK has been received
#define MT_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+W or data bytes

#define MR_START            0x08           // Start condition has been transmitted
#define MR_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MR_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+R or NOT ACK bit
#define MR_SLA_R_ACK        0x40           // SLA+R has been transmitted and ACK has been received
#define MR_SLA_R_NACK       0x48           // SLA+R has been transmitted and NOT ACK has been received
#define MR_DATA_ACK         0x50           // DATA has been received and ACK has been returned
#define MR_DATA_NACK        0x58           // DATA has been received and NOT ACK has been returned
#define SLA_W               0x70		   //IC ADDRESS AND WRITE
#define SLA_R               0x71		   //IC ADDRESS AND READ
#define input_port          0x00
void TWI_setup(){
   /*
   * System Frequency vs Bit Rate generator register setting
   * ----------------------------------------------------------------
   * | CPU clock frequency [MHz]| TWBR | TWPS | SCL Frequency [KHz] |
   * ----------------------------------------------------------------
   * | 16                       |  12  |  0   |  400                |
   * ----------------------------------------------------------------
   * | 16                       |  72  |  0   |  100                |
   * ----------------------------------------------------------------
   */ 
  TWBR = 72;
  TWSR &= ~((1<<TWPS1)|(1<<TWPS0));  // TWBR = 72,and TWSP[1:0]= 0 for setting bit rate as 100K bps
  TWCR = (1<<TWEN);                  // enable TWI
}

int main(void) {
	C4M_DEVICE_set();
	int clc;
	TWI_setup();
	while(1)
	{
		printf("input clc\n");
		scanf("%d",&clc);
		if(clc==1)//設定腳位輸出輸入
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==2)//輸出訊號進入p腳位
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==3)
		{
			TWI_START();
			data_read();
			TWI_STOP();
		}
		
	}
	printf("end\n");
	return 0;
}

void TWI_START(){
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);       // start condition TWINT=7 TWSTA=5 TWEN=2
	while(!(TWCR & (1<<TWINT)));                  // wait till complete and wait for TWINT flag set
}

void TWI_STOP(){
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);       // stop condition TWINT=7 TWSTO=4 TWEN=2
	while(!(TWCR & (1<<TWSTO)));                  // wait till stop condition has been sent
	printf("stop\n");
}

void TWI_sent_byte(unsigned char data){
	TWDR = data;                                  // put data into TWDR
	TWCR = (1<<TWINT)|(1<<TWEN);
	while(!(TWCR & (1<<TWINT)));                  // wait for TWINT flag set
	//printf("data=%d\n",TWDR);
}

void data_write(int clc)
{
	unsigned char mydata[2]={0x03,0xFF};
	unsigned char mydata_out[2]={0x01,0xFF};
	if((TWSR & 0xF8) != MT_START)
	{
		// TWI error
		TWI_STOP();									                     // STOP TWI
	}
	else
	{
		printf("TWSR=%d\n",TWSR);
		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("sec_twsr=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			for(unsigned int i=0;i<2;i++)
			{
				_delay_ms(100);
				if (clc==1)
				{
					TWI_sent_byte(mydata[i]);
				}
				else if(clc==2)
				{
					TWI_sent_byte(mydata_out[i]);
				}
				if((TWSR & 0xF8) == MT_DATA_ACK)
				{
					printf("TWDR=%d\n",TWDR);
					printf("TWSR=%d\n",TWSR);
					continue;
				}
				else
				{
					// TWI error
					TWI_STOP();									               // STOP TWI
					break;
				}
			}
		}
		
	}
}

unsigned char TWI_Receive_ACK(){
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);        // data has been received and return ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

unsigned char TWI_Receive_NACK(){
	TWCR = (1<<TWINT)|(1<<TWEN);                  // data has been received and return NOT ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

void data_read()
{
	unsigned char received_data[1]={};
	int input=0;
	if((TWSR & 0xF8)!=MR_START)
	{
		TWI_STOP();
	}
	else
	{

		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("TWSR=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			_delay_ms(100);
			TWI_sent_byte(input_port);	
			if((TWSR & 0xF8) == MT_DATA_ACK)
			{
				TWI_START();
				if((TWSR & 0xF8)!=MR_REPEAT_START)
				{
					printf("TWSR=%d\n",TWSR);
					
					TWI_STOP();
				}
				else
				{
					printf("TWSR=%d\n",TWSR);
					TWI_sent_byte(SLA_R);
					if((TWSR & 0xF8) != MR_SLA_R_ACK)
					{
						// TWI error
						printf("TWSR=%d\n",TWSR);
						TWI_STOP();									               // STOP TWI
					}
					else
					{
						printf("TWSR=%d\n",TWSR);
						received_data[0] = TWI_Receive_NACK();	  // store data in data array and return ACK
						input=received_data[0];
						if ((TWSR & 0xF8) != MR_DATA_NACK)
						{
							// TWI error
							printf("TWSR=%d\n",TWSR);
							TWI_STOP();									               // STOP TWI
						}
						else
						{
							printf("TWSR=%d\n",TWSR);
							
						}
					}
				}
				
			}
			else
			{
				// TWI error
				printf("TWSR=%d\n",TWSR);
				TWI_STOP();									               // STOP TWI
			}
			
		}
	}
	printf("input=%d\n",input);
}


```
2.休眠模式下單發量測
```c=
#include "c4mlib.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "TWI.cfg"

void TWI_STOP();
void TWI_START();
void TWI_sent_byte(unsigned char data);
void data_write(int clc);
unsigned char TWI_Receive_ACK();
unsigned char TWI_Receive_NACK();
void data_read();
//  Status Code for Master Transmitter
#define MT_START            0x08           // Start condition has been transmitted
#define MT_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MT_SLA_W_ACK        0x18           // SLA+W has been transmitted and ACK has been received
#define MT_SLA_W_NACK       0x20           // SLA+W has been transmitted and NOT ACK has been received
#define MT_DATA_ACK         0x28           // Data byte has been transmitted and ACK has been received
#define MT_DATA_NACK        0x30           // Data byte has been transmitted and NOT ACK has been received
#define MT_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+W or data bytes

#define MR_START            0x08           // Start condition has been transmitted
#define MR_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MR_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+R or NOT ACK bit
#define MR_SLA_R_ACK        0x40           // SLA+R has been transmitted and ACK has been received
#define MR_SLA_R_NACK       0x48           // SLA+R has been transmitted and NOT ACK has been received
#define MR_DATA_ACK         0x50           // DATA has been received and ACK has been returned
#define MR_DATA_NACK        0x58           // DATA has been received and NOT ACK has been returned
#define SLA_W               0x90		   //IC ADDRESS AND WRITE
#define SLA_R               0x91		   //IC ADDRESS AND READ
#define TEM_reg				0x00
void TWI_setup(){
   /*
   * System Frequency vs Bit Rate generator register setting
   * ----------------------------------------------------------------
   * | CPU clock frequency [MHz]| TWBR | TWPS | SCL Frequency [KHz] |
   * ----------------------------------------------------------------
   * | 16                       |  12  |  0   |  400                |
   * ----------------------------------------------------------------
   * | 16                       |  72  |  0   |  100                |
   * ----------------------------------------------------------------
   */ 
  TWBR = 72;
  TWSR &= ~((1<<TWPS1)|(1<<TWPS0));  // TWBR = 72,and TWSP[1:0]= 0 for setting bit rate as 100K bps
  TWCR = (1<<TWEN);                  // enable TWI
}

int main(void) {
	C4M_DEVICE_set();
	int clc;
	TWI_setup();
	while(1)
	{
		printf("input clc\n");
		scanf("%d",&clc);
		if(clc==1)//設定休眠模式
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==2)//輸出訊號進入p腳位
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==3)//讀取溫度
		{
			TWI_START();
			data_read();
			TWI_STOP();
		}
		
	}
	printf("end\n");
	return 0;
}

void TWI_START(){
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);       // start condition TWINT=7 TWSTA=5 TWEN=2
	while(!(TWCR & (1<<TWINT)));                  // wait till complete and wait for TWINT flag set
}

void TWI_STOP(){
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);       // stop condition TWINT=7 TWSTO=4 TWEN=2
	while(!(TWCR & (1<<TWSTO)));                  // wait till stop condition has been sent
	printf("stop\n");
}

void TWI_sent_byte(unsigned char data){
	TWDR = data;                                  // put data into TWDR
	TWCR = (1<<TWINT)|(1<<TWEN);
	while(!(TWCR & (1<<TWINT)));                  // wait for TWINT flag set
	//printf("data=%d\n",TWDR);
}

void data_write(int clc)
{
	unsigned char mydata[2]={0x01,0xE1};
	unsigned char mydata_out[2]={0x01,0xFF};
	if((TWSR & 0xF8) != MT_START)
	{
		// TWI error
		TWI_STOP();									                     // STOP TWI
	}
	else
	{
		printf("TWSR=%d\n",TWSR);
		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("sec_twsr=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			for(unsigned int i=0;i<2;i++)
			{
				if (clc==1)
				{
					TWI_sent_byte(mydata[i]);
				}
				else if(clc==2)
				{
					TWI_sent_byte(mydata_out[i]);
				}
				if((TWSR & 0xF8) == MT_DATA_ACK)
				{
					printf("TWDR=%d\n",TWDR);
					printf("TWSR=%d\n",TWSR);
					continue;
				}
				else
				{
					// TWI error
					printf("TWSR=%d\n",TWSR);
					printf("TWDR=%d\n",TWDR);
					printf("data fail\n");
					TWI_STOP();									               // STOP TWI
					break;
				}
			}
		}
		
	}
}

unsigned char TWI_Receive_ACK(){
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);        // data has been received and return ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

unsigned char TWI_Receive_NACK(){
	TWCR = (1<<TWINT)|(1<<TWEN);                  // data has been received and return NOT ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

void data_read()
{
	unsigned char received_data[2]={};
	float input_hi=0,input_low=0,input=0;
	if((TWSR & 0xF8)!=MR_START)
	{
		TWI_STOP();
	}
	else
	{

		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("TWSR=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			TWI_sent_byte(TEM_reg);	
			if((TWSR & 0xF8) == MT_DATA_ACK)
			{
				TWI_START();
				if((TWSR & 0xF8)!=MR_REPEAT_START)
				{
					printf("TWSR=%d\n",TWSR);
					
					TWI_STOP();
				}
				else
				{
					printf("TWSR=%d\n",TWSR);
					TWI_sent_byte(SLA_R);
					if((TWSR & 0xF8) != MR_SLA_R_ACK)
					{
						// TWI error
						printf("TWSR=%d\n",TWSR);
						TWI_STOP();									               // STOP TWI
					}
					else
					{
						printf("TWSR=%d\n",TWSR);
						received_data[0] = TWI_Receive_ACK();	  // store data in data array and return ACK
						input_hi=received_data[0];
						if ((TWSR & 0xF8) != MR_DATA_ACK)
						{
							// TWI error
							printf("TWSR=%d\n",TWSR);
							TWI_STOP();									               // STOP TWI
						}
						else
						{
							input_low = ((TWI_Receive_NACK()>> 4)+1)*0.0625;
							printf("TWSR=%d\n",TWSR);
						}
					}
				}
				
			}
			else
			{
				// TWI error
				printf("TWSR=%d\n",TWSR);
				TWI_STOP();									               // STOP TWI
			}
			
		}
	}
	input=input_hi+input_low;
	printf("temperature=%f\n",input);
}


```
3. 比較模式下溫度中斷警告
```c=
#include "c4mlib.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "TWI.cfg"

void TWI_STOP();
void TWI_START();
void TWI_sent_byte(unsigned char data);
void data_write(int clc);
unsigned char TWI_Receive_ACK();
unsigned char TWI_Receive_NACK();
void data_read();
//  Status Code for Master Transmitter
#define MT_START            0x08           // Start condition has been transmitted
#define MT_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MT_SLA_W_ACK        0x18           // SLA+W has been transmitted and ACK has been received
#define MT_SLA_W_NACK       0x20           // SLA+W has been transmitted and NOT ACK has been received
#define MT_DATA_ACK         0x28           // Data byte has been transmitted and ACK has been received
#define MT_DATA_NACK        0x30           // Data byte has been transmitted and NOT ACK has been received
#define MT_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+W or data bytes

#define MR_START            0x08           // Start condition has been transmitted
#define MR_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MR_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+R or NOT ACK bit
#define MR_SLA_R_ACK        0x40           // SLA+R has been transmitted and ACK has been received
#define MR_SLA_R_NACK       0x48           // SLA+R has been transmitted and NOT ACK has been received
#define MR_DATA_ACK         0x50           // DATA has been received and ACK has been returned
#define MR_DATA_NACK        0x58           // DATA has been received and NOT ACK has been returned
#define SLA_W               0x90		   //IC ADDRESS AND WRITE
#define SLA_R               0x91		   //IC ADDRESS AND READ
#define TEM_reg				0x00

void TWI_setup(){
   /*
   * System Frequency vs Bit Rate generator register setting
   * ----------------------------------------------------------------
   * | CPU clock frequency [MHz]| TWBR | TWPS | SCL Frequency [KHz] |
   * ----------------------------------------------------------------
   * | 16                       |  12  |  0   |  400                |
   * ----------------------------------------------------------------
   * | 16                       |  72  |  0   |  100                |
   * ----------------------------------------------------------------
   */ 
  TWBR = 72;
  TWSR &= ~((1<<TWPS1)|(1<<TWPS0));  // TWBR = 72,and TWSP[1:0]= 0 for setting bit rate as 100K bps
  TWCR = (1<<TWEN);                  // enable TWI
}

int main(void) {
	C4M_DEVICE_set();
	int clc;
	TWI_setup();
	REGFPT(&DDRE,0x20,0,0);//設定E5為輸入
	REGFPT(&EICRB,0x0C,2,2);//設定外部中斷觸發訊號偵測模式(下降元觸發)
	REGFPT(&EIMSK,0x20,5,1);//設定外部中斷禁致能
	sei();
	while(1)
	{
		printf("input clc\n");
		printf("1=config 2=temperature_low 3=temperature_high 4=temperature_get\n");
		scanf("%d",&clc);
		if(clc==1)//設定比較模式
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==2)//設定低溫暫存器
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==3)//設定高溫暫存器
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==4)//讀取溫度
		{
			TWI_START();
			data_read();
			TWI_STOP();
		}
		
	}
	printf("end\n");
	return 0;
}

void TWI_START(){
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);       // start condition TWINT=7 TWSTA=5 TWEN=2
	while(!(TWCR & (1<<TWINT)));                  // wait till complete and wait for TWINT flag set
}

void TWI_STOP(){
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);       // stop condition TWINT=7 TWSTO=4 TWEN=2
	while(!(TWCR & (1<<TWSTO)));                  // wait till stop condition has been sent
	printf("stop\n");
}

void TWI_sent_byte(unsigned char data){
	TWDR = data;                                  // put data into TWDR
	TWCR = (1<<TWINT)|(1<<TWEN);
	while(!(TWCR & (1<<TWINT)));                  // wait for TWINT flag set
	//printf("data=%d\n",TWDR);
}

void data_write(int clc)
{
	unsigned char mydata[2]={0x01,0x60};//設定config
	unsigned char mydata_lowlimit[2]={0x02,0x1C};//設定低溫暫存器28度
	unsigned char mydata_hignlimit[2]={0x03,0x1D};//設定高溫暫存器29度
	if((TWSR & 0xF8) != MT_START)
	{
		// TWI error
		TWI_STOP();									                     // STOP TWI
	}
	else
	{
		printf("TWSR=%d\n",TWSR);
		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("sec_twsr=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			for(unsigned int i=0;i<2;i++)
			{
				if (clc==1)
				{
					TWI_sent_byte(mydata[i]);
				}
				else if(clc==2)
				{
					TWI_sent_byte(mydata_lowlimit[i]);
				}
				else if(clc==3)
				{
					TWI_sent_byte(mydata_hignlimit[i]);
				}
				if((TWSR & 0xF8) == MT_DATA_ACK)
				{
					printf("TWDR=%d\n",TWDR);
					printf("TWSR=%d\n",TWSR);
					continue;
				}
				else
				{
					// TWI error
					printf("TWSR=%d\n",TWSR);
					printf("TWDR=%d\n",TWDR);
					printf("data fail\n");
					TWI_STOP();									               // STOP TWI
					break;
				}
			}
		}
		
	}
}

unsigned char TWI_Receive_ACK(){
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);        // data has been received and return ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

unsigned char TWI_Receive_NACK(){
	TWCR = (1<<TWINT)|(1<<TWEN);                  // data has been received and return NOT ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

void data_read()
{
	unsigned char received_data[2]={};
	float input_hi=0,input_low=0,input=0;
	if((TWSR & 0xF8)!=MR_START)
	{
		TWI_STOP();
	}
	else
	{

		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("TWSR=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			TWI_sent_byte(TEM_reg);	
			if((TWSR & 0xF8) == MT_DATA_ACK)
			{
				TWI_START();
				if((TWSR & 0xF8)!=MR_REPEAT_START)
				{
					printf("TWSR=%d\n",TWSR);
					
					TWI_STOP();
				}
				else
				{
					printf("TWSR=%d\n",TWSR);
					TWI_sent_byte(SLA_R);
					if((TWSR & 0xF8) != MR_SLA_R_ACK)
					{
						// TWI error
						printf("TWSR=%d\n",TWSR);
						TWI_STOP();									               // STOP TWI
					}
					else
					{
						printf("TWSR=%d\n",TWSR);
						received_data[0] = TWI_Receive_ACK();	  // store data in data array and return ACK
						input_hi=received_data[0];
						if ((TWSR & 0xF8) != MR_DATA_ACK)
						{
							// TWI error
							printf("TWSR=%d\n",TWSR);
							TWI_STOP();									               // STOP TWI
						}
						else
						{
							input_low = ((TWI_Receive_NACK()>> 4)+1)*0.0625;
							printf("TWSR=%d\n",TWSR);
						}
					}
				}
				
			}
			else
			{
				// TWI error
				printf("TWSR=%d\n",TWSR);
				TWI_STOP();									               // STOP TWI
			}
			
		}
	}
	input=input_hi+input_low;
	printf("temperature=%f\n",input);
}

ISR(INT5_vect)
{
	printf("too high or too low\n");
}


```
4.TMP interrupt mode
```c=
#include "c4mlib.h"
#include "math.h"
#include "stdlib.h"
#include "stdio.h"
#include "TWI.cfg"

void TWI_STOP();
void TWI_START();
void TWI_sent_byte(unsigned char data);
void data_write(int clc);
unsigned char TWI_Receive_ACK();
unsigned char TWI_Receive_NACK();
void data_read();
//  Status Code for Master Transmitter
#define MT_START            0x08           // Start condition has been transmitted
#define MT_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MT_SLA_W_ACK        0x18           // SLA+W has been transmitted and ACK has been received
#define MT_SLA_W_NACK       0x20           // SLA+W has been transmitted and NOT ACK has been received
#define MT_DATA_ACK         0x28           // Data byte has been transmitted and ACK has been received
#define MT_DATA_NACK        0x30           // Data byte has been transmitted and NOT ACK has been received
#define MT_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+W or data bytes

#define MR_START            0x08           // Start condition has been transmitted
#define MR_REPEAT_START     0x10           // Repeat Start condition has been transmitted
#define MR_LOST_ARBITRATION 0x38           // Arbitration lost in SLA+R or NOT ACK bit
#define MR_SLA_R_ACK        0x40           // SLA+R has been transmitted and ACK has been received
#define MR_SLA_R_NACK       0x48           // SLA+R has been transmitted and NOT ACK has been received
#define MR_DATA_ACK         0x50           // DATA has been received and ACK has been returned
#define MR_DATA_NACK        0x58           // DATA has been received and NOT ACK has been returned
#define SLA_W               0x90		   //IC ADDRESS AND WRITE
#define SLA_R               0x91		   //IC ADDRESS AND READ
#define TEM_reg				0x00

void TWI_setup(){
   /*
   * System Frequency vs Bit Rate generator register setting
   * ----------------------------------------------------------------
   * | CPU clock frequency [MHz]| TWBR | TWPS | SCL Frequency [KHz] |
   * ----------------------------------------------------------------
   * | 16                       |  12  |  0   |  400                |
   * ----------------------------------------------------------------
   * | 16                       |  72  |  0   |  100                |
   * ----------------------------------------------------------------
   */ 
  TWBR = 72;
  TWSR &= ~((1<<TWPS1)|(1<<TWPS0));  // TWBR = 72,and TWSP[1:0]= 0 for setting bit rate as 100K bps
  TWCR = (1<<TWEN);                  // enable TWI
}

int main(void) {
	C4M_DEVICE_set();
	int clc;
	TWI_setup();
	REGFPT(&DDRE,0x20,0,0);//設定E5為輸入
	REGFPT(&EICRB,0x0C,2,2);//設定外部中斷觸發訊號偵測模式(下降元觸發)
	REGFPT(&EIMSK,0x20,5,1);//設定外部中斷禁致能
	sei();
	while(1)
	{
		printf("input clc\n");
		printf("1=config 2=temperature_low 3=temperature_high 4=temperature_get\n");
		scanf("%d",&clc);
		if(clc==1)//設定中斷模式
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==2)//設定低溫暫存器
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==3)//設定高溫暫存器
		{
			TWI_START();
			data_write(clc);
			TWI_STOP();
		}
		if (clc==4)//讀取溫度
		{
			TWI_START();
			data_read();
			TWI_STOP();
		}
		
	}
	printf("end\n");
	return 0;
}

void TWI_START(){
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);       // start condition TWINT=7 TWSTA=5 TWEN=2
	while(!(TWCR & (1<<TWINT)));                  // wait till complete and wait for TWINT flag set
}

void TWI_STOP(){
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);       // stop condition TWINT=7 TWSTO=4 TWEN=2
	while(!(TWCR & (1<<TWSTO)));                  // wait till stop condition has been sent
	printf("stop\n");
}

void TWI_sent_byte(unsigned char data){
	TWDR = data;                                  // put data into TWDR
	TWCR = (1<<TWINT)|(1<<TWEN);
	while(!(TWCR & (1<<TWINT)));                  // wait for TWINT flag set
	//printf("data=%d\n",TWDR);
}

void data_write(int clc)
{
	unsigned char mydata[2]={0x01,0x62};//設定config
	unsigned char mydata_lowlimit[2]={0x02,0x18};//設定低溫暫存器24度
	unsigned char mydata_hignlimit[2]={0x03,0x1D};//設定高溫暫存器29度
	if((TWSR & 0xF8) != MT_START)
	{
		// TWI error
		TWI_STOP();									                     // STOP TWI
	}
	else
	{
		printf("TWSR=%d\n",TWSR);
		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("sec_twsr=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			for(unsigned int i=0;i<2;i++)
			{
				if (clc==1)
				{
					TWI_sent_byte(mydata[i]);
				}
				else if(clc==2)
				{
					TWI_sent_byte(mydata_lowlimit[i]);
				}
				else if(clc==3)
				{
					TWI_sent_byte(mydata_hignlimit[i]);
				}
				if((TWSR & 0xF8) == MT_DATA_ACK)
				{
					printf("TWDR=%d\n",TWDR);
					printf("TWSR=%d\n",TWSR);
					continue;
				}
				else
				{
					// TWI error
					printf("TWSR=%d\n",TWSR);
					printf("TWDR=%d\n",TWDR);
					printf("data fail\n");
					TWI_STOP();									               // STOP TWI
					break;
				}
			}
		}
		
	}
}

unsigned char TWI_Receive_ACK(){
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);        // data has been received and return ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

unsigned char TWI_Receive_NACK(){
	TWCR = (1<<TWINT)|(1<<TWEN);                  // data has been received and return NOT ACK
	while (!(TWCR & (1<<TWINT)));
	return TWDR;
}

void data_read()
{
	unsigned char received_data[2]={};
	float input_hi=0,input_low=0,input=0;
	if((TWSR & 0xF8)!=MR_START)
	{
		TWI_STOP();
	}
	else
	{

		TWI_sent_byte(SLA_W);
		if((TWSR & 0xF8) != MT_SLA_W_ACK)
		{
			printf("TWSR=%d\n",TWSR);
			TWI_STOP();									                     // STOP TWI
		}
		else
		{
			printf("TWSR=%d\n",TWSR);
			TWI_sent_byte(TEM_reg);	
			if((TWSR & 0xF8) == MT_DATA_ACK)
			{
				TWI_START();
				if((TWSR & 0xF8)!=MR_REPEAT_START)
				{
					printf("TWSR=%d\n",TWSR);
					
					TWI_STOP();
				}
				else
				{
					printf("TWSR=%d\n",TWSR);
					TWI_sent_byte(SLA_R);
					if((TWSR & 0xF8) != MR_SLA_R_ACK)
					{
						// TWI error
						printf("TWSR=%d\n",TWSR);
						TWI_STOP();									               // STOP TWI
					}
					else
					{
						printf("TWSR=%d\n",TWSR);
						received_data[0] = TWI_Receive_ACK();	  // store data in data array and return ACK
						input_hi=received_data[0];
						if ((TWSR & 0xF8) != MR_DATA_ACK)
						{
							// TWI error
							printf("TWSR=%d\n",TWSR);
							TWI_STOP();									               // STOP TWI
						}
						else
						{
							input_low = ((TWI_Receive_NACK()>> 4)+1)*0.0625;
							printf("TWSR=%d\n",TWSR);
						}
					}
				}
				
			}
			else
			{
				// TWI error
				printf("TWSR=%d\n",TWSR);
				TWI_STOP();									               // STOP TWI
			}
			
		}
	}
	input=input_hi+input_low;
	printf("temperature=%f\n",input);
}

ISR(INT5_vect)
{
	printf("too high or too low\n");
}


```
## 實驗數據
1. 休眠模式下單發量測
> 溫度量測為27.3125度
![](https://i.imgur.com/xWJAk51.jpg)
2. 比較模式下溫度中斷警告
> 設定工作模式暫存器
![](https://i.imgur.com/ivDdV0X.jpg)
> 設定低溫暫存器
![](https://i.imgur.com/u0HT2MO.jpg)
> 設定高溫暫存器
![](https://i.imgur.com/RydGU0a.jpg)
> 上面設定高溫暫存器為26度，而量測出來溫度為27度，所以透過外部中斷設定得到too high
![](https://i.imgur.com/fezAgYF.jpg)
> 當下溫度高於高溫暫存器時，警告線下降LOW發出警告
![](https://i.imgur.com/deuuugQ.jpg)
> 當溫度低於低溫暫存器後又高於低溫暫存器，警告線變回原來的HI
![](https://i.imgur.com/BDU6Cao.jpg)
> 依照下圖所顯示的警告線有按照比較模式下的方式發出警告
![](https://i.imgur.com/TYY2nfm.jpg)

3.量測模式下固定周期顯示
> 溫度過高
![](https://i.imgur.com/xuslO5I.jpg)
> 溫度過高發出警告，透過read後警告被消除
![](https://i.imgur.com/m31ESwm.jpg)
 > 依照下圖interrupt mode的警告線有按照量測模式下的方式發出警告
![](https://i.imgur.com/Ihpsgpw.jpg)

## 遭遇問題 
- [x] 資料都有成功傳進去，但是出來的效果卻不是我想要的，(start、住址0x70、暫存器住址0x01皆成ack)像是我data使用0x00或0xFF，結果p0:7的電壓沒照我的控制，而是顯示0.67附近的電壓，使用邏輯分析儀量燈的地方，顯示一直為1。
![](https://i.imgur.com/QOIfwN1.png)
![](https://i.imgur.com/Bo162QM.png)

## 驗收問題
- 設置除頻"16"
- bit rate 約138k(HZ)
- 使用TCA9534A與TMP175這兩顆IC做實驗，用LED顯示器模組顯示溫度，當中斷模式下溫度超過暫存器設定下，使用TCA9534A接一顆LED閃爍。並且將閃爍前溫度變化傳至matlab畫圖(數據至少要看出溫度變化)。
- 最後將由TCA9534A接一顆按鈕清除所有資料，將LED顯示器模組顯示00，LED燈滅掉。