# 介面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, ¶meter, 1, 0);
id1 = FreqRedu_reg(&a, &LO, ¶meter, 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執行函式使用練習

### 2. 量測單極性ADC線性誤差量測

### 3. 雙通道弦波訊號擷取

## 驗收
### 驗收題目
用產波器產生隨機圖案的波形,大小在2.56之下,用adc讀完後以matlab顯示,上述程式要登錄在pipeline,要錄影,影片中要有三種波形
### 驗收成果
[影片](https://ncu365-my.sharepoint.com/:v:/g/personal/oreo900930_office365_ncu_edu_tw/ERdmMOuUeiBHkwfKkEZCxaUBDh_hAmx3riIk9HqVphCcqw?e=3i2Rip)