# 介面實驗二 ## 工作日誌 > [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燈滅掉。