KEA128幾種例程(gpio/uart/oled/adc/pwm/超聲波) IAR C

根據北京郵電大學2019智能車測試題編寫,下面放部分預覽,實現的功能參照上傳文件(我的資源)中壓縮包內的文檔中存在的代碼片對應函數。

//isr.c
#include "backend.h"
#include "isr.h"

extern int Scene;
extern volatile UART_Type *UARTx[3];

extern void SwitchScene(int sceneCode);
extern void Q1_1(UARTn uart);
extern void Q1_2();
extern void Q1_3(UARTn uart);
extern void Q2_1(UARTn uart);
extern void Q2_2_Extra();
extern void Q2_5();
extern void Q3_2();
extern void Q4();

extern void Q7();

void NormalUartInterrupt(UARTn uart) {
	switch(Scene) {
	case SCENE_Q1_1:
		Q1_1(uart);
	    break;
		
	case SCENE_Q1_3:
		Q1_3(uart);
		break;
		
	case SCENE_Q2_1:
		Q2_1(uart);
		break;
		
	case SCENE_Q2_5:
		Q2_5(uart);
		break;
		
	default:
		while(UARTx[uart]->S1 & UART_S1_RDRF_MASK) {
			uart_getchar(uart);
		}
		break;
	}
}


//串口0中斷服務
void UART0_ISR(void) {

    DisableInterrupts;
	
	NormalUartInterrupt(UARTR0);
	
  	EnableInterrupts;
}


//串口1中斷服務
void UART1_ISR(void) {
	
}

//串口2中斷服務
void UART2_ISR(void) {
	DisableInterrupts;
	
	if(gpio_get(Key_CENTER)) {
		NormalUartInterrupt(UARTR2);
	} else {
		UART2_ISR_SwitchScene();
	}
	
	EnableInterrupts;
}

void UART2_ISR_SwitchScene(){ 
	int scene_base[8] =
	{
		SCENE_Q1_1, SCENE_Q2_1, SCENE_Q3_1, SCENE_Q4, SCENE_Q5_1,
		SCENE_Q6, SCENE_Q7, SCENE_Q8_1
	};
	int count = 0;
	
	uint8_t control[2] = {'x', 'x'};
	//memset(control, 'x', 3);
	
	while(UART2->S1 & UART_S1_RDRF_MASK) {
		control[count] = uart_getchar(UARTR2);
		count++;
		uart_putchar(UARTR2, control[0]);
		uart_putchar(UARTR2, control[1]);
		uart_putchar(UARTR2, '\n');
		
		if(count >= 2)
			break;
	}
	
	switch(count){
	case 1:
		if(control[0] >= '1' && control[0] <= '8') 
			SwitchScene(scene_base[ control[0]-'1' ]);
		else if(control[0] == '0')
			SwitchScene(SCENE_DEBUG);
		
		break;
		
	case 2:
		if(control[0] >= '1' && control[0] <= '8') {
			//unhandle err(data out of range)
			SwitchScene(scene_base[ control[0]-'1' ] + control[1]-'1');
		}
		else if(control[0] == '0')
			SwitchScene(SCENE_DEBUG);
		
		break;
		
	default:
		break;
	}
}


  //系統時間
//定時器0中斷函數

void PIT0_ISR(void) {
	
    PIT->CHANNEL[0].TFLG |= PIT_TFLG_TIF_MASK;
	
	switch(Scene) {
	case SCENE_Q1_2:
		Q1_2();
		break;
	case SCENE_Q1_3:
		Q1_2();
		break;
		
	case SCENE_Q3_2:
		Q3_2();
		break;
		
	case SCENE_Q2_2:
		Q2_2_Extra();
		break;
	case SCENE_Q4:
		Q4();
		break;
	case SCENE_Q7:
		Q7();
		break;
	default:
		break;
		
	}
}

long stime = 0;
void PIT1_ISR(void) {
	PIT->CHANNEL[1].TFLG |= PIT_TFLG_TIF_MASK;
	stime++;
}


