根据北京邮电大学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;
}