# 介面lab05
## 工作日誌
* 10/4 閱讀講義
## 程式碼
### 1. DAC介面卡原型試作
```c
#include "c4mlib.h"
#define F_CPU 11059200UL
void SPI_SET(void);
int main(void)
{
C4M_DEVICE_set();
uint16_t data=2560;// 3 = 2*2.4*2560/4096
SPI_SET();
while (1)
{
REGFPT(&PORTF,1,0,0);
_delay_ms(10);
ASA_SPIM_trm(2,9,0x50,2,&data,10);//對A通達雙倍參考電壓輸出
REGFPT(&PORTF,1,0,1);
}
}
void SPI_SET(void)
{
/*SPI串列通訊埠設定旗標群*/
REGFPT(&SPSR,0x01,0,1);//選擇雙倍工作時脈
REGFPT(&SPCR,0x03,0,0);//設定工作時脈除頻值4
REGFPT(&SPCR,0x04,2,0);//同步時脈讀寫 前收後送
REGFPT(&SPCR,0x08,3,0);//同步時脈前緣 前緣為上
REGFPT(&SPCR,0x10,4,1);//主僕選擇 主
REGFPT(&SPCR,0x20,5,0);//SPI資料傳輸順序 高位元先送
REGFPT(&DDRB,0x0F,0,7);//設定 MOSI、SCK、SS 輸出,MISO 接腳為輸入
REGFPT(&DDRF,0xE0,5,7);//設定 ASAID 接腳為輸出
REGFPT(&DDRF,0x0F,0,1);//設定SPI SS8 PF0接腳為CS
/*SPI串列通訊埠控制旗標群*/
REGFPT(&SPCR,0x80,7,0);//SPI中斷禁能
REGFPT(&SPCR,0x40,6,1);//SPI致能
REGFPT(&PORTF,1,0,1);//CS初始值1
}
```
### 2. 使用SPI DAC卡完成ADC DAC完成控制迴路
```c
#include "c4mlib.h"
#define F_CPU 11059200UL
//----------降頻結構設定----------//
#define Taskblock_INI {.state=0,.FBFunc_p=NULL,.FBPara_p=NULL}
TaskBlock_t c[6]={Taskblock_INI,Taskblock_INI,Taskblock_INI,Taskblock_INI,Taskblock_INI,Taskblock_INI};
#define PhaseDivi_INI {.Divi=1,.DiviCount=0,.phase=0}
PhaseDivi_t b=PhaseDivi_INI;
uint16_t period=1;//改位移
#define FreqReduStr_INI {.Cycle=4,.Counter=0,.TaskId=0,.MaxTask=6,.Total=0,.Divi_p=&b,.Task_p=c,.Period_p=&period}
FreqReduStr_t a=FreqReduStr_INI;
//----------end----------//
uint8_t Pid0, Pid1, Pid2;
uint8_t Fid0, Fid1, Fid2;
uint8_t task0[]="Task0";
uint8_t task1[]="Task1";
uint8_t task2[]="Task2";
void SPI_SET(void);
void TIMER2_SET(void);
void ADC_SET(void);
void FREQREDU_SET(void);
void PIPELINE_SET(void);
void DAC_output(void);
void ADC_Single_end(void);
void record(void);
uint16_t singletrm=0, difftrm=0;
float singleDigit[1][100] = {0};
uint16_t mat[1][100] = {0};
int flag=0;
int count=0;
uint16_t Dn=2560;
int main(void)
{
C4M_DEVICE_set();
SPI_SET();
TIMER2_SET();
ADC_SET();
FREQREDU_SET();
PIPELINE_SET();
HMI_snget_matrix( 5, 1, 100, &mat);
sei();
TRIG_NEXT_TASK(0);
while (!flag)
{
}
}
void SPI_SET(void)
{
/*SPI串列通訊埠設定旗標群*/
REGFPT(&SPSR,0x01,0,1);//選擇雙倍工作時脈
REGFPT(&SPCR,0x03,0,0);//設定工作時脈除頻值4
REGFPT(&SPCR,0x04,2,0);//同步時脈讀寫 前收後送
REGFPT(&SPCR,0x08,3,0);//同步時脈前緣 前緣為上
REGFPT(&SPCR,0x10,4,1);//主僕選擇 主
REGFPT(&SPCR,0x20,5,0);//SPI資料傳輸順序 高位元先送
REGFPT(&DDRB,0x0F,0,7);//設定 MOSI、SCK、SS 輸出,MISO 接腳為輸入
REGFPT(&DDRF,0xE0,5,7);//設定 ASAID 接腳為輸出
REGFPT(&DDRF,0x0F,0,1);//設定SPI SS8 PF0接腳為CS
/*SPI串列通訊埠控制旗標群*/
REGFPT(&SPCR,0x80,7,0);//SPI中斷禁能
REGFPT(&SPCR,0x40,6,1);//SPI致能
REGFPT(&PORTF,1,0,1);//CS初始值1
}
void TIMER2_SET(void)
{
//----計時中斷硬體設定----//
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
}
void ADC_SET(void)
{
/*ADC設定旗標群*/
REGFPT(&ADMUX,0x1F,0,0x1F);//設定輸入通道Calibrate
REGFPT(&ADMUX,0xC0,6,3);//設定參考電壓2.56
REGFPT(&ADMUX,0x20,5,0);//設定10位元轉換
REGFPT(&ADCSRA,0x07,0,2);//設定工作時脈除頻4
REGFPT(&ADCSRA,0x20,5,0);//禁能觸發轉換
REGFPT(&ADCSRA,0x08,3,0);//禁能ADC中斷
REGFPT(&DDRF,0x0F,0,0);//設定ADC接腳為輸入
REGFPT(&ADCSRA,0x80,7,1);//致能ADC
REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換
}
void FREQREDU_SET(void)
{
/*降頻執行器*/
Fid0 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 0);
Fid1 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 2);
Fid2 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 3);
FreqRedu_en(&a, Fid0, 1);
FreqRedu_en(&a, Fid1, 1);
FreqRedu_en(&a, Fid2, 1);
}
void PIPELINE_SET(void)
{
/*PIPELINE排程器工作方塊佈局及登錄*/
PIPELINE_LAY(3, 3, 10);
Pid0 = Pipeline_reg(&SysPipeline_str, DAC_output, NULL, task0);
Pid1 = Pipeline_reg(&SysPipeline_str, ADC_Single_end, NULL, task1);
Pid2 = Pipeline_reg(&SysPipeline_str, record, NULL, task2);
//printf("%d %d %d\n", aa, bb, cc);
}
void DAC_output(void)
{
if (!flag)
{
Dn = mat[0][count];
//printf("Dn: %d = mat[0][%d]\n", Dn, count);
REGFPT(&PORTF,1,0,0);
_delay_ms(1);
ASA_SPIM_trm(2,9,0x50,2,&Dn,10);//對A通達雙倍參考電壓輸出
REGFPT(&PORTF,1,0,1);
TRIG_NEXT_TASK(1);
}
}
void ADC_Single_end(void)
{
REGFPT(&ADMUX,0x1F,0,0X01);//設定輸入通道PF1 ADC1-GND 5V
_delay_ms(10);
REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換
_delay_ms(10);
REGGET(&ADCL, 2, &singletrm);//讀取 10 位元 uint16_t型態轉換結果
TRIG_NEXT_TASK(2);
//printf("single = %d\n", singletrm);
}
void record(void)
{
singleDigit[0][count] = singletrm*5/1024;
if (count>=99)
{
//cli();
HMI_snput_matrix(8, 1, 100, &singleDigit);
flag = 1;
count = 0;
}
//printf("count = %d\n", count);
count++;
TRIG_NEXT_TASK(3);
}
ISR(TIMER2_COMP_vect)
{
FreqRedu_step(&a);
}
```
## 流程圖
### 1. DAC介面卡原型試作

### 2. 使用SPI DAC卡完成ADC DAC完成控制迴路

## 實驗數據
### 1. DAC介面卡原型試作

### 2. 使用SPI DAC卡完成ADC DAC完成控制迴路


## 驗收
### 驗收題目
(D)DAC原理是?A 積分器 B 微分器 C 乘法器 D 加法器 E 減法器
vin接可變電阻,用DAC來做ADC,輸出結果print出來

### 驗收成果
* Vin=4.05 V


* Vin=4.40 V


* Vin=4.23 V

