例程1. LKB -- 慕司板IAP15
来源:互联网 发布:java桌面开发框架 编辑:程序博客网 时间:2024/05/22 00:12
LKB是LED、KEY、Buzzer的首字母缩写,代表LED、按键、蜂鸣器的操作,都属于基本的IO(GPIO)操作。
慕司板(IAP15)板载一个用户LED(蓝色光)、10个独立按键、1个无源蜂鸣器,电路如下:
与单片机的对应关系如下图:
先说说GPIO(通用IO口):
贴片44个引脚的IAP15L2K61S2有42个GPIO口(P0、P1、P2、P3、P4、P5.4、P5.5),除了VCC和GND,都是可用的GPIO口。芯片手册中明确指出STC15系列单片机的I/O口有4种工作类型,通过PxM1和PxM0(x:0~5)设置:
复位后默认IO为准双向口模式,如欲设定P25(对应慕司板的蜂鸣器)为推挽输出:
P2M1 &= 0xdf; //1101 1111,第5位清0P2M0 |= 0x20; //0010 0000,第5位置1
LED不用多说,对应引脚等于0即可点亮,1熄灭。
无源蜂鸣器使用一个S8050的NPN晶体管,工作在截止区或饱和区而不是三极管的放大区,仅起开关作用,10K的下拉电阻确保晶体管可以稳定关断。实验表明,设置为推挽输出才能响(同理,把蜂鸣器换成继电器等,也要设置为推挽),初始化代码(lkb.c)如下:
*****************************************设置蜂鸣器端口为推挽输出****************************************/void LKB_Init(){ P2M1 &= 0xdf; //P25清0:1101 1111 P2M0 |= 0x20; //P25置1:0010 0000}
蜂鸣器有频率和鸣响时间两个参数,于是又有了Buzzer_Func()函数(lkb.c中):
/*****************************************无源蜂鸣器频率、时间控制函数*Freq:蜂鸣器频率*time: 蜂鸣器响的时间:ms****************************************/void Buzzer_Func(unsigned int Freq,unsigned int time){ unsigned int i; for(i=0;i<time*Freq/500;i++) { BEEP=~BEEP; Delay_us(500000L/Freq); //最低500000L/65536=7.6Hz约8Hz 最高500 000Hz } BEEP=0; //关闭蜂鸣器}
至于按键,考虑到每个按键的独立性以及可能作为其它用途,十个按键均为独立按键,参考了正点原子的代码:
/******************************************按键扫描函数(参考自正点原子按键程序)*mode:*0 不支持连按*1 支持连按*****************************************/void Key_Scan(unsigned char mode){ static unsigned char key_up=1;//按键按松开标志 if(mode) key_up=1; //支持连按 if(key_up && (KEY1==0 || KEY2==0 || KEY3==0 || KEY4==0 || KEY5==0 ||KEY6==0 || KEY7==0 || KEY8==0 || KEY9==0 || KEY10==0) ) //有按键按下 { Delay_ms(10); key_up=0; if(KEY1==0) Key_Num = 1; else if(KEY2==0) Key_Num = 2; else if(KEY3==0) Key_Num = 3; else if(KEY4==0) Key_Num = 4; else if(KEY5==0) Key_Num = 5; else if(KEY6==0) Key_Num = 6; else if(KEY7==0) Key_Num = 7; else if(KEY8==0) Key_Num = 8; else if(KEY9==0) Key_Num = 9; else if(KEY10==0) Key_Num = 10; else Key_Num=0; } else if( (KEY1==1) && (KEY2==1) && (KEY3==1) && (KEY4==1) && (KEY5==1) &&(KEY6==1) && (KEY7==1) && (KEY8==1) && (KEY9==1) && (KEY10==1)) // 无按键按下 { key_up=1; Key_Num=0; } else Key_Num=0; }
Key_Num是全局变量,在lkb.c中定义,在config0.h中作了声明:
extern unsigned char Key_Num;
当然,按键程序千千万,需要实现什么功能要自己会改,如常说的点动(按住不松手就输出,一松手就停止输出,类似上面程序中的连按模式)、互锁(各个按键是互斥的,如电风扇的1档和2档不能同时按下)、自锁(按一下就连续运转),具体介绍如下:
点动,用英文字母M代表(如遥控器工作方式为M4,代表点动方式,有ABCD
4个按键),即手按遥控器的每一个键,相应继电器接通,松开遥控器按键,相应继电器断开,一次只有一路继电器是接通的。例如一路直流开关,用一键遥控器控制。一直按着遥控器按键,则继电器一直接通,松开按键,继电器断开。互锁,用英文字母L代表,手按遥控器第一个键,相应继电器接通,再按另一个按键,相应继电器接通,之前接通的那路继电器则断开,它具有唯一关系,每次只有按的那一路继电器接通,之前接通的会断开。例如二路直流互锁遥控开关,用二键遥控器控制(A、B两键)。按A键时,A对应的继电器会接通,按B键时,B键对应的继电器会接通,A键对应的断开。
自锁,用英文字母T代表,同一个键控制一路,按一次开,再按一次关,可独立控制,可同时有多个通断。像家里有的灯具遥控开关,基本上都是使用自锁功能。如四路直流自锁开关,用桃木四键遥控器控制(ABCD四键),按A时,A对应的继电器接通,再按一下A时,A对应的继电器断开,其它按键亦然。可逐次按下ABCD四键,则四路继电器都接通。
回到程序来,main.c中我们实现按键的点动方式?按下一个按键,蜂鸣器响一声(300ms),然后反转蓝光LED的状态:
void main(){ Delay_us(10); LKB_Init(); while(1) { Key_Scan(0); //可以试试为1时按下的情况 if(Key_Num) { Buzzer_Func(Key_Num*500,300); LED1 = ~LED1; //位取反 } }}
按下F7编译,设置好仿真:
按下Ctrl+F5进入仿真,按下F5全速运行,这时按下十个按键可以听到十种不同频率的声音,并能看到LED的状态反转。
由于蜂鸣器和按键扫描函数均使用了Delay,单片机空跑,比较浪费时间,下一节我们将用定时器改造我们的代码,使单片机的效率大大提高。
后面例程的学习也类似,看示例代码,比照芯片手册相应章节的寄存器定义,看懂驱动程序,运行程序,自己可以试着修改一下。这样,用不了多长时间,一款单片机就能学会的。
原作于 2014年10月
CSDN发表于2016年4月
weifengdq
- 例程1. LKB -- 慕司板IAP15
- 例程3. 串口 -- 慕司板IAP15
- 例程5. ADC -- 慕司板IAP15
- 例程8. PCA_PWM -- 慕司板IAP15
- 例程7. HMC5883工程说明 -- 慕司板IAP15
- 例程9. NRF24L01工程说明 -- 慕司板IAP15
- 例程6. MPU6050工程变量超出data区的解决办法 -- 慕司板IAP15
- 序 -- 慕司板IAP15
- 慕司板编程说明 -- 慕司板IAP15
- 软件安装与仿真设置 -- 慕司板IAP15
- IAP15L2K61S2新建工程与点灯 -- 慕司板IAP15
- 演示程序之打游戏 -- 慕司板IAP15
- IAP15 + MATLAB + Serial Chart综合测试
- 例程
- 例程4. SPI_LCD -- 慕司板IAP
- atmega8 例程:12864例程
- 开始例程,结束例程,专家例程
- 1.写出下例程序的运行结果
- 第六周项目一-分数类的雏形(1)
- PHPExcel导出
- Java NIO -AtomicInteger
- ViewPager
- achartengine/MPAndroidChart——图表实现之Java
- 例程1. LKB -- 慕司板IAP15
- 1.Mysql数据库的优化技术(1)
- HDOJ 1202 The calculation of GPA
- linux yum命令详解
- Codeforces Round #346 (Div. 2) B (pair+vector的应用)
- Mac下使用git和github
- TextView设置字体颜色的几种方法简记
- Unity3D研究院之两种方式播放游戏视频-转自雨松mono
- java虚拟机HotSpot 的 GC 算法实现