/*-----------KB:
---------PTA0-PTD7
*/
void KBI0_Isr(void) {
	//DisableInterrupts;
	
	KBI0->SC |= KBI_SC_KBACK_MASK;                /* clear interrupt flag */
	KBI0->SC |= KBI_SC_RSTKBSP_MASK ;             
	
//	switch(Scene) {
//	case SCENE_DEBUG:
		HandleDirectionKeys();
//		break;
//	}
	//EnableInterrupts;
}


/*-----------KB:
---------PTE0-PTH7
*/
//KBI1中斷函數
void KBI1_Isr(void) {
	//DisableInterrupts;
	
    KBI1->SC |= KBI_SC_KBACK_MASK;                /* clear interrupt flag */
    KBI1->SC |= KBI_SC_RSTKBSP_MASK ;             
	
//	switch(Scene) {
//	case SCENE_DEBUG:
		HandleDirectionKeys();
//		break;
//	}
	
	//EnableInterrupts;
}
//backend.h
#include "backend.h"

int Scene = SCENE_DEBUG;
extern volatile UART_Type *UARTx[3];
extern double sin(double);

//------------初始化方向鍵-----------------
void InitAllDirectionKeys(void) {

	KBI_Init(KBIX1, Key_UP, KBI_FALLING_LOW);
	KBI_Enable(KBIX1, Key_UP);
	
	KBI_Init(KBIX1, Key_DOWN, KBI_FALLING_LOW);
	KBI_Enable(KBIX1, Key_DOWN);
	
	KBI_Init(KBIX1, Key_LEFT, KBI_FALLING_LOW);
	KBI_Enable(KBIX1, Key_LEFT);
	
	KBI_Init(KBIX0, Key_RIGHT, KBI_FALLING_LOW);
	KBI_Enable(KBIX0, Key_RIGHT);

	KBI_Init(KBIX1, Key_CENTER, KBI_FALLING_LOW);
	KBI_Enable(KBIX1, Key_CENTER);
	
}

//-------------初始化右上LED燈--------------
void InitLED(void) {
	gpio_init(LED0, GPO, 0);
	gpio_init(LED1, GPO, 0);
	gpio_init(LED2, GPO, 0);
	gpio_init(LED3, GPO, 0);
}

//--------------初始化全部------------------
void InitAll() {
	DisableInterrupts;
	
	PIT_Init(PIT_CHANNEL0, 1);
	PIT_Init(PIT_CHANNEL1, 10000);
	
	gpio_init(PTG0, GPO, 0);
	
	gpio_init(TRIG, GPO, 0);
	gpio_init(ECHO, GPI, 0);
	
	ADC_Init(ADC_CHANNEL_AD6, ADC_12BIT);
	
	InitLED();
	uart_init(UARTR0, 9600);
	uart_init(UARTR2, 9600);
	
	uart_rx_irq_en(UARTR0);
	
	uart_rx_irq_en(UARTR2);
	uart_tx_irq_dis(UARTR2);
	uart_txc_irq_dis(UARTR2);
	
	OLED_Init();
	uint8_t	str[7] = {'I', 'N', 'I', 'T', 'E', 'D', '\0'};
	InitAllDirectionKeys();
	OLED_P8x16Str(0, 0, str);
	
	Scene = SCENE_DEBUG;
	
	EnableInterrupts;
}

//---------重置控件(目前只加入了重置LED)-----
void ResetAll_LED() {
	DisableInterrupts;
	
	gpio_set(LED0, 0);
	gpio_set(LED1, 0);
	gpio_set(LED2, 0);
	gpio_set(LED3, 0);
}

//----------------Q1-1--------------------
void Q1_1(UARTn uart){
	if(UARTx[uart]->S1 & UART_S1_RDRF_MASK) {
		uint8_t Data = uart_getchar(uart);
		switch(Data) {
	  	case '1':
		    gpio_turn(LED0);
			break;
		case '2':
			gpio_turn(LED1);
			break;
		case '3':
			gpio_turn(LED2);
		    break;
	    case '4':
			gpio_turn(LED3);
		    break;
	    default:
		    break;
	  }
	}
}

