# 介面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介面卡原型試作 ![](https://i.imgur.com/rXLX77N.png) ### 2. 使用SPI DAC卡完成ADC DAC完成控制迴路 ![](https://i.imgur.com/RsuYyI1.png) ## 實驗數據 ### 1. DAC介面卡原型試作 ![](https://i.imgur.com/9j3ecO9.jpg) ### 2. 使用SPI DAC卡完成ADC DAC完成控制迴路 ![](https://i.imgur.com/egyyX5i.jpg) ![](https://i.imgur.com/zvbqhAa.png) ## 驗收 ### 驗收題目 (D)DAC原理是?A 積分器 B 微分器 C 乘法器 D 加法器 E 減法器 vin接可變電阻,用DAC來做ADC,輸出結果print出來 ![](https://i.imgur.com/mZEXaCy.jpg) ### 驗收成果 * Vin=4.05 V ![](https://i.imgur.com/LeLBG2o.png) ![](https://i.imgur.com/4K9Qk3V.jpg) * Vin=4.40 V ![](https://i.imgur.com/fRlzCuf.png) ![](https://i.imgur.com/E9sW5Ql.jpg) * Vin=4.23 V ![](https://i.imgur.com/hz9g153.png) ![](https://i.imgur.com/hBEnFBm.jpg)