【自学51单片机】9 -- 步进电机原理、蜂鸣器原理,单片机IO口的结构,上下拉电阻
1、单片机IO口的结构
单片机IO口有四种结构:准双向IO,开漏输出、强推挽输出和高阻态输出。内部结构如下图。
T1和T2为MOS管,靠电压导通的原件。(1)准双向IO口特点:内部输出为1,才能正常读取外部信号。(2)开漏输出特点:必须外加上拉电阻,不然单片机IO电平是个不确定的态。(3)强推挽输出特点:可输出或输入高电流,驱动能力强。(4)强阻态特点:状态取决与外部输入。 标准51单片机P0默认开漏输出。
2、上下拉电阻
上下拉电阻:上拉电阻就是将不确定的信号通过一个电阻拉到高电平,同时此电阻也起限流作用,下拉电阻同理。
上拉电阻的应用:(1)OC门(开漏输出中,三极管的集电极)要输出高电平,外部必须加上拉电阻(2)加大普通IO口的驱动能力(3)起到限流的作用(4)抵抗电磁干扰
电路设计中如何选择上下拉电阻阻值:(1)从降低功耗方面考虑应该足够大,因为电阻越大,电流越小。(2)从确保足够的引脚驱动能力考虑应该足够小,电阻越小,电流才能越大。(3)开漏输出时,过大的上拉电阻会导致信号上升沿变缓,解释:电平变化需要时间,开漏输出时,上拉电阻的大小直接影响电平上升的时间,如下图所示。
3、电机
3.1 电机分类
从用途角度分为: 驱动类电机和控制类电机。直流电机属于驱动类电机,这种电机是将电能转换成机械能,应用在电风扇、洗衣机等。步进电机属于控制类电机,它是将脉冲信号转换成一个转动角度的电机,应用在机器人,空调扇叶转动等。
步进电机分为:反应式、永磁式和混合式三种。(1)反应式:结构简单,成本低,性能差(2)永磁式:动态性能好,力矩较大,转动误差相对大一些。(3)混合式:动态性能好,力矩大,转动精度高。
3.2 28BYJ-48型步进电机
28BYJ-48实物如下图9-3
1、28 — 步进电机的有效最大外经28mm。
2、B — 表示是步进电机。
3、Y — 表示为永磁式。
4、J — 表示是减速型。
5、48 — 表示四相八拍
步进电机结构原理如下图9-4
标注为0~5的齿叫转子,转子是一块永磁体,上带有永久磁性。外圈的齿为定子,图片上有8个,它是固定的。每个定子都绕了线圈绕组,正对的两个定子绕组是串联在一起的,这两定子组成一相。图中一共有A-B-C-D四相。
28BYJ-48电机结构原理如下图
定子上拥有 4 相×8 组=32 个齿。
3.2 28BYJ-48电机转动原理
**原理:**由实物图和原理图可知,红线为公共端,橙,黄,粉,蓝对应A-B-C-D相,P1.0~~P1.3分别控制进步电机的A-B-C-D相,导通D相只需让P1.3输出高电平,使Q5
三极管导通,三极管基极b接地,即能导通A相。导通其他相同理,导通后对应相的定子产生磁性,就会对靠近的转子产生吸引力,使转子转动。
3.3 28BYJ-48电机工作模式
步进电机单四拍模式:单相绕组通电四节拍 。假如一开始电机为28BYJ-48电机结构原理里的状态,完成D-C-B-A依次导通后,即完成4个节拍后,转子会因为吸引力转动转过一组绕组。而每经过 1 个单拍,转子都将转过一个定子齿的角度,转一整圈就需要 4×8=32节拍。一个节拍转子转过11.25度(360/32 ),这个值叫步进角度。
步进电机八拍模式:在单四拍模式的每两个节拍之间再插入一个双绕组导通的中间节拍,比如在单独A导通和单独B导通中间加一个同时A和B导通的节拍。这样转子转一圈就需要8 x 8 = 64节拍。一个节拍转子转过5.625度,相比单四拍模式,该模式转动精度更加精准,输出力矩更大。下面看八拍模式绕组控制顺序表。
从上面表中,可以得到把八节拍下P1的低四位IO控制代码
unsigned char code BeatCode[8] = {
0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
};
3.4 步进电机启动频率
控制电机切换一次节拍需要多长时间?
这个时间由步进电机的启动频率决定,在步进电机空载下不高于启动频率就可以正常启动电机。下面见28BYJ-48电机参数表。
表中28BYJ-48电机启动频率为550.单位P.P.S,即每秒脉冲数,通过计算可以知道单个节拍持续时间应该大于1 / 500 =1.8ms即可让电机正常工作。
3.5 实际28BYJ-48电机外部转轮转一圈的情况
先见电机内部齿轮示意图9-7。
上面讲八节拍模式下转动一圈需要64节拍。实际这转动一圈指的是内部最小的齿轮转动一圈需要的节拍数,外部转轮转动一圈需要的节拍数还需要根据电机减速比参数计算。见表9-2中,28BYJ-48电机减速比为1:64。但因为该电机应用在消费领域,所以该参数表也只是给了一个近似整数的减速比1:64,一般转动角度不超过360度。这就不会导致太大误差。随着转动圈数的增多,误差会发生质变。现在通过计算实际减速比约为1:63.684。这就得出八节拍模式下外部转轮转动一圈需要约4076(64 x 63.684)节拍 。
4、综合小程序–按键控制电机转动
//综合小程序-按键控制步进电机的转动
#include sbit keyin1 = P2^4; sbit keyin2 = P2^5; sbit keyin3 = P2^6; sbit keyin4 = P2^7; sbit keyout1 = P2^3; sbit keyout2 = P2^2; sbit keyout3 = P2^1; sbit keyout4 = P2^0; unsigned char keysta[4][4]= { //记录全部矩阵按键当前状态 {1,1,1,1}, {1,1,1,1},{1,1,1,1},{1,1,1,1} }; unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表 { 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键 { 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键 { 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键 { 0x30, 0x1B, 0x0D, 0x27 } //数字键0、ESC键、 回车键、 向右键 }; signed long beats = 0;电机转动节拍总数 void KeyDriver(); //按键驱动函数 void KeyAction(unsigned char keycode);按键动作函数 void StarMotor(signed long angle);//步进电机启动函数 void StopMotor(); //步进电机停止函数 void KeyScan(); //按键扫描函数 void TurnMotor();//电机转动控制函数 void main() { EA = 1;//使能总中断 TMOD = 0x01;//为T0配置模式1 TH0 = 0xFC;//为T0赋初值0xFC67,定时1ms TL0 = 0x67; TR0 = 1; //开启T0 ET0 = 1; //使能T0中断 while(1) { KeyDriver(); //调用按键驱动函数 } } //按键驱动函数,检测按键动作,调用相应动作函数,需要在主循环中调用 void KeyDriver() { unsigned char i, j; static unsigned char backup[4][4]= { //按键值备份,保存前一次的值 {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1} }; for(i = 0; i < 4; i++) //循环检测4*4的矩阵按键 { for(j = 0; j < 4; j++) { if(backup[i][j] != keysta[i][j])//检测按键动作 { if(backup[i][j] == 0) //按键前次值为0执行动作 { KeyAction(KeyCodeMap[i][j]);//调用按键动作函数 } backup[i][j] = keysta[i][j];//刷新前一次的备份值 } } } } //按键动作函数,根据键码执行相应的操作,keycode为按键键码 void KeyAction(unsigned char keycode) { static unsigned char dirMotor = 0; //电机转动方向 if((keycode >= 0x30) && (keycode <= 0x39))//控制电机转动1~9圈 { if(dirMotor == 0) { StarMotor(360*(keycode - 0x30)); } else { StarMotor(-360*(keycode - 0x30)); } } else if(keycode == 0x26) //向上键,控制转动方向为正转 { dirMotor = 0; } else if(keycode == 0x28)//向下键,控制转动方向为反转 { dirMotor = 1; } else if(keycode == 0X25) //向左键,固定正转90度 { StarMotor(90); } else if(keycode == 0x27) //向右键,固定反转90度 { StarMotor(-90); } else if(keycode == 0x1B) //esc键,停止转动 { StopMotor(); } } //步进电机启动函数,angle为需要转动的角度 void StarMotor(signed long angle) { EA = 0; beats = (angle*4076)/360; //实测为4076拍转动一圈 EA = 1; } //步进电机停止函数 void StopMotor() { EA = 0; beats = 0; EA = 1; } //T0中断服务函数,用于按键扫描与电机转动控制 void InterruptTimer0() interrupt 1 { static bit div = 1; TH0 = 0xFC; //重新加载初值 TL0 = 0x67; KeyScan(); //执行按键扫描 //用一个静态bit变量实现二分频,即定时2ms,用于控制电机 div = ~div; if(div == 1) { TurnMotor(); } } void KeyScan() { unsigned char i; static unsigned char keyout = 0;//矩阵按键扫描输出索引 static unsigned keybuf[4][4] = { //矩阵按键扫描缓冲区 {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF} }; //将一行的4个按键值移入缓冲区 keybuf[keyout][0] = (keybuf[keyout][0] << 1) | keyin1; keybuf[keyout][1] = (keybuf[keyout][1] << 1) | keyin2; keybuf[keyout][2] = (keybuf[keyout][2] << 1) | keyin3; keybuf[keyout][3] = (keybuf[keyout][3] << 1) | keyin4; //消抖后更新按键状态 for (i = 0; i < 4; i++)//每行四个按键,所以循环4次 { if( (keybuf[keyout][i] & 0x0F) == 0x00 ) { //连续4次扫描值为零,即4*4ms内都是按下状态,可认为按键已稳定地按下 keysta[keyout][i] = 0; } if( (keybuf[keyout][i] & 0x0F) == 0x0F ) { //连续4次扫描值为1,即4*4ms内都是弹起状态,可认为按键已稳定地弹起 keysta[keyout][i] = 1; } } keyout++; //输出索引递增 keyout = keyout & 0x03; //索引值加到4后归零 switch(keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚 { case 0:keyout4 = 1; keyout1 = 0;break; case 1:keyout1 = 1; keyout2 = 0;break; case 2:keyout2 = 1; keyout3 = 0;break; case 3:keyout3 = 1; keyout4 = 0;break; default: break; } } //电机控制函数 void TurnMotor() { unsigned char tmp;//临时变量 static unsigned char index = 0; //节拍输出索引 unsigned char code BeatCode[8] = {//步进电机节拍对应的IO控制代码 0x0E, 0x0C, 0x0D, 0x09, 0x0B, 0x03, 0x07, 0x06 }; if(beats != 0)//节拍数不为0则产生一个驱动节拍 { if(beats > 0)//节拍数大于0时正转 { index++; //正转时节拍输出索引递增 index = index & 0x07;//用&操作实现到8归零 beats--;//正转时节拍数递减 } else //节拍数小于零时反转 { index--;//正转时节拍输出索引递减 index = index & 0x07; //用&操作实现到-1时归7 beats++;//正转时节拍数递减 } tmp = P1;//用tmp把P1口当前值暂存 tmp = tmp & 0xF0;//用&操作清空低四位 P1 = tmp | BeatCode[index];//用|操作把节拍代码写到低四位并送到P1 } else //节拍数为零则关闭步进电机所有相 { P1 = 0xFF; } } 因为STC89C52是8位单片机,单片机操作数据时都是按8位即一个字节进行的,操作多个字节数据,无论读还是写就必须分次进行了,所以程序中计算unsigned long型变量beats时,为了防止beats变量在一个一个字节赋值时,突然进入中断,造成beats数值错误,就在进行beats变量赋值前,关闭中断,在赋值后重新打开中断,这就避免了中断的发生。 5、蜂鸣器 有源蜂鸣器:内部带了振荡源,给了BUZZ引脚一个低电平,就会响 无源蜂鸣器:内部带无振荡源,要让它响要给予500Hz ~ 4.5KHzz之间的脉冲频率信号来驱动它。 下面见kst-51开发板中的蜂鸣器电路图 说明:蜂鸣器驱动电流相对较大,因此需要三极管驱动。因为蜂鸣器是感性器件,导通时蜂鸣器电流逐渐变大,关闭后需要续流二极管D4来避免蜂鸣器的电感电流造成的反向冲击。根据电路分析Buzz引脚位于P1.6,那么发声程序就很好编写了。 6、蜂鸣器发声程序 #include sbit Buzz = P1^6;//蜂鸣器控制引脚 unsigned char TORH; //T0重载值的高字节 unsigned char TORL; //T0重载值的低字节 void OpenBuzz(unsigned int frequ); void StopBuzz(); void main() { unsigned int i; EA = 1; //使能总中断 TMOD = 0x01; //配置T0为模式1,但先不启动 while(1) { OpenBuzz(4000);//以4k的频率启动蜂鸣器 for(i = 40000; i > 0; i--);//非精准延时蜂鸣器 StopBuzz();//停止蜂鸣器 for(i = 40000; i > 0; i--); OpenBuzz(1000);//以1kHZ的频率启动蜂鸣器 for(i = 40000; i > 0; i--); StopBuzz();//停止蜂鸣器 for(i = 40000; i > 0; i--); } } //蜂鸣器启动函数,frequ-工作频率 void OpenBuzz(unsigned int frequ) { unsigned int reload;//计算所需的定时器重载值 reload = 65536 - (11059200 / 12)/(frequ*2); //由给定频率计算定时器重载值 TORH = (unsigned char)(reload >> 8);//16位重载值分解为高低两个字节 TORL = (unsigned char)reload; TH0 = 0xFF;//设定一个即将溢出的初值,使定时器马上投入工作 TL0 = 0xFE; ET0 = 1;//使能T0中断 TR0 = 1;//启动T0 } //蜂鸣器停止函数 void StopBuzz() { ET0 = 0;//禁用T0中断 TR0 = 0;//停止T0 } //T0中断服务函数,用于控制蜂鸣器发声 void InterruptTimer0() interrupt 1 { TH0 = TORH;//重新加载重载值 TL0 = TORL; Buzz = ~Buzz;//反转蜂鸣器控制电平 }
上一篇:【自学51单片机】10 --PWM介绍、51单片机RAM区域划分
下一篇:【自学51单片机】8 -- 按键的学习,单片机最小系统
推荐阅读
史海拾趣
在供应链管理方面,Bomar Interconnect公司也进行了一系列优化措施。公司与供应商建立了长期稳定的合作关系,确保原材料的稳定供应和质量可控。同时,公司还加强了对供应链的监控和管理,通过信息化手段提高了供应链的透明度和效率。这些努力不仅降低了公司的采购成本,也提高了供应链的响应速度和灵活性。
为了提升产品质量和竞争力,意普(ESPE)公司开始注重品质管理,建立了严格的质量检测体系。同时,公司积极申请国际认证,成功获得了欧洲四级安全认证体系,进一步提升了产品的国际竞争力。这些努力不仅赢得了客户的信任,也为公司打开了国际市场的大门。
AnalogicTech公司成立于1997年,总部位于美国硅谷。在创立初期,公司面临资金短缺、市场竞争激烈等诸多挑战。然而,凭借创始团队对半导体技术的深刻理解和前瞻视野,AnalogicTech成功开发出一系列具有创新性的产品,逐渐在市场中站稳脚跟。
随着全球对环保和可持续发展的重视,Elcos AG也开始注重自身的环保责任和可持续发展战略。公司采用环保材料和生产工艺,减少了对环境的污染和资源的浪费。同时,Elcos AG还积极参与社会公益事业和环保活动,通过捐款、赞助和志愿服务等方式回馈社会。这些举措不仅提升了公司的社会形象和品牌价值,也为公司的长期发展奠定了坚实的基础。
在环保意识日益增强的今天,锋鸣电子(深圳分公司)积极响应国家号召,致力于绿色电子产品的研发与生产。公司投入大量资金引进环保设备和生产工艺,确保产品从原材料采购到生产制造的全过程都符合环保标准。同时,锋鸣电子还积极推广节能减排理念,为客户提供绿色、低碳的电子产品解决方案。凭借在绿色环保方面的突出表现,锋鸣电子赢得了业界的广泛赞誉。
随着5G技术的快速发展,磁联达(CND-tek)公司意识到无线充电技术将成为未来的重要趋势。公司投入大量资源进行无线充电发射线圈的研发,经过多次试验和改进,终于成功推出了一款性能稳定、效率高的无线充电产品。这一创新不仅为公司带来了丰厚的利润,也进一步巩固了公司在行业内的领先地位。
本帖最后由 paulhyde 于 2014-9-15 09:18 编辑 1、 选择好队友,电子设计需要合作才可以完成。所以选择队友很重要,现在比较流行的说法是一个写软件、一个做硬件、一个写报告。其实我觉得不应该这样:首先电子设计时间短不可能让我们一件事情一件 ...… 查看全部问答∨ |
|
讨论讨论:硬件工程师手册 网上流传*华*为(HW)的硬件工程师手册有一段时间了。2@1IC原来也是有的,现在好像撤掉了。在其他网页,应该还有下载的地方。网上其他公司的手册也有所见,有兴趣的网友可以搜索一下。无意评价那个公司具体的技术水平, ...… 查看全部问答∨ |
最近使用稳压芯片,朋友推荐了一款低价芯片L385可调稳压芯片,先简要介绍给大家。 特点:输出电压可调从1.24~30V; 工作电流从10微安到20豪安; 1% 和2% 初始 ...… 查看全部问答∨ |
我最近准备做一下简易交通灯,利用的主控芯片是AT89C52,时间上是采用定时0的方式1来定时,采用定时器0中断,所采用的语言是C语言,因为定时器0的方式1最多计算65536次,因此我需要放一变量在中断处理函数里,每次相应一次中断后,就在中断处理 ...… 查看全部问答∨ |
|
在很多应用中我们都需要使用到字库,常见的方法有: 1. 把字库放入SD卡中。需要带SD卡,需要使用文件系统,软硬件成本比较高。 2. 把字符放入代码中一起编译,后下载到单片机中。对单片机的FLASH要求比较 ...… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- CE X86下内核编译出错,求教,急急急
- 在ce6下,想做个比较通用的控制gpio口的驱动,想听听各位比较好的提议
- 那位老大对TI的IQMATH库感兴趣?一起把它翻译为C代码如何?
- 我是学国际经济与贸易的的,以前没学过电子,由于工作中的需要,想了解CCL和FE-4方面的知识,请问在网上哪里能够找到这方面的知识啊?另外有哪些书或资料有讲解啊?
- HDP503通用型压力变送器
- 这么好的板子,无人认领!
- 定制型加密芯片全方位保护产品方案
- UC/OS-II 中断嵌套
- 51单片机程序求教怎么才能操作4次那?谢谢了
- tms320f28335英文 PDF,28DSP硬件设计指南,DSP2833x_examples