//--------------------Q1-2--------------------
int led_index = -1;
int PIT_Running = 0;

void Q1_2() {
	switch(led_index) {
	case 0:
		gpio_turn(LED0);
		gpio_turn(LED1);
		led_index = 1;
		break;
	case 1:
		gpio_turn(LED1);
		gpio_turn(LED2);
		led_index = 2;
		break;
	case 2:
		gpio_turn(LED2);
		gpio_turn(LED3);
		led_index = 3;
		break;
	case 3:
		gpio_turn(LED3);
		gpio_turn(LED0);
		led_index = 0;
		break;
	default:
		gpio_turn(LED0);
		led_index = 0;
		break;
	}
	
}

//------------------Q1-3---------------------
void Q1_3(UARTn uart) {
	if(UARTx[uart]->S1 & UART_S1_RDRF_MASK) {
		uint8_t Data = uart_getchar(uart);
		switch(Data) {
	  	case 'e':
			if(!PIT_Running) {
		    	PIT_IRQ_EN(PIT_CHANNEL0);
				PIT_Running = 1;
			}
			break;
			
		case 'd':
			if(PIT_Running) {
		    	PIT_IRQ_DIS(PIT_CHANNEL0);
				PIT_Running = 0;
			}
			break;
			
	    default:
		    break;
	  }
	}
}

//-----------------Q1-4--------------------
uint16_t CounterValue = 0;

void UpdateLedCounter() {
	gpio_set(LED0, CounterValue%2);
	gpio_set(LED1, CounterValue%4/2);
	gpio_set(LED2, CounterValue%8/4);
	gpio_set(LED3, CounterValue/8);

	if(CounterValue != 0)
		OLED_Print_Num(60, 3, CounterValue);
	else {
		uint8_t temp[2] = {'0', '\0'};
		OLED_P8x16Str(60, 3, temp);
	}
}

void Q1_4(int Index) {
	OLED_CLS();
	switch(Index) {
	case 0:
		if(CounterValue == 15) {
			CounterValue = 0;
			gpio_set(PTH6, 1);
		}
		else
			CounterValue = CounterValue + 1;
		UpdateLedCounter();
		break;
		
	case 1:
		if(CounterValue == 0) {
			CounterValue = 15;
			PIT_IRQ_EN(PIT_CHANNEL1);
		}
		else
			CounterValue = CounterValue - 1;
		UpdateLedCounter();
		break;
		
	case 2:
		CounterValue = (CounterValue << 1)%16;
		UpdateLedCounter();
		break;
		
	case 3:
		CounterValue = (CounterValue >> 1)%16;
		UpdateLedCounter();
		break;
		
	default:
		UpdateLedCounter();
		break;
		//return;
	}
	//UpdateLedCounter();
}

void Q2_1(UARTn uart) {
	while(UARTx[uart]->S1 & UART_S1_RDRF_MASK) {
		uart_putchar(uart, uart_getchar(uart));
	}
}

double Q2_2_Time_ms = 0.0;

void Q2_2_Extra() {
	
	UARTn uart_wave = UARTR0;
	UARTn uart_serial = UARTR2;
	
	double value = sin(Q2_2_Time_ms);
	uartPrintf(uart_serial, "%.6lf\n", value);
	
	double waveData[1];
	waveData[0] = value;
	
	uart_sendware(uart_wave, (uint8_t*)waveData, 8);
	
	Q2_2_Time_ms += 0.01;
	if(Q2_2_Time_ms > 6.2832) 
		Q2_2_Time_ms = 0;
	
	//OLED_CLS();
	OLED_StartQuery();
	
	for(uint8_t i = 0; i < 128; i++) {
		OLED_DrawPoint(i, 31, 1);
	}
	for(uint8_t i = 0; i < 64; i++) {
		OLED_DrawPoint(9, i, 1);
	}
	
	double temp = (Q2_2_Time_ms - 0.49);
	for(uint8_t i = 0; i < 127; i++) {
		double var = sin(temp);
		
		temp += 0.049;
		OLED_DrawPoint(i, (uint8_t)(var * 32) + 31, 1);
	}
	
	OLED_FinishQuery();
}

