# 介面lab04 ## 工作日誌 * 8/31開始閱讀講義 * 9/15開始實作 ## 程式碼 ### 1. C4MOS執行函式使用練習 ```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}; uint16_t period=1; #define PhaseDivi_INI {.Divi=1,.DiviCount=0,.phase=0} PhaseDivi_t b=PhaseDivi_INI; #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; int step=0; void HI(void *parameter) { REGFPT(&PORTD,1,0,1); } void LO(void *parameter) { REGFPT(&PORTD,1,0,0); } int main(void) { C4M_DEVICE_set(); /*降頻執行器*/ char parameter=0; uint8_t id0, id1; id0 = FreqRedu_reg(&a, &HI, &parameter, 1, 0); id1 = FreqRedu_reg(&a, &LO, &parameter, 1, 2); FreqRedu_en(&a, id0, 1); FreqRedu_en(&a, id1, 1); //----計時中斷硬體設定----// 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 sei();//致能中斷 REGFPT(&DDRD,1,0,1); while(1){ } } ISR(TIMER2_COMP_vect) { FreqRedu_step(&a); } ``` ### 2. 量測單極性ADC線性誤差量測 ```c #include "c4mlib.h" #define F_CPU 11059200UL uint16_t BC[1][2]= {0}; void meansure_0v(void) { uint16_t trm=0; REGFPT(&ADMUX,0x1F,0,0x1F);//設定輸入通道 _delay_ms(100); REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換 _delay_ms(10); REGGET(&ADCL, 2, &trm);//讀取 10 位元 uint16_t型態轉換結果 BC[0][0] = trm; printf("0V = %d\n", BC[0][0]); _delay_ms(100); } void meansure_1_23v(void) { uint16_t trm1=0; REGFPT(&ADMUX,0x1F,0,0x1E);//設定輸入通道 _delay_ms(100); REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換 _delay_ms(10); REGGET(&ADCL, 2, &trm1);//讀取 10 位元 BC[0][1] = trm1; printf("1.23V = %d\n", BC[0][1]); _delay_ms(100); } int main(void) { C4M_DEVICE_set(); /*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 meansure_0v(); meansure_1_23v(); HMI_snput_matrix(5, 1, 2, &BC); } ``` ### 3. 雙通道弦波訊號擷取 ```c #include "c4mlib.h" #define F_CPU 11059200UL void Single_end(void); void Differential(void); void record(void); //----------降頻結構設定----------// #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----------// int flag=0; uint8_t aa, bb, cc; uint8_t id0, id1, id2; uint8_t task0[]="Task0"; uint8_t task1[]="Task1"; uint8_t task2[]="Task2"; uint16_t singletrm=0, difftrm=0; float singleDigit[1][100] = {0}; float DiffDigit[1][100] = {0}; int main(void) { C4M_DEVICE_set(); /*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(&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 /*PIPELINE排程器工作方塊佈局及登錄*/ PIPELINE_LAY(3, 3, 10); aa = Pipeline_reg(&SysPipeline_str, Single_end, NULL, task0); bb = Pipeline_reg(&SysPipeline_str, Differential, NULL, task1); cc = Pipeline_reg(&SysPipeline_str, record, NULL, task2); //printf("%d %d %d\n", aa, bb, cc); /*降頻執行器*/ id0 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 0); id1 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 2); id2 = FreqRedu_reg(&a, &Pipeline_step, &SysPipeline_str, 1, 3); FreqRedu_en(&a, id0, 1); FreqRedu_en(&a, id1, 1); FreqRedu_en(&a, id2, 1); sei(); TRIG_NEXT_TASK(0); while (!flag) { } return 0; } void Single_end(void) { REGFPT(&ADMUX,0x1F,0,0X01);//設定輸入通道PF1 ADC1-GND 5V _delay_ms(100); REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換 _delay_ms(10); REGGET(&ADCL, 2, &singletrm);//讀取 10 位元 uint16_t型態轉換結果 TRIG_NEXT_TASK(1); //printf("single = %d\n", singletrm); } void Differential(void) { REGFPT(&ADMUX,0x1F,0,0X1B);//設定輸入通道PF3PF2 ADC3-ADC2 _delay_ms(100); REGFPT(&ADCSRA,0x40,6,1);//觸發 ADC 轉換 _delay_ms(10); REGGET(&ADCL, 2, &difftrm);//讀取 10 位元 uint16_t型態轉換結果 TRIG_NEXT_TASK(2); //printf("diff = %d\n", difftrm); } void record(void) { static int count=0; singleDigit[0][count] = singletrm*2.56/1024; DiffDigit[0][count] = difftrm*2.56/1024; count++; if (count>=99) { //cli(); HMI_snput_matrix(8, 1, 100, &singleDigit); HMI_snput_matrix(8, 1, 100, &DiffDigit); // HMI_put_matrix(5, 1, 100, &singleDigit); // HMI_put_matrix(5, 1, 100, &DiffDigit); flag = 1; count = 0; // FreqRedu_en(&a, id0, 0); // FreqRedu_en(&a, id1, 0); // FreqRedu_en(&a, id2, 0); } //printf("count = %d\n", count); TRIG_NEXT_TASK(3); } ISR(TIMER2_COMP_vect) { FreqRedu_step(&a); } ``` ## 實驗數據 ### 1. C4MOS執行函式使用練習 ![](https://i.imgur.com/nKWcfFG.png) ### 2. 量測單極性ADC線性誤差量測 ![](https://i.imgur.com/PNAp5gw.png)![](https://i.imgur.com/MA1puir.png) ### 3. 雙通道弦波訊號擷取 ![](https://i.imgur.com/eC1LvYL.png) ## 驗收 ### 驗收題目 用產波器產生隨機圖案的波形,大小在2.56之下,用adc讀完後以matlab顯示,上述程式要登錄在pipeline,要錄影,影片中要有三種波形 ### 驗收成果 [影片](https://ncu365-my.sharepoint.com/:v:/g/personal/oreo900930_office365_ncu_edu_tw/ERdmMOuUeiBHkwfKkEZCxaUBDh_hAmx3riIk9HqVphCcqw?e=3i2Rip)