---
# System prepended metadata

title: 介面lab04

---

# 介面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)