uint8_t Q2_5_FLAG = 0;
uint8_t Q2_5_CNT  = 0;

void Q2_5(UARTn uart) {
	if(UARTx[uart]->S1 & UART_S1_RDRF_MASK) {
		uint8_t temp = uart_getchar(uart);
		if(temp == 'b' && Q2_5_CNT == 0) {
			Q2_5_CNT = 1;
			
		} else if(temp == 'u' && Q2_5_CNT == 1) {
			Q2_5_CNT = 2;
			
		} else if(temp == 'p' && Q2_5_CNT == 2) {
			Q2_5_CNT = 3;
			
		} else if(temp == 't' && Q2_5_CNT == 3) {
			if(Q2_5_FLAG == 1) {
				Q2_5_FLAG = 0;
				uartPrintf(uart, "\n關閉回顯加密\n");
				
			} else {
				Q2_5_FLAG = 1;
				uartPrintf(uart, "\n開啓回顯加密\n");
				
			}
			Q2_5_CNT = 0;
			
		} else {
			Q2_5_CNT = 0;
			if(Q2_5_FLAG == 0) {
				uart_putchar(uart, temp);
				
			} else {
				if(temp == 'Y') {
					uart_putchar(uart, 'A');
				} else if(temp == 'Z') {
					uart_putchar(uart, 'B');
				} else if(temp == 'y') {
					uart_putchar(uart, 'a');
				} else if(temp == 'z') {
					uart_putchar(uart, 'b');
				} else
					uart_putchar(uart, temp+2);
			}
		}
	}
}

void Q3_1() {
	FTM_PWM_init(CFTM2, FTM_CH0, 50, 5000);
}

void Q3_2() {
	//c0
    uartPrintf(UARTR2,"%d\n",ftm_count_get(CFTM1));
    ftm_count_clean(CFTM1);
}

void Q4() {
	double val;
	double temp = 0.0;
	
	val=(double)adc_once(ADC_CHANNEL_AD6);
	val=(double)adc_ave(ADC_CHANNEL_AD6, 10);
	temp = val / 1000.0;
	
    uart_sendware(UARTR0,(uint8_t*)&temp, 8);
}

uint8_t Depth = 0;
uint8_t Status= 0;

void Q5_1(uint8_t Index) {
	if(Index < 2)
		return;
	
	if(Status == 0) {
		if(Index == 3) {
			Status = 1;
		}else if(Index == 4) {
			Depth++;
		}
	} else if(Status == 1) {
		if(Index == 2) {
			Status = 0;
		}else if(Index == 4) {
			if(Depth > 0)
				Depth--;
		}
	}
	
	//OLED_CLS();
	
	OLED_StartQuery();
	switch(Status) {
	case 0:
		for(uint8_t i = 7; i <= 49; i++) {
			OLED_DrawPoint(i, 63-39, 1);
		}
		for(uint8_t i = 40; i <= 56; i++) {
			OLED_DrawPoint(7, 63-i, 1);
		}
		for(uint8_t i = 7; i <= 49; i++) {
			OLED_DrawPoint(i, 62-55, 1);
		}
		for(uint8_t i = 40; i <= 56; i++) {
			OLED_DrawPoint(49, 63-i, 1);
		}
		break;
		
	case 1:
		for(uint8_t i = 63; i <= 104; i++) {
			OLED_DrawPoint(i, 63-39, 1);
		}
		for(uint8_t i = 40; i <= 56; i++) {
			OLED_DrawPoint(63, 63-i, 1);
		}
		for(uint8_t i = 63; i <= 104; i++) {
			OLED_DrawPoint(i, 62-55, 1);
		}
		for(uint8_t i = 40; i <= 56; i++) {
			OLED_DrawPoint(105, 63-i, 1);
		}
		break;
		
	default:
		break;
	}
	
	OLED_FinishQuery();
	
	OLED_P8x16Str(8, 5, "forwd");
	OLED_P8x16Str(64, 5, "bakwd");
	OLED_P8x16Str(20, 2, "depth ");
	
	if(Depth != 0){
		OLED_Print_Num(76, 2, Depth);
	}
	else {
		uint8_t temp[2] = {'0', '\0'};
		OLED_P8x16Str(76, 2, temp);
	}
	
}

