---
# System prepended metadata

title: 介面實驗三

---

# 介面實驗三
## 遭遇問題

- [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)
