ARM实训报告.docx
- 文档编号:25088847
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:20
- 大小:240.75KB
ARM实训报告.docx
《ARM实训报告.docx》由会员分享,可在线阅读,更多相关《ARM实训报告.docx(20页珍藏版)》请在冰豆网上搜索。
ARM实训报告
成绩
《ARM嵌入式系统》
课程设计报告
题目:
外部按键中断延迟控制设计
学生姓名:
夜阑寄语
学生学号:
年级:
专业:
班级:
指导教师:
电子工程学院制
2016年12月
目录
一、实训目的:
3
二、实训内容:
3
三、实训要求:
3
四、实训过程:
3
1、STM32外部中断简介:
3
2、电路设计:
5
3、算法设计:
6
4、部分源代码:
8
五、实训结果:
19
六实训小结:
21
一、实训目的:
1.掌握STM32项目开发流程;
2.学会画出算法流程图;
3.掌握外部按键中断延迟、LED控制编程。
二、实训内容:
完成下列任务的项目:
(1)按键KEY0,在中断程序中控制LED0亮、3s后熄灭;
(2)按键KEY1,在中断程序中也控制LED0亮、3s后熄灭;
(3)按键KEY2,在中断程序中控制LED0和LED1同时亮5s,然后熄灭。
三、实训要求:
1、绘出流程算法图;
2、用C语言实现算法;
3、建立工程项目,生成目标文件;
4、将目标文件编程下载到开发板,观察结果是否满足设计要求。
四、实训过程:
1、STM32外部中断简介:
STM32的每个IO都可以作为外部中断的中断输入口,这点也是STM32的强大之处。
STM32F103的中断控制器支持19个外部中断/事件请求。
每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
STM32F103的19个外部中断为:
线0~15:
对应外部IO口的输入中断;
线16:
连接到PVD输出;
线17:
连接到RTC闹钟事件;
线18:
连接到USB唤醒事件。
从上面可以看出,STM32供IO口使用的中断线只有16个,但是STM32的IO口却远远不止16个,那么STM32是怎么把16个中断线和IO口一一对应起来的呢?
于是STM32就这样设计,GPIO的管教GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线15~0。
这样每个中断线对应了最多7个IO口,以线0为例:
它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。
而中断线每次只能连接到1个IO口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO上了。
下面我们看看GPIO跟中断线的映射关系图:
图1GPIO和中断线的映射关系图
2、电路设计:
(1)使用LED0和LED1两个LED,连接图如下图所示:
图2LED原理图
(2)所用到的硬件只有LED(DS0和DS1)。
LED与MCU连接,实现定时控制LED闪烁,其原理图如下所示:
图3LED与STM32连接原理图
3、算法设计:
算法解释:
通过if选择语句实现按键选择功能
按下KEY0时,实现函数
LED0=0;
delay_ms(1500);
delay_ms(1500);
按下KEY1时,实现函数
LED0=0;
delay_ms(1500);
delay_ms(1500);
按下WK_UP时,实现函数
LED0=0;
LED1=0;
delay_ms(1500);
delay_ms(1500);
delay_ms(1500);
delay_ms(500);
LED0=1;
LED1=1;
4、部分源代码:
外部中断程序:
#include"exti.h"
#include"led.h"
#include"key.h"
#include"delay.h"
#include"usart.h"
voidEXTIX_Init(void)
{
EXTI_InitTypeDefEXTI_InitStructure;
NVIC_InitTypeDefNVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
KEY_Init();
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
voidEXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP==1)
{
LED0=0;
LED1=0;
delay_ms(1500);
delay_ms(1500);
delay_ms(1500);
delay_ms(500);
LED0=1;
LED1=1;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
voidEXTI9_5_IRQHandler(void)
{
delay_ms(10);
if(KEY0==0){
LED0=0;
delay_ms(1500);
delay_ms(1500);
LED0=1;
}
EXTI_ClearITPendingBit(EXTI_Line5);
}
voidEXTI15_10_IRQHandler(void)
{
delay_ms(10);
if(KEY1==0){
LED0=0;
delay_ms(1500);
delay_ms(1500);
LED0=1;
}
EXTI_ClearITPendingBit(EXTI_Line15);
程序解释:
#include"exti.h"
#include"led.h"
#include"key.h"
#include"delay.h"
#include"usart.h"
引用能使用到的头文件:
"exti.h"外部中断:
"led.h"LED灯:
"key.h"按键:
"delay.h"延迟函数:
"delay.h"串口。
因为WK_UP按键是高电平有效的,而KEY0,KEY1是低电平有效的,所以WK_UP=1时触发中断,KEY=0时触发中断,KEY1=0时触发中断。
当KEY0=0时,LED0亮,3s之后LED0灭,并清除Line9_5上的中断标志位后,使KEY1=0,LED1亮3s之后灭,并清除Line15上的中断标志位,使WK_UP=1,两个灯同时亮5s后同时熄灭,并清除Line0上的中断标志位,清除标志位是为了清除已发生的中断请求,使其不影响后面中断的发生。
中间有个10s的延迟是为了消除抖动。
按键程序:
#include"key.h"
#include"delay.h"
voidKEY_Init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
u8KEY_Scan(u8mode)
{
staticu8key_up=1;
if(mode)key_up=1;
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
delay_ms(10);
key_up=0;
if(KEY0==0)returnKEY0_PRES;
elseif(KEY1==0)returnKEY1_PRES;
elseif(WK_UP==1)returnWKUP_PRES;
}elseif(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return0;
}
LED灯程序:
#include"led.h"
voidLED_Init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
延迟程序:
#include"delay.h"
#ifSYSTEM_SUPPORT_OS
#include"includes.h"
#endif
staticu8fac_us=0;
staticu16fac_ms=0;
#ifdefOS_CRITICAL_METHOD
#definedelay_osrunningOSRunning
#definedelay_ostickspersecOS_TICKS_PER_SEC
#definedelay_osintnestingOSIntNesting
#endif
voiddelay_osschedlock(void)
{
#ifdefCPU_CFG_CRITICAL_METHOD
OS_ERRerr;
OSSchedLock(&err);
#else
OSSchedLock();
#endif
}
voiddelay_osschedunlock(void)
{
#ifdefCPU_CFG_CRITICAL_METHOD
OS_ERRerr;
OSSchedUnlock(&err);
#else
OSSchedUnlock();
#endif
}
voiddelay_ostimedly(u32ticks)
{
#ifdefCPU_CFG_CRITICAL_METHOD
OS_ERRerr;
OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err);
#else
OSTimeDly(ticks);
#endif
}
voidSysTick_Handler(void)
{
if(delay_osrunning==1)
{{
OSIntEnter();
OSTimeTick();
OSIntExit();
}
}
#endif
voiddelay_init()
{
#ifSYSTEM_SUPPORT_OS
u32reload;
#endif
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SystemCoreClock/8000000;
#ifSYSTEM_SUPPORT_OS
reload=SystemCoreClock/8000000;
reload*=1000000/delay_ostickspersec;
fac_ms=1000/delay_ostickspersec;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
#else
fac_ms=(u16)fac_us*1000;
#endif
}
#ifSYSTEM_SUPPORT_OS
voiddelay_us(u32nus)
{
u32ticks;
u32told,tnow,tcnt=0;
u32reload=SysTick->LOAD;
ticks=nus*fac_us;
tcnt=0;
delay_osschedlock();
told=SysTick->VAL;
while
(1)
{
tnow=SysTick->VAL;
if(tnow!
=told)
{
if(tnow elsetcnt+=reload-tnow+told; told=tnow; if(tcnt>=ticks)break; } }; delay_osschedunlock(); } voiddelay_ms(u16nms) { if(delay_osrunning&&delay_osintnesting==0) { if(nms>=fac_ms) { delay_ostimedly(nms/fac_ms) } nms%=fac_ms; } delay_us((u32)(nms*1000)); } #else voiddelay_us(u32nus) { u32temp; SysTick->LOAD=nus*fac_us; SysTick->VAL=0x00; SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; do { temp=SysTick->CTRL; }while((temp&0x01)&&! (temp&(1<<16))); SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; SysTick->VAL=0X00; } voiddelay_ms(u16nms) { u32temp; SysTick->LOAD=(u32)nms*fac_ms; SysTick->VAL=0x00; SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; do { temp=SysTick->CTRL; }while((temp&0x01)&&! (temp&(1<<16))); SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; SysTick->VAL=0X00; } #endif 五、实训结果: 六实训小结: 每一次的实验都有不一样的感觉,这次的实验是在外部中断程序上加了一个延迟的效果,虽然是重复着课堂上老师所说的编程、调试、检验三个步骤,但是很明显自己一个人独立完成这项任务就显得很吃力,反应了自己对老师所说的知识不能很好的掌握。 自己在改程序时觉得自己有想法但是不能用代码曲表达出来,发现自己操作所学到的和课堂上所学到的还是有所不同的。 希望自己以后能更加努力,去克服学习中遇到的困难。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 报告