void Q7() {
    gpio_turn(TRIG);
    delayus(10);
	gpio_turn(TRIG);
	
	long stime = 0;
	
	while(!gpio_get(ECHO));
	//PIT_IRQ_EN(PIT_CHANNEL1);
	while(gpio_get(ECHO)) {
		delayus(1);
		stime++;
	}
	//PIT_IRQ_DIS(PIT_CHANNEL1);
	
    int Distance = (int)((double)stime/5.8);
	uart_sendware(UARTR2, (uint8*)&Distance, 4);
	uartPrintf(UARTR0, "distance = %d mm\n", Distance);
}  

//------按題號切換場景,方式:---------------------------
//----------按下Center鍵然後通過USB串口輸入(1/2)位數字---
//------eg:11           refers to Q1_1


void SwitchScene(int sceneCode) {
	DisableInterrupts;
	
	ResetAll_LED();
	
	if(PIT_Running) {
		PIT_IRQ_DIS(PIT_CHANNEL0);
		PIT_Running = 0;
	}
	//---------重置中斷--------
	
	if(sceneCode > SCENE_Q8_4 || sceneCode < 0) {
		EnableInterrupts;
		return;
	}
	
	OLED_CLS();
	uint8_t msg_slice_1[10] = {'S', 'w', 'i', 't', 'c', 'h', ' ', 't', 'o', '\0'};
	OLED_P8x16Str(0, 0, msg_slice_1);
	
	uint8_t msg_slice_2[2] = {'Q', '\0'};
	OLED_P8x16Str(0, 3, msg_slice_2);
	OLED_Print_Num(12, 3, (uint8_t)sceneCode);
	
	Scene = sceneCode;
	
	EnableInterrupts;
	
	switch(Scene) {
	case SCENE_Q1_2:
		PIT_ResetInterval(PIT_CHANNEL0, 1);
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		led_index = -1;
		break;
		
	case SCENE_Q1_3:
		PIT_ResetInterval(PIT_CHANNEL0, 1);
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		led_index = -1;
		break;
		
	case SCENE_Q1_4:
		CounterValue = 0;
		break;
		
	case SCENE_Q2_2:
		PIT_ResetInterval(PIT_CHANNEL0, 100);
		Q2_2_Time_ms = 0.0;
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		break;
		
	case SCENE_Q2_5:
		Q2_5_FLAG = 0;
		Q2_5_CNT  = 0;
		break;
		
	case SCENE_Q3_1:
		Q3_1();
		break;
		
	case SCENE_Q3_2:
		Q3_1();
		ftm_count_init(CFTM1);
		PIT_ResetInterval(PIT_CHANNEL0, 1);
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		break;
		
	case SCENE_Q4:
		PIT_ResetInterval(PIT_CHANNEL0, 50);
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		Q4();
		break;
		
	case SCENE_Q5_1:
		Depth = 0;
		Status= 0;
		break;
		
	case SCENE_Q7:
		PIT_ResetInterval(PIT_CHANNEL0, 5);
		PIT_IRQ_EN(PIT_CHANNEL0);
		PIT_Running = 1;
		break;
		
	default:
		break;
	}
}

//-----------測試用方向鍵及打印響應------------
//-----------利用狀態機進行按鍵消抖-----------
//---------------或者利用while阻塞------------
//-for test, only enable single click operation--
int SomeKeyPressed = 0;

