# 介面實驗三 ## 遭遇問題 - [x] (**已解決**)使用spi時無法一對多,如果先設定完max7219後,讀溫度會一直顯示0,反過來則是先讀溫度在設定顯示LED燈的話,則是顯示2次溫度改變後,溫度就不會變了,接下來我在下面程式碼的部分對個別的ic(分別//個別ic)去做測試都正常,想請問使用不了一對多可能的原因?謝謝 * 需要先確認實際傳輸的時候發生什麼狀況 請先接示波器或邏輯分析儀到SPI傳輸的腳位,再分別拍照記錄溫度顯示0 以及 顯示2次溫度改變就不動的波形前後有什麼狀況 >**把原本接在asa bus上的GND與5V,改成用40PIN的GND與5V上面,因為量測時發現ASA BUS上的電壓只剩2V多,導致我的CLOCK會在非傳輸時間亂跳,換完後clock有在正確地方顯示,另外改完後,燈無法顯示,結果是加了一個電容就解決了。** ![](https://i.imgur.com/SnY5TL3.jpg) ## 流程圖 1. 開發 ASA BUS 溫度感測介面卡 ![](https://i.imgur.com/xVjfcLq.jpg) 2. 開發 ASA BUS LED 矩陣顯示器介面卡 ![](https://i.imgur.com/U3NaL38.jpg) ## 程式碼 1. 開發 ASA BUS 溫度感測介面卡 :::spoiler ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" #include "TWI.cfg" #define PIN_CS 0 #define PIN_SCK 1 #define PIN_MOSI 2 #define PIN_MISO 3 void SPI_setup(); void pin_setup(); int main(void) { C4M_DEVICE_set(); float Temp=0; uint16_t temp=0; pin_setup(); // setup I/O pin SPI_setup(); // initial SPI PORTF |= (1<<PIN_CS); //set CS high after receive data while(1) { _delay_ms(500); PORTF &= ~(1<<PIN_CS); //set CS low before receive data ASA_SPIM_rec(4, 8, 0, 2, &temp, 1); PORTF |= (1<<PIN_CS); //set CS high after receive data Temp=temp*(0.0078125); printf("temperature=%f\n",Temp); _delay_ms(500); } return 0; } void SPI_setup() { SPCR=(1<<SPE)|(1<<MSTR); // enable SPI interrupt and SPI,set master mode,CPHA=0,CPOL=0,DORD=0,SPR0:1=0 REGFPT(&SPSR,0x01,0,1); //choose double } void pin_setup() { DDRB |= (1<<PIN_SCK)|(1<<PIN_MOSI)|(1<<PIN_CS); //set pin CS,SCK as output DDRF |= (1<<PIN_CS)|(1<<5)|(1<<6)|(1<<7); DDRB &= ~(1<<PIN_MISO); // set pin MISO as input } ``` ::: 2. 開發 ASA BUS LED 矩陣顯示器介面卡 :::spoiler ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" #include <avr/io.h> #include "spi.cfg" void SPI_setup(); void read_tem(); void max7219_setup(); void LED_SHOW(float tem ); void pin_setup(); #define PIN_CS 0 #define PIN_F1CS 1 #define PIN_SCK 1 #define PIN_MOSI 2 #define PIN_MISO 3 float Temp=0; uint16_t temp=0; uint8_t LED[10]={126,48,109,121,51,91,95,114,127,123}; uint8_t LED_dot[10]={254,176,237,249,179,219,223,242,255,251}; int main(void) { C4M_DEVICE_set(); pin_setup(); SPI_setup(); // initial SPI REGFPT(&PORTF,0x03,0,3); max7219_setup(); while(1) { read_tem(); //讀溫度 printf("temperature=%f\n",Temp); LED_SHOW(Temp); //顯示溫度 } return 0; } void SPI_setup() { SPCR=(1<<SPE)|(1<<MSTR); // enable SPI,set master mode,CPHA=0,CPOL=0,DORD=0,SPR0:1=0 REGFPT(&SPSR,0x01,0,1); //set double mode } void pin_setup() { DDRB |= (1<<PIN_SCK)|(1<<PIN_MOSI)|(1<<PIN_CS); //set pin CS,SCK as output DDRF |= (1<<PIN_CS)|(1<<PIN_F1CS)|(1<<5)|(1<<6)|(1<<7); DDRB &= ~(1<<PIN_MISO); // set pin MISO as input } void read_tem() { REGFPT(&PORTF,1,0,0); //set CS low before receive data ASA_SPIM_rec(4,8,0,2,&temp,1); REGFPT(&PORTF,1,0,1); //set CS high after receive data Temp=temp*(0.0078125); _delay_ms(500); } void max7219_setup() { uint8_t decoder = 0; uint8_t intensity = 15; uint8_t scane = 3; uint8_t shutdown = 1; uint8_t display = 0; REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,9,1,&decoder,10); //not decode REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,10,1,&intensity,10); //set intensity REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,11,1,&scane,10); //scane limit REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,12,1,&shutdown,10); //set shutdown REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,15,1,&display,10); //display test REGFPT(&PORTF,2,0,2); //set CS high after receive data printf("ALREADY SET\n"); _delay_ms(10); } void LED_SHOW(float tem ) { /* 數字暫存器 1 2 3 4 第二個加小數點 */ int x=0,y=0,z=0,a=0; x = tem/10; y=tem-10*x; z=tem*10-100*x-10*y; a=tem*100-1000*x-100*y-10*z; REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,1,1,&LED[a],10); //小數點後第二位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,2,1,&LED[z],10); //小數點後第一位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,3,1,&LED_dot[y],10); //個位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,4,1,&LED[x],10); //十位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); } ``` ::: ## 實驗數據 1. 開發 ASA BUS 溫度感測介面卡 ![](https://i.imgur.com/6nnuVs6.jpg) 2. 開發 ASA BUS LED 矩陣顯示器介面卡 ![](https://i.imgur.com/5elb9EH.jpg) ![](https://i.imgur.com/0orUmnh.jpg) ## 驗收 * 溫度低於一定值(例如27.5度)後,七節管顯示Cold >設定為低於27.5度 ### 程式碼 :::spoiler ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" #include <avr/io.h> #include "spi.cfg" void SPI_setup(); void read_tem(); void max7219_setup(); void LED_SHOW(float tem ); void pin_setup(); #define PIN_CS 0 #define PIN_F1CS 1 #define PIN_SCK 1 #define PIN_MOSI 2 #define PIN_MISO 3 float Temp=0; uint16_t temp=0; uint8_t LED[10]={126,48,109,121,51,91,95,114,127,123}; uint8_t LED_dot[10]={254,176,237,249,179,219,223,242,255,251}; uint8_t cold[4]={78,126,48,61}; int main(void) { C4M_DEVICE_set(); pin_setup(); SPI_setup(); // initial SPI REGFPT(&PORTF,0x03,0,3); max7219_setup(); while(1) { read_tem(); //讀溫度 printf("temperature=%f\n",Temp); LED_SHOW(Temp); //顯示溫度 } return 0; } void SPI_setup() { SPCR=(1<<SPE)|(1<<MSTR); // enable SPI,set master mode,CPHA=0,CPOL=0,DORD=0,SPR0:1=0 REGFPT(&SPSR,0x01,0,1); //set double mode } void pin_setup() { DDRB |= (1<<PIN_SCK)|(1<<PIN_MOSI)|(1<<PIN_CS); //set pin CS,SCK as output DDRF |= (1<<PIN_CS)|(1<<PIN_F1CS)|(1<<5)|(1<<6)|(1<<7); DDRB &= ~(1<<PIN_MISO); // set pin MISO as input } void read_tem() { REGFPT(&PORTF,1,0,0); //set CS low before receive data ASA_SPIM_rec(4,8,0,2,&temp,1); REGFPT(&PORTF,1,0,1); //set CS high after receive data Temp=temp*(0.0078125); _delay_ms(500); } void max7219_setup() { uint8_t decoder = 0; uint8_t intensity = 15; uint8_t scane = 3; uint8_t shutdown = 1; uint8_t display = 0; REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,9,1,&decoder,10); //not decode REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,10,1,&intensity,10); //set intensity REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,11,1,&scane,10); //scane limit REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,12,1,&shutdown,10); //set shutdown REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,15,1,&display,10); //display test REGFPT(&PORTF,2,0,2); //set CS high after receive data printf("ALREADY SET\n"); _delay_ms(10); } void LED_SHOW(float tem ) { /* 數字暫存器 1 2 3 4 第二個加小數點 */ int x=0,y=0,z=0,a=0; x = tem/10; y=tem-10*x; z=tem*10-100*x-10*y; a=tem*100-1000*x-100*y-10*z; if (tem <=27.5) { REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,1,1,&cold[3],10); //小數點後第二位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,2,1,&cold[2],10); //小數點後第一位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,3,1,&cold[1],10); //個位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,4,1,&cold[0],10); //十位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); } else { REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,1,1,&LED[a],10); //小數點後第二位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,2,1,&LED[z],10); //小數點後第一位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,3,1,&LED_dot[y],10); //個位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); REGFPT(&PORTF,2,0,0); //set CS low before receive data ASA_SPIM_trm(6,9,4,1,&LED[x],10); //十位數 REGFPT(&PORTF,2,0,2); //set CS high after receive data _delay_ms(10); } } ``` ::: ### 實驗結果 ![](https://i.imgur.com/Pi1tFva.jpg) ![](https://i.imgur.com/6xYVWdK.jpg)