完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
用的52单片机,但是蜂鸣器无法响。求大神解答,谢谢
#include #include ***it left=P3^0; ***it right= P3^2; ***it fuyuan=P3^1; ***it led1=P1^0; ***it led2=P1^1; ***it led3=P1^2; ***it bee=P2^3; ***it beekey=P3^3; int i=1; void delay1s(void) // 1秒延时 { unsigned char a,b,c; for(c=46;c>0;c--) for(b=152;b>0;b--) for(a=70;a>0;a--); _nop_(); //if Keil,require use intrins.h } void delay(void) // 10微妙延时 { unsigned char a,b,c; for(c=5;c>0;c--) for(b=4;b>0;b--) for(a=248;a>0;a--); } void Inittimer0(void) //定时器0; { TMOD = 0x01; TH0 = 0x0FF; TL0 = 0x9C; EA = 1; ET0 = 1; TR0 = 1; } void beescankey() //按下蜂鸣器响 { if(beekey==0) { delay(); if(beekey==0) { bee=1; while(beekey==0) ; bee=0; } } } void scankey() //按下L独立按键 ,led灯亮 { if(left==0) { delay(); if(left==0) { led1=0; while(left==0) ; delay1s() ; led1=1; } } if(right==0) { delay(); if(right==0) { led3=0; while(right==0) ; delay1s() ; led3=1; } } if(fuyuan==0) { delay(); if(fuyuan==0) { led2=0; while(fuyuan==0) ; delay1s() ; led2=1; } } } void main() { InitTimer0(); while(1) scankey(); } void Timer0Interrupt(void) interrupt 1 { TH0 = 0x0FF; TL0 = 0x9C; beescankey() ; } |
|
相关推荐
6个回答
|
|
d顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
|
|
|
|
把按键里面就加一个bee=1看看会不会响,感觉有可能松手有问题
|
|
|
|
版权声明:本文为博主原创文章,未经博主允许不得转载。
最近写一个程序,需要在用户模式下关中断,但ARM 7的体系结构决定了中断必须在特权模式下才可以更改,所以想到使用ARM的软中断来实现关中断和开中断. 使用软中断,首先要有硬件指令的支持.ARM有条指令是SWI. SWI 指令的格式为: SWI {条件} 24 位的立即数 SWI 指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。操作系统在 SWI 的异常处理程序中提供相应的系统服务,指令中 24 位的立即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传递,当指令中 24 位的立即数被忽略时,用户程序调用系统例程的类型由通用寄存器 R0 的内容决定,同时,参数通过其他通用寄存器传递。 指令示例: SWI 0x02 ;该指令调用操作系统编号位02的系统例程。 在keil MDK中,关键字__svc可以产生硬件SWI指令,使得处理器能响应软件中断.关键字__svc,keil MDK帮助文件中这样描述: __svc 关键字声明超级用户调用 (SVC) 函数,该函数最多使用四个类似于整数的参数,并通过 value_in_regs 结构最多返回四个结果。 __svc 是一个函数限定符。它影响函数的类型。 语法 __svc(int svc_num) return-type function-name([argument-list]); 其中: svc_num 是在 SVC 指令中使用的立即值。 它是一个表达式,其计算结果为以下范围内的整数: • 在 ARM 指令中为 0 到 224–1 (24 位值) • 在 16 位 Thumb 指令中为 0-255 (8 位值)。 要在keil MDK中使用软件中断,要做好两件事:第一件,更改启动文件,编写软件中断的汇编入口.在这个汇编入口中主要根据软件中断命令号进行相应的函数跳转.第二件,编写相应命令号的C语言服务函数.下面举例怎么样用软件中断实现开中断和关中断. 第一步:更改启动代码 keil MDK自带的启动代码有类似下面的语句: Vectors LDR PC, Reset_Addr LDR PC, Undef_Addr LDR PC, SWI_Addr LDR PC, PAbt_Addr LDR PC, DAbt_Addr 蓝色语句是程序复位后要执行的第一条指令,即复位异常入口;而红色语句就是执行一个软件中断指令后,要跳转到的软件中断异常入口.通过语句"SWI_Addr DCD SWI_Handler"进行中转,软件中断会跳转到标号为SWI_Handler的语句处,该处即处理软件中断的命令号.源代码如下: EXPORT SWI_Handler extern EnableIrqFunc ;使能中断函数名,用C语言实现 extern DisableIrqFunc ;禁止中断函数名,用C语言实现 SWI_Handler STMFD SP!, {R0,R12,LR} ;入栈 LDR R0, [LR,#-4] ;取指令 BIC R0,R0,#0xFF000000 ;取软件中断命令号 CMP R0,#0 ;和0比较,因为我的使能中断用了软件中断命令0,禁止中断使用了软件中断命令1 BLEQ EnableIrqFunc ;为零调用使能中断函数 BLNE DisableIrqFunc ;不为零调用禁止中断函数 LDMFD SP!,{R0,R12,PC}^ ;出栈 第二部:编写相应命令号的C语言服务函数. 声明软件中断: __svc(0x00) void EnableIrq(void); //使能中断 __svc(0x01) void DisableIrq(void); //禁止中断 编写服务函数: [cpp] view plain copy print? void DisableIrqFunc(void) { int temp; __asm { MRS temp,SPSR ORR temp,temp,#0x80 MSR SPSR_c,temp } } void EnableIrqFunc(void) { int temp; __asm { MRS temp,SPSR BIC temp,temp,#0x80 MSR SPSR_c,temp } } 到此,使能和禁止中断的软中断就结束了,下面看一下执行过程. 在程序中,如果想关中断,只需使用:DisableIrq(); MDK编译器在执行这句函数时,自动用软中断指令代替,即: SWI 0x01 ARM执行这条软件中断指令后,发生软件中断异常,程序跳转到软件中断异常服务函数处,即汇编代码标号为SWI_Handler处,在这里判断软件中断命令号是0x01,然后执行 BLNE DisableIrqFunc 语句,调用禁止中断函数,实现关中断. |
|
|
|
|
|
|
|
专业打酱油的路过!!!!!!!!!!!!!!!!
|
|
|
|
顶顶顶顶顶顶顶顶顶顶
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
串口发送中断中对发送I/O口定义为GPIO输出,出现发送数据不完整,缺少2个字节,求解答
1589 浏览 3 评论
777 浏览 0 评论
【xG24 Matter开发套件试用体验】10-Bluetooth示例1
908 浏览 0 评论
996 浏览 0 评论
【xG24 Matter开发套件试用体验】power specification电源规格参数配置
810 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
10866 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-27 04:19 , Processed in 0.856009 second(s), Total 80, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191