void Keys_DebugOutput(int Index) {
//	uartPrintf(UARTR0, "GPIO_Keyboard's Status: %d %d %d %d %d\n", gpio_get(Key_UP), gpio_get(Key_DOWN),
//		   gpio_get(Key_LEFT), gpio_get(Key_RIGHT), gpio_get(Key_CENTER));
	
	OLED_CLS();
	
	uint8_t* KbTestMsg = NULL;
	
	switch(Index) {
	case 0:
		uartPrintf(UARTR0, "[KEYBOARD]: Up Pressed\n");
		KbTestMsg = (uint8_t*)malloc(3);
		memset(KbTestMsg, '\0', 3);
		
		KbTestMsg[0] = 'U'; KbTestMsg[1] = 'P';
		OLED_P8x16Str(0, 0, KbTestMsg);
		break;
		
	case 1:
		uartPrintf(UARTR0, "[KEYBOARD]: Down Pressed\n");
		KbTestMsg = (uint8_t*)malloc(5);
		memset(KbTestMsg, '\0', 5);
		
		KbTestMsg[0] = 'D'; KbTestMsg[1] = 'O'; KbTestMsg[2] = 'W'; KbTestMsg[3] = 'N';
		OLED_P8x16Str(0, 0, KbTestMsg);
		break;
		
	case 2:
		uartPrintf(UARTR0, "[KEYBOARD]: Left Pressed\n");
		KbTestMsg = (uint8_t*)malloc(5);
		memset(KbTestMsg, '\0', 5);
		
		KbTestMsg[0] = 'L'; KbTestMsg[1] = 'E'; KbTestMsg[2] = 'F'; KbTestMsg[3] = 'T';
		OLED_P8x16Str(0, 0, KbTestMsg);
		break;
		
	case 3:
		uartPrintf(UARTR0, "[KEYBOARD]: Right Pressed\n");
		KbTestMsg = (uint8_t*)malloc(6);
		memset(KbTestMsg, '\0', 6);
		
		KbTestMsg[0] = 'R'; KbTestMsg[1] = 'I'; KbTestMsg[2] = 'G'; KbTestMsg[3] = 'H'; KbTestMsg[4] = 'T';
		OLED_P8x16Str(0, 0, KbTestMsg);
		break;
		
	case 4:
		uartPrintf(UARTR0, "[KEYBOARD]: Center Pressed\n");
		KbTestMsg = (uint8_t*)malloc(7);
		memset(KbTestMsg, '\0', 7);
		
		KbTestMsg[0] = 'C'; KbTestMsg[1] = 'E'; KbTestMsg[2] = 'N'; KbTestMsg[3] = 'T'; KbTestMsg[4] = 'E'; KbTestMsg[5] = 'R';
		OLED_P8x16Str(0, 0, KbTestMsg);
		break;
		
	default:
		return;
	}
	
	free(KbTestMsg);
	KbTestMsg = NULL;
	
}

//-------------接收並檢測輸入的事哪一個按鍵-------------
void HandleDirectionKeys(void) {
	
	uint8_t KeyStatus[5] = {0, 0, 0, 0, 0};
	KeyStatus[0] = gpio_get(Key_UP);
	KeyStatus[1] = gpio_get(Key_DOWN);
	KeyStatus[2] = gpio_get(Key_LEFT);
	KeyStatus[3] = gpio_get(Key_RIGHT);
	KeyStatus[4] = gpio_get(Key_CENTER);
	int Index = -1;
	for(int i = 0; i < 5; i++) {
		if(!KeyStatus[i]) {
			Index = i;
			break;
		}
	}
	
	if(SomeKeyPressed == 1 || Index == -1)
		return;
	
	SomeKeyPressed = 1;
	
	switch(Scene) {
	case SCENE_DEBUG:
		Keys_DebugOutput(Index);
		break;
		
	case SCENE_Q1_4:
		Q1_4(Index);
		break;
	
	case SCENE_Q5_1:
		Q5_1(Index);
		break;
	
	default:
		break;
	}
	
	delayms(255);
	uartPrintf(UARTR0, "Keys Interrupt Reseted.\n");
	
	SomeKeyPressed = 0;
}
發佈了19 篇原創文章 · 獲贊 7 · 訪問量 5163
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章