# 介面實驗三
## 遭遇問題
- [x] (**已解決**)使用spi時無法一對多,如果先設定完max7219後,讀溫度會一直顯示0,反過來則是先讀溫度在設定顯示LED燈的話,則是顯示2次溫度改變後,溫度就不會變了,接下來我在下面程式碼的部分對個別的ic(分別//個別ic)去做測試都正常,想請問使用不了一對多可能的原因?謝謝
* 需要先確認實際傳輸的時候發生什麼狀況
請先接示波器或邏輯分析儀到SPI傳輸的腳位,再分別拍照記錄溫度顯示0 以及 顯示2次溫度改變就不動的波形前後有什麼狀況
>**把原本接在asa bus上的GND與5V,改成用40PIN的GND與5V上面,因為量測時發現ASA BUS上的電壓只剩2V多,導致我的CLOCK會在非傳輸時間亂跳,換完後clock有在正確地方顯示,另外改完後,燈無法顯示,結果是加了一個電容就解決了。**

## 流程圖
1. 開發 ASA BUS 溫度感測介面卡

2. 開發 ASA BUS LED 矩陣顯示器介面卡

## 程式碼
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 溫度感測介面卡

2. 開發 ASA BUS LED 矩陣顯示器介面卡


## 驗收
* 溫度低於一定值(例如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);
}
}
```
:::
### 實驗結果

