# 介面實驗二
## 工作日誌
> [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傳送資料

2. 接收資料


3. TCA9534A運作流程

4. TMP175單發量測模式

5. TMP175比較模式

6. TMP175中斷模式

## 程式碼
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度

2. 比較模式下溫度中斷警告
> 設定工作模式暫存器

> 設定低溫暫存器

> 設定高溫暫存器

> 上面設定高溫暫存器為26度,而量測出來溫度為27度,所以透過外部中斷設定得到too high

> 當下溫度高於高溫暫存器時,警告線下降LOW發出警告

> 當溫度低於低溫暫存器後又高於低溫暫存器,警告線變回原來的HI

> 依照下圖所顯示的警告線有按照比較模式下的方式發出警告

3.量測模式下固定周期顯示
> 溫度過高

> 溫度過高發出警告,透過read後警告被消除

> 依照下圖interrupt mode的警告線有按照量測模式下的方式發出警告

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


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