# 介面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)