嵌入式系统导论实验报告
一、实验目的
1、进一步掌握本学期以来所做实验用到的各种元器件的使用方法和编程;
2、加深GPIO、中断、定时器、LED等的使用;
3、加强综合问题解决能力和拓展思维创新能力。
二、设计思路
设置一个flag的全局变量,初始化为0x00,当按下SW1时,触发边沿触发中断,将flag改为0x11,当按下SW2时,通过查询方式,将flag改为0x01。
在main函数中,首先通过定时函数,延时1s,然后初始化Timer0A中断,在Timer0A中断的handler中,通过判断不同flag重新设置不同的频率,在Timer0A中断触发调用的UserTask中,通过判断不同的flag,使用不同的LED灯的变换模式。
三、实现功能
1、程序开始时,有1s的延迟;
2、程序初始为,LED以16HZ的频率在8种颜色中切换;
3、按下SW1后,LED以8HZ的频率在4种颜色中切换;
4、按下SW2后,LED以1HZ的频率在4种颜色中切换;
四、使用工具
软件:Keil
硬件:Tiva C Series TM3C123G LaunchPad
五、程序流程图
1、主程序
2、PF4下降沿触发中断
3、系统定时器中断
4、Timer0A中断
六、实际运行现象
1、程序开始,有1s的延迟
2、1s后,程序以高频率切换灯的颜色
3、按下SW2,LED以低频率在4种颜色中切换
4、按下SW1,LED以中等频率在4种颜色中切换
七、设计分析体会
在完成这次实验之前,我翻看了以前的实验报告和工程文件,对这门课这半个学期所学到的知识进行了一个复习和整合。
这次实验基本上就是对之前所学知识的运用和思考。一开始,我尝试在一个中断中触发另一个中断,结果发现,完成不了状态的切换。理论知识的不够,导致实验过程中犯下了这样的错误,不过也算是有所收获。在和同学讨论之后,我通过一个flag,在每次中断时判断灯的亮灭顺序和速度,虽然确定了思路,但在实验过程中还是遇到了一些小问题,这还是源于自己对于这方面的知识了解不够深入。
虽然实验完成后,看着结果,感觉好像也不是很复杂,但是在实验过程中走过的歪路确实不少的,这次实验,我反复观看上课时录下的视频,并结合代码,加深了对实验原理的理解,尤其是中断部分。
附录
常量定义
#define WHEELSIZE 8 // must be an integer multiple of 2
#define WHEELSIZE2 4
#define F1HZ (50000000/1)
#define F8HZ (50000000/8)
#define F16HZ (50000000/16)
const long COLORWHEEL[WHEELSIZE] = {RED, RED+GREEN, GREEN, GREEN+BLUE, BLUE, BLUE+RED, RED+GREEN+BLUE, 0};
const long COLORWHEEL2[WHEELSIZE2] = {RED,GREEN,BLUE,RED+GREEN+BLUE};
const long COLORWHEEL3[WHEELSIZE2] = {RED+GREEN,GREEN+BLUE,BLUE+RED,0};
uint32_t flag = 0x00;
static int cnt=0;
主程序
int main(void){
DisableInterrupts();
uint32_t status;
PLL_Init(); // bus clock at 50 MHz
PortFinit();
EdgeCounter_Init();
LEDS = 0; // turn all LEDs off
//Timer0A_Init(&UserTask, F20KHZ); // initialize timer0A (20,000 Hz)
//SysTick_Init(500000);
//Timer0A_Init(&UserTask, F16HZ); // initialize timer0A (16 Hz)
EnableInterrupts();
SysTick_Init(); // initialize SysTick timer,
SysTick_Wait10ms(100);
Timer0A_Init(&UserTask);
while(1){
status = PortF_Input();
if(status==0x0){
flag = 0x01; //SW2 pressed
cnt = 0;
}
}
}
PF4下降沿触发中断切换flag
void GPIOPortF_Handler(void){
GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4
flag = 0x11;
cnt = 0;
FallingEdges = FallingEdges + 1;
}
中断函数根据flag变化频率
void Timer0A_Handler(void){
uint32_t period=F16HZ;
if(flag==0x00){
period=F16HZ;
}
else if(flag==0x01){
period=F1HZ;
}
else if(flag==0x11){
period=F8HZ;
}
TIMER0_TAILR_R = period-1;
TIMER0_ICR_R = TIMER_ICR_TATOCINT;// acknowledge timer0A timeout
(*PeriodicTask)(); // execute user task
}
中断函数调用的UserTask根据flag选择灯的颜色顺序
void UserTask(void){
if(flag==0x00){LEDS = COLORWHEEL[cnt&(WHEELSIZE-1)];}
else if(flag==0x01){LEDS = COLORWHEEL2[cnt&(WHEELSIZE2-1)];}
else if(flag==0x11){LEDS = COLORWHEEL3[cnt&(WHEELSIZE2-1)];}
cnt = cnt + 1; //全局变量cnt保证每次切换状态后,灯重新开始亮灭。
}