2017-11-12 21:54:21 pyromaniac 阅读数 1476
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3399 人正在学习 去看看 朱有鹏

1,电平:数字电路中只有两种电平,高电平和低电平,对应的是计算机中的二进制原理。

2,晶振电路:决定单片机运行的节奏,即频率。

3,复位电路:重置开发板。

4,机器周期:一个机器周期包含12个时钟周期,在一个机器周期内,cpu就可以完成一个独立的操作。

5,时钟周期:也称为振荡周期,由晶振电路产生,指的是为单片机提供时钟脉冲信号的振荡源的周期。

6,在单片机编程时,一定要带reg52.h(51单片机),原因是该头文件已经将MCU中的IO口全部定义好了,只要对照结构图,就可以在头文件中找到代表对应接口的变量,进而就可以对这些变量进行操作,相当于直接操作对应的IO口了。

7,sfr:特殊功能寄存器,也是一种单片机扩充的数据类型,利用它可以访问51单片机内部的所有特殊功能寄存器。例:sfr P0 = 0x80;//定义P0接口,其地址就是0x80 (sfr定义的是8位的特殊功能寄存器,sfr16,则是用来定义16位的特殊功能寄存器的)

8,sbit:对应的是可位寻址空间的一个位,单片机里的可位寻址区域:20H~2FH,一旦用了sbit XXX =地址 这样的定义,这个变量的地址就确定了。sbit大部分是用在寄存器中的,目的是为了方便对寄存器的某位进行操作。

9,高阻态:既不是高电平也不是低电平的状态。

10,锁存器:是一种有好几种模式的电路结构,某一种模式下输出端的状态不会随着输入端状态变化而变化;在另外一种模式下才会随着输入信号的变化而变化。它是通过改变LE位的值来改变它的模式,当LE位为高电平时,锁存器输出的是当前输入的值;当LE位为低电平时,锁存器输出的是之前一次保存的值。它的主要作用就是缓存,其次就是完成高速控制器与慢速外设的不同步的问题。

11:芯片引脚标志上的横线代表该引脚是低电平有效。

12:数码管的结构原理:数码管的控制分为位选和段选,段选决定的是单个数码管显示的数;位选决定的是哪些数码管会被点亮。

13:数码管的动态显示:动态显示是用的人眼的视觉暂留效应来形成的。因为八位的数码管同时只能显示一个数值。

14,定时器:就是一个计数器,每经过一个机器周期,计数器就+1,定时器是由两个计数器控制的,一个是控制寄存器TCON,一个是模式寄存器TMOD。

15,定时器的控制寄存器TCON:它有两个主要的标志位,TF:溢出标志位,当定时器计数溢出的时候,由硬件把这个位置1,该位是可以由软件置0的;TR:运行控制位,由软件置1或者清零,为1的时候才允许定时器开始计数。

16,定时器的模式寄存器TMOD:它有几个主要的标志位:GATE位:控制的是定时器的启动模式;C/T位:控制的是定时器的计数方式,1代表的是计数器,用外部的脉冲作为计数单位,0为定时器,用的是内部的机器周期作为计数单位;M0位和M1位:控制定时器(计数器)的工作模式。

17,编程使用定时器(计数器)的步骤:
设置定时器的工作模式(通过TMOD)
设置定时器的初值
启动定时器(通过TCON)
定时器开始之后,查看TCON的TF位是否溢出(置1),如果为1,并且要继续使用定时器,则需要通过软件将它清零,如果是8位自动重装模式,则不需要手动清零

18,键盘有编码键盘和非编码键盘两种,编码键盘通过硬件电路产生被按按键的键值码,这种键盘的特点是使用方便,所需程序简单,但是硬件电路复杂。如计算机的键盘就属于编码键盘;非编码键盘则是通过程序来识别按下的键,它的硬件结构相对简单,但是程序识别会困难一些,单片机上的键盘就是非编码键盘。
非编码键盘包含独立键盘和矩阵键盘两种,独立键盘是每个按键单独对应硬件上的一位;而矩阵键盘上的每个按键对应的是硬件上某几位的组合。

19,按键特性:按键的按下与释放是通过机械触点的闭合和断开来实现的,因为机械触点的弹性作用,在闭合和断开的过程中均会有一个抖动的过程,因此在进行键盘按键识别编程的时候需要用软件延时来跳过这段抖动的时间。

20,在软件判断是否按下按键的时候,需要在判断语句之后加上松手检测环节,以免循环判断。

21,根据矩阵键盘的电路结构,在编程判定到底按下的是哪个按键的时候,需要先将行线位全部赋值为0,列线全部赋值为1,再看列线的值的变化,判断按键是属于哪一列;随后将列线位全部赋值为0,行线位全部赋值为1,再看行线的值的变化,判断按键是属于哪一行。从而定位到按键的具体位置。

22,单片机每次上电的时候必须进行复位,否则容易出现程序错乱。所以单片机硬件在设计的时候就考虑到了这个问题,根据复位的电路结构就可以看出,每次上电都会给电路中的电容充电,从而自动进行复位操作,同时电路中也提供一个按钮可以手动复位。

23,51单片机中一共有5个中断源,其中两个为外部中断,均由低电平或下降沿引发,外部中断接口分别为P3.2和P3.3的复用接口,可以通过特殊功能寄存器TCON的低四位来控制。3个内部中断分别是两个定时器中断和一个串口通讯中断。

24,TCON的低四位:
IE0/IE1:外部中断触发标志位,0代表没有外部中断申请,1代表有外部中断申请。
IT0/IT1:中断触发方式的选择位,0代表低电平有效,1代表负跳变有效。

25,单片机中断的撤销:
定时器中断执行后由硬件自动撤销;
串行口中断的撤销:在中断执行后需要人工将标志位清零(T1和R1)
外部中断的撤销分为两类:
负跳变方式中断的撤销:在中断执行后由硬件自动撤销。
低电平方式中断的撤销:在中断执行结束后需要人工将中断引脚置为高电平。

26,中断允许控制寄存器IE:控制单片机中断开启和关闭的寄存器,其中的几个位的意义如下:
EA:中断总允许位,取0时禁止全部中断,取1时允许中断
ES:串行口中断允许位,取0时禁止串行口中断,取1时允许串行口中断
ET0/ET1:定时器中断允许位,取0时禁止定时器中断,取1时允许定时器中断
EX0/EX1:外部中断允许位,取0时禁止外部中断,取1时允许外部中断

27, 单片机的中断优先级控制寄存器IP(只有后五位有效,并且可以位寻址):
PX0/PX1: INT0/INT1 外部中断优先级控制位,0表示低优先级,1表示高优先级
PT0/PT1: T0/T1 定时器溢出中断优先级控制位,0表示低优先级,1表示高优先级
PS: 串行口中断优先级控制位,0表示低优先级,1表示高优先级

28,单片机同优先级中断查询顺序(由高到低):
外部中断0,T0溢出中断,外部中断1,T1溢出中断,串行口中断。

29,编程写单片机的中断响应函数的时候,需要在函数名后面加上interrupt关键字,并加上标号,标号由中断查询顺序决定,由高到低分别是0~4。
例: void INT0() interrupt 0 //外部中断0的响应函数,由于外部中断查询顺位是第一位,所以标号为0

30,并行通信和串行通信
并行通信:数据的各位同时在多根数据线上进行发送或者接收
串行通信:使用一条数据线,将数据一位一位的顺序传输

31,串行通信的种类:
异步通信:是以帧为单位进行传输的方式,帧与帧之间的时间间隔是任意的,但每个帧中位和位之间的时间间隔都是固定的。
同步通信:建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。即发送数据的每一位的到达时间都不同,但是它们到达的间隔时间都是相同的。

32,串口通信的三种制式:
单工:单向的(或者是收或者是发)
半双工:(串行通信)收/发不可同时进行
全双工:(串行通信)收/发可同时进行

33,比特率:每秒钟传输二进制代码的位数
注意:串口通信的时候,发送端和接收端的比特率要相同

34,单片机串口通信的数据缓存器SBUF:SBUF只有一个,它既表示发送寄存器,又表示接收寄存器,在CPU往SBUF上写数据时,数据就会被送入发送寄存器准备发送;在CPU读取SBUF上的数据时,则读入的数据一定来自接收寄存器。
例:a = SBUF; //用变量a接收串口通信的数据
SBUF = a; //将a的值作为传输数据发送

35,串行控制寄存器SCON:是一个既可以字节寻址又可以位寻址的8位特殊功能寄存器。单片机复位时,SCON所有位均清0。几个比较重要的位的意义如下:
SM0和SM1:为工作方式选择位,可选择四种工作方式,最常见的工作方式是SM0=0,SM1=1,此时工作方式是10位的异步收发器,每帧传送8位数据(加两位帧头尾),此模式下比特率可变
REN:串行接受允许控制位。该位由软件置位或复位。当REN=1,允许接收;当REN=0,禁止接收。
TI:发送中断标志位。TI=1,表示已结束一帧数据发送,可由软件查询TI位标志,也可以向CPU申请中断。注意:TI在任何工作方式下都必须由软件清0。
RI:接收中断标志位。RI=1,表示一帧数据接收结束。可由软件查询RI位标志,也可以向CPU申请中断。注意:RI在任何工作方式下也都必须由软件清0。

36,由于单片机串行通信只有一个中断,所以TI=1的时候或者RI=1的时候(前提是该中断被打开)都会触发该中断,因此在中断程序中必须由软件查询TI和RI的状态才能确定究竟是接收还是发送中断,进而作出相应的处理。

37,51单片机的串口通信的波特率的设置:
根据串口的电路结构,串口通信的波特率默认是由定时器1来设置的,具体设置的方法和定时器1的开启方法相同:
设置定时器的工作模式(通过TMOD,设置为8位自动重装模式)
设置定时器的初值(TH1和TL1的值要相同)
启动定时器(通过将TCON的TR1位置1)
波特率的大小和初值有关,关系如下(串口通信方式1):
波特率 =(2的SMOD次方/32)·(T1溢出率)

38,电平转换芯片的作用:
当两个不同的设备要进行通信的时候,以计算机和单片机为例,存在电平不兼容的问题,计算机的逻辑0(低电平)为3~15v,逻辑1(高电平)为-15~-3v,而单片机的逻辑0为0~0.8v,逻辑1为3~5v,因此需要电平转换芯片来使它们的高低电平做一个对应的映射,从而实现不同的设备之间的通信。

39,typedef和define的用法与区别
define是预处理指令,在编译预处理时进行简单替换,不做正确性检查,不管含义是否正确,照样带入,只有在编译已经被替换后的源程序时才会发现可能的错误并报错。
typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名,而#define只是简单地替换

40,模拟量和数字量
模拟量:自然界连续变化的物理量。所谓连续,包含两个方面的含义
一方面从时间上来说,它是随时间连续变化的;
另一方面从数值上来说,它的数值也是连续变化的。这种连续变化的物理量通常称为模拟量。
数字量:计算机中处理的是不连续变化的量,离散性的数字量

41,模拟量输入方式:差分输入与单端输入
单端输入,输入信号均以共同的地线为基准.这种输入方法主要应用于输入信号电压较高(高于1 V),信号源到模拟输入硬件的导线较短,且所有的输入信号共用一个基准地线.如果信号达不到这些标准,此时应该用差分输入.对于差分输入,每一个输入信号都有自有的基准地线;由于共模噪声可以被导线所消除,从而减小了噪声误差.
单端输入时, 是判断信号与 GND 的电压差. 差分输入时, 是判断两个信号线的电压差.
信号受干扰时, 差分的两线会同时受影响, 但电压差变化不大. (抗干扰性较佳) 而单端输入的一线变化时, GND 不变, 所以电压差变化较大. (抗干扰性较差)

42,EEPROM:
EEPROM(带电可擦写可编程读写存储器)是用户可更改的只读存储器
,其可通过高于普通电压的作用来擦除和重编程(重写)。不像EPROM芯片,EEPROM不需从计算机中取出即可修改。在一个EEPROM中,当计算机在使用的时候可频繁地反复编程,因此EEPROM的寿命是一个很重要的设计考虑参数。EEPROM是一种特殊形式的闪存,其应用通常是个人电脑中的电压来擦写和重编程。
EEPROM,一般用于即插即用(Plug & Play)。
常用在接口卡中,用来存放硬件设置数据。

2020-01-01 23:14:31 liangmaoxuan 阅读数 191
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3399 人正在学习 去看看 朱有鹏

51单片机流水灯原理

在实验之前必须的准备工作有:

1.单片机 STC90C51

2.编译软件keil

3.烧写软件

4.面包板

5.发光二极管

实验说明:通过单片机芯片,定时在引脚P00,P01,P02,P03循坏输出高电平,制作流水灯效果

重要端口:

 

原理说明:(红色部分为该实验电路图)

电流顺序:VCC正极进入 》 芯片P0.0触发一个高电平 》 LED0二极管 》 EA 》 GND负极流出

 

 

C语言编程烧写代码:

/**************************************************************************************
*		              LED闪烁实验												  *
实现现象:下载程序后指示灯闪烁
注意事项:无																				  
***************************************************************************************/

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;


sbit led0=P0^0;		 //将单片机的P0.0端口定义为led
sbit led1=P0^1;
sbit led2=P0^2;
sbit led3=P0^3;
/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{
	while(1)
	{
		led0=0;
		delay(50000); //大约延时450ms
		led0=1;
		delay(50000); //大约延时450ms
		led1=0;
		delay(50000); //大约延时450ms
		led1=1;
		delay(50000); //大约延时450ms
		led2=0;
		delay(50000); //大约延时450ms
		led2=1;
		delay(50000); //大约延时450ms
		led3=0;
		delay(50000); //大约延时450ms
		led3=1;
		delay(50000); //大约延时450ms	
	}		
}

 

 

 

总结不好多多担待,文章只单纯个人总结,如不好勿喷,技术有限,有错漏麻烦指正提出。本人QQ:373965070

 

2018-08-30 10:46:40 ShawnWang1994 阅读数 27678
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3399 人正在学习 去看看 朱有鹏

步进电机简介

步进电机是将电脉冲控制信号转变为角位移或线位移的一种常用的数字控制执行元件,又称为脉冲电机。在驱动电源的作用下,步进电机受到脉冲的控制,其转子的角位移量和速度严格地与输入脉冲的数量和脉冲频率成正比。步进电机每接收一个电脉冲,转子就转过一个相应的角度(步距角)。**改变通电顺序可改变步进电动机的旋转方向;改变通电频率可改变步进电动机的转速。**因此,通过控制输入电脉冲的数目、频率及电动机绕组的通电顺序就可以获得所需要的转角、转速及转向,利用单片机就可以很容易实现步进电机的开环数字控制。
传统的步进电机控制方法是由触发器产生控制脉冲来进行控制的,但此种控制方法工作方式单一而且难于实现人机交互,当步进电机的参数发生变化时,需要重新进行控制器的设计。因此适合于单片机控制,单片机通过向步进电机驱动电路发送控制信号就能实现对步进电机的控制。


PWM调速方法

在步进电机控制系统中可以通过输人PWM波的方法来对步进电动的运动进行控制。PWM波的产生可以通过时钟频率、自动重装值等参数进行设置,从而调节PWM波的占空比和输出频率。
脉冲宽度调制(PWM),是英文“Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制, PWM 原理如图:这里写图片描述
我们假定定时器工作在向上计数 PWM模式,且当 CNT小于CCRx 时,输出 0,当 CNT大于等于CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。,
通过控制脉冲占空比来改变电机的电枢电压.改变占空比的方法有3种:(1)定宽调频法,这种方法是保持t1不变,只改变t2,这样周期(T或频率)也随之改变;(2)调宽调频法,保持t1不变,而改变t2,这样也使周期T(或频率)改变;(3)定频调宽法,这种方法是使周期(T或频率)不变,而同时改变t1和t2.由于前两利,方法都改变了周期(或频率),当控制频率与系统的固有频率接近时,将会引起振荡,用的比较少,因此本系统用的是定频调宽法.在脉冲作用下,当电机通电时,速度增加.电机断电时,速度逐渐减小.只要按一定规律,改变通断电时间,即可实现对电机的转速控制。


系统硬件电路

系统硬件电路设计框图如下:
这里写图片描述

通过对STM32F4单片机编写程序实现对步进电机的控制,并且可以利用计算机和单片机的串口通信,接收到单片机所反馈回来的控制数据,包括:**步进电机的正向转动、反向转动、步进电机的定位功能以及调速功能。**要实现上述功能需要对STM32F4的以下模块进行设置,主要包括:串口通信模块、按键输入模块、电机驱动模块三大部分。下面就以重要模块的实现过程来进行详细的论述。

串口通信模块

串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段, 其重要性不言而喻。现在基本上所有的 MCU 都会带有串口, STM32 自然也不例外。STM32F4 的串口资源相当丰富的,功能也相当强劲。 ALIENTEK 探索者 STM32F4 开发板所使用的 STM32F407ZGT6 最多可提供 6 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、 支持调制解调器操作、 智能卡协议和 IrDA SIR ENDEC 规范、具有 DMA 等。
处理器与外部设备通信的两种方式:
并行通信:
-传输原理:数据各个位同时传输。
-优点:速度快
-缺点:占用引脚资源多

串行通信:
-传输原理:数据按位顺序传输。
-优点:占用引脚资源少
-缺点:速度相对较慢
这里我们选用串行通信。串行通信按照数据传送方向,分为:
单工
数据传输只支持数据在一个方向上传输
半双工
允许数据在两个方向上传输,但是,在某一时刻,只允许数
据在一个方向上传输,它实际上是一种切换方向的单工通信;
全双工
允许数据同时在两个方向上传输,因此,全双工通信是两个
单工通信方式的结合,它要求发送设备和接收设备都有独立
的接收和发送能力。 这里写图片描述
这里我们给出串口配置的一般步骤:
①串口时钟使能:RCC_APBxPeriphClockCmd();
GPIO时钟使能:RCC_AHB1PeriphClockCmd();
② 引脚复用映射:
GPIO_PinAFConfig();
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
NVIC_Init();
USART_ITConfig();
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
⑧串口数据收发:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
⑨串口传输状态获取:
FlagStatus USART_GetFlagStatus();
void USART_ClearITPendingBit();

相关代码如下:

void uart_init(u32 bound) //GPIO端口设置 
{ 
GPIO_InitTypeDef GPIO_InitStructure; 
USART_InitTypeDef USART_InitStructure; 
NVIC_InitTypeDef NVIC_InitStructure; 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIO时钟 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1 
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //使能GPIOA9时钟 
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //使能GPIOA10时钟 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHZ 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用功能 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10 
USART_InitStructure.USART_BaudRate = bound;//波特率设置 
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 
USART_Init(USART1, &USART_InitStructure); //初始化串口1 
USART_Cmd(USART1, ENABLE); //使能串口1 
#if EN_USART1_RX 
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级 
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 
} 
void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 	
//如果SYSTEM_SUPPORT_OS为真,则需要支持OS
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接受到的数据必须是0x0d 0x0a结尾)
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//(USART1->DR);//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收  
				}		 
			}
		}   		 
  } 
#if SYSTEM_SUPPORT_OS 	
//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

按键输入模块

STM32F4开发板上的按键 KEY0 连接在 PE4 上、 KEY1 连接在 PE3 上、 KEY2 连接在 PE2 上、 KEY_UP连接在 PA0 上。 如图所示:
这里写图片描述
在此次实验中,我们设置按下 KEY-UP, 电机以 所设定频率回到绝对原点; 按下 KEY0, 电机以所设定频率顺时针转动; 按下 KEY1, 电机以所设定频率逆时针转动。
下面给出实现按键输入的一般步骤:
①使能按键对应IO口时钟。调用函数:
RCC_AHB1PeriphClockCmd ();
②初始化IO模式:上拉/下拉输入。调用函数:
GPIO_Init();
③扫描IO口电平(库函数/寄存器/位操作)。
相关代码如下:

void KEY_Init(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIO2,3,4
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//WK_UP对应引脚  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;//下拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0
 } 
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键松开标志
	if(mode)key_up=1;  //支持连接		  
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
	{
		delay_ms(10);//去抖动
		key_up=0;
		if(KEY0==0)return 1;
		else if(KEY1==0)return 2;
		else if(KEY2==0)return 3;
		else if(WK_UP==1)return 4;
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1; 	    
 	return 0;// 无按键按下
}

电机驱动模块

电源与驱动器连接方法如下图:这里写图片描述
驱动器与STM32F4连接如下图:
这里写图片描述
代码需要用到的 4 个主要函数如下:
void Driver_Init(void);//驱动器初始化
void TIM8_OPM_RCR_Init(u16 arr, u16 psc); //TIM8_CH2 初始化 单脉冲+重复计数模式
void Locate_Rle(long num, u32 frequency, DIR_Type dir) //相对定位函数
void Locate_Abs(long num, u32 frequency);/绝对定位函数
1)驱动器初始化函数,主要就是初始化与驱动器 ENA+,DIR+相连的 2 个 IO为推挽输出。
2) TIM8_CH2 初始化, 此例程产生脉冲所使用的定时器均是 TIM8_CH2(PC7) ,定时器工作在单脉冲+重复计数模式,需要注意的是定时器必须初始化为 1MHz 计数频率。
3) 相对定位函数: 在步进电机当前位置基础上顺时针(CW)或者逆时针(CCW)走 num 个脉冲, 此函数带方向控制, DIR_Type 是 driver.h 下声明的一个枚举类型,用于设置电机旋转方向,参数 dir=CW,电机顺时针旋转; dir=CCW,电机逆时针旋转。
绝对定位函数:步进电机按设定频率转动到设置的绝对位置, 开发板上电和复位时,当前位置为 0,电机的当前位置用一个 long 型变量 current_pos 指示。 在current_pos=0 的基础上顺时针转动后 current_pos 为正, 否则为负。 5) 此例程配置了 usmart 函数和按键函数,可以通过按键或者串口调用相对定位函数和绝对定位函数控制驱动器,从而控制步进电机。
驱动模块代码如下:

u8 rcr_remainder;   //重复计数余数部分
u8 is_rcr_finish=1; //重复计数器是否设置完成
long rcr_integer;	//重复计数整数部分
long target_pos=0;  //有符号方向
long current_pos=0; //有符号方向
DIR_Type motor_dir=CW;//顺时针

驱动控制信号线初始化:

void Driver_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //DRIVER_DIR DRIVER_OE对应引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
		GPIO_SetBits(GPIOE,GPIO_Pin_5);//PE5输出高 顺时针方向  DRIVER_DIR
	GPIO_ResetBits(GPIOE,GPIO_Pin_6);//PE6输出低 使能输出 DRIVER_OE
}

单脉冲+重复计数模式:

void TIM8_OPM_RCR_Init(u16 arr,u16 psc)
{		 					 
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);  	//TIM8时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 	//使能PORTC时钟	                                                                     	
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //GPIOC7复用为定时器8
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;           //GPIOC7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;      //下拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);               //初始化PF9
	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMX时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseStructure中指定的参数化TIMX的时间基数单位
	TIM_ClearITPendingBit(TIM8,TIM_IT_Update);
	TIM_UpdateRequestConfig(TIM8,TIM_UpdateSource_Regular); /********* 设计只有计数溢出作为更新中断 ********/
	TIM_SelectOnePulseMode(TIM8,TIM_OPMode_Single);/******* 单脉冲模式**********/
 	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比较输出2N使能 *******/
	TIM_OCInitStructure.TIM_Pulse = arr>>1; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMX
	TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2预装载值 
	TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMX在ARR上的预装载值
	TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE);  //TIM8   使能或者失能指定的TIM中断
 	NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;  //TIM8中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	TIM_ClearITPendingBit(TIM8, TIM_IT_Update);  //清除TIMx的中断待处理位:TIM中断源
	TIM_Cmd(TIM8, ENABLE);  //使能TIM8											  
}

TIM8更新中断服务程序:

void TIM8_UP_TIM13_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//更新中断
	{
		TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中断标志位		
		if(is_rcr_finish==0)//重复计数器未设置完成
		{
			if(rcr_integer!=0) //整数部分脉冲还未发送
			{
				TIM8->RCR=RCR_VAL;//设置重复计数值
				rcr_integer--;//减少RCR_VAL+1个脉冲			
			}else if(rcr_remainder!=0)//余数部分脉冲 不为0
			{
				TIM8->RCR=rcr_remainder-1;//设置余数部分
				rcr_remainder=0;//清零
				is_rcr_finish=1;//重复计数器设置完成				
			}else goto out;   //rcr_remainder=0直接退出			 
			TIM_GenerateEvent(TIM8,TIM_EventSource_Update);//产生一个更新事件 重新初始化计数器
			TIM_CtrlPWMOutputs(TIM8,ENABLE);	//MOE主输出使能	
			TIM_Cmd(TIM8, ENABLE);  //使能TIM8			
			if(motor_dir==CW) //如果方向为顺时针 
				current_pos+=(TIM8->RCR+1);//加上重复计数值
			else          //否则方向为逆时针
				current_pos-=(TIM8->RCR+1);//减去重复计数		
		}else
		{
out:		is_rcr_finish=1;//重复计数器设置完成
			TIM_CtrlPWMOutputs(TIM8,DISABLE);	//MOE 主输出关闭
			TIM_Cmd(TIM8, DISABLE);  //关闭TIM8				
			printf("µ±Ç°Î»ÖÃ=%ld\r\n",current_pos);//打印输出
		}	
	}
}

启动TIM8:

void TIM8_Startup(u32 frequency)   //启动定时器8
{
	u16 temp_arr=1000000/frequency-1; 
	TIM_SetAutoreload(TIM8,temp_arr);//设定自动重装值	
	TIM_SetCompare2(TIM8,temp_arr>>1); //匹配值2等于重装值一半,是以占空比为50%
	TIM_SetCounter(TIM8,0);//计数器清零
	TIM_Cmd(TIM8, ENABLE);  //使能TIM8
}

相对定位函数:

void Locate_Rle(long num,u32 frequency,DIR_Type dir) //相对定位函数
{
	if(num<=0) //数值小于等于0 则直接返回
	{
		printf("\r\nThe num should be greater than zero!!\r\n");
		return;
	}
	if(TIM8->CR1&0x01)//上一次脉冲还未发送完成 直接返回
	{
		printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
		return;
	}
	if((frequency<20)||(frequency>100000))//脉冲频率不在范围之内 直接返回
	{
		printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
		return;
	}
	motor_dir=dir;//得到方向	
	DRIVER_DIR=motor_dir;//设置方向
		if(motor_dir==CW)//顺时针
		target_pos=current_pos+num;//目标位置
	else if(motor_dir==CCW)//逆时针
		target_pos=current_pos-num;//目标位置
	rcr_integer=num/(RCR_VAL+1);//重复计数整数部分
	rcr_remainder=num%(RCR_VAL+1);//重复计数余数部分
	is_rcr_finish=0;//重复计数器未设置完成
	TIM8_Startup(frequency);//开启TIM8
}

绝对定位函数:

void Locate_Abs(long num,u32 frequency)//绝对定位函数
{
	if(TIM8->CR1&0x01)//上一次脉冲还未发送完成 直接返回
	{
		printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
		return;
	}
	if((frequency<20)||(frequency>100000))//脉冲频率不在范围内 直接返回
	{
		printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");
		return;
	}
	target_pos=num;//设置目标位置
	if(target_pos!=current_pos)//目标和当前位置不同
	{
		if(target_pos>current_pos)
			motor_dir=CW;//顺时针
		else
			motor_dir=CCW;//逆时针
		DRIVER_DIR=motor_dir;//设置方向
		
		rcr_integer=abs(target_pos-current_pos)/(RCR_VAL+1);//重复计数整数部分
		rcr_remainder=abs(target_pos-current_pos)%(RCR_VAL+1);//重复计数余数部分
		is_rcr_finish=0;//重复计数器未设置完成
		TIM8_Startup(frequency);//开启TIM8
	}
}

最后是主函数:

int main(void)
{ 
	u8 i;
	u8 keyval;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率115200
	usmart_dev.init(84); 	//初始化USMART			
	LED_Init();					  //初始化LED
 	KEY_Init();					//初始化按键
	Driver_Init();			//驱动器初始化
	TIM8_OPM_RCR_Init(999,168-1); //1MHz计数频率 单脉冲+重复计数模式
	while(1) 
	{		 	  
		keyval=KEY_Scan(0);
		if(keyval==WKUP_PRES)
		{
			Locate_Abs(0,500);//按下WKUP,回到零点
		}else if(keyval==KEY0_PRES)
		{
			Locate_Rle(1200,500,CW);//按下KEY0,以500Hz的频率 顺时针发200脉冲
		}else if(keyval==KEY1_PRES)
		{
			Locate_Rle(1200,500,CCW);//按下KEY1,以500Hz频率 逆时针发400脉冲
		}			
		delay_ms(10);
		i++;
		if(i==50)	
		{	
			i=0;
			LED1=!LED1;
		}			
	}
}

可以根据实际要求修改参数值以达到相应目的控制步进电机转动的转速和步距角。


实验验证

设置驱动器细分和电流, 完成硬件接线, 然后给开发板上电(USB232 接口), 打开 XCOM 调试助手,找到对应COM,设置波特率 115200,1 位停止位,8位数据位,无校验,勾上发送新行,然后打开串口,最后给驱动器上电。按下 KEY-UP, 电机以 500Hz 频率回到绝对原点; 按下 KEY0, 电机以 500Hz 频率顺时针走 200 个脉冲; 按下KEY1,电机以 500Hz 频率逆时针走 400 个脉冲;依次按下KEY_UP, KEY0, KEY1,串口打印的情况如下。
这里写图片描述
点击发送条目后边的数字就可调用该函数, 这儿的相对的定位函数 Locate_Rle 最后
一个参数用于设置电机旋转方向的, 0(CCW) 表示逆时针方向, 1(CW) 表示顺时针方向,实验时, 如果电机旋转方向和设置方向相反, 只需更改 driver.h 下的CW=0,CCW=1;每调用一次函数,串口打印当前的位置。 然后我们依次调用这 4 个函数, 根据串口的打印, 可以看到当前位置的变化情况,如图所示。
这里写图片描述


结语

本文介绍了利用单片机控制基于STM32F4芯片的步进电机定位控制系统的整体设计思路以及用pwm实现对步进电机控制的脉冲时序的分配进行了详细的仿真。利用STM32F4芯片严谨的基于硬件的编程语言和精确的时间控制特点,准确地实现了精确定位功能,对步进电机的运行速度的精确控制。实践证明,这种方法定位准确,控制速度精确,是一种行之有效的方案。


1.此次实验所选用的的驱动器为TB6600步进电机专用驱动器。
TB6600步进电机驱动器是一款专业的两相步进电机驱动,可实现正反转控制。通 过S1 S2 S3 3位拨码开关选择8 档细分控制(1、2、4、8、16 ),通过S4 S5 S6 3位拨码开关选择6档电流控制(0.5A,1A,1.5A,2.0A,2.5A,3.0A, 3.5A, 4.0A)。适合驱动86,57,42,39 型两相、四相混合式步进电机。驱动器具有 噪音小,震动小,运行平稳的特点。
这里写图片描述
TB6600步进电机专用驱动器电气参数如下表:
这里写图片描述
2.此次实验所选用的步进电机为57步进电机。其相关参数及尺寸如下。
这里写图片描述

2008-01-17 15:49:00 mybirdsky 阅读数 605
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3399 人正在学习 去看看 朱有鹏
2006-04-28 10:49:13

字体变小 字体变大

单片机控制的数字触发器


摘要 介绍了8051单片机在晶阐管触发电路中的应用,同时有单片机与上位机进行串口通讯的软件设计。由软件控制可产生不同顺序的6组触发脉冲。

关键词 单片机 VB 晶阐管 数字触发器

电力电子技术研究的内容包括三个方面:电力电子器件、变流电路和控制电路。电力电子变流技术在工业化领域有着广泛的应用。家用电器节能灯、电子拖动、电炉控制系统中已采用相控整流技术。但多数触发装置普遍是模拟的,调节十分的不便,触发精度差、故障率高。采用单片机来控制晶阐管的触发,是晶阐管应用的发展趋势。本文介绍了一种由8051单片机组成的触发控制系统,可实现高分辨率的数字触发器。

1 系统硬件组成及其原理

系统硬件组成如图1,被控对象是三相全控桥整流电路。控制电路由8051单片机及其外围电路组成。外围电路主要是由键盘电路、同步脉冲形成电路、驱动输出电路等组成。

1.1 控制角θ

控制角θ是滞后自然换相点的电度角,在工频条件下,它和时间Tθ有如下关系:
Tθ=T/360*θ=(20*θ)/360=0.056ms
其中T是工频电源周期,θ是控制角。

由上式可知,只要知道控制角就可以算出定时时间Tθ,采用定时计数器来完成对控制角的定时。
8051单片机有两个定时计数器,可由程序选择作为定时器用或作为计数器用,定时时间或计数值也可由程序设定。随便选择定时或计数方式,其实质都是一样的。

如果选择的是方式1的话,定时时间可由下式计算

Td=(65536-x)*Tcy

其中Tcy=1μS 因为采用的是12MHz的晶振,x是计数值。

分辨率为:φ=360/T*Tcy=0.018(度)

方式1是16位的定时器,其最大的定时角度为:

θmax=0.018*65536=1179.648(度)

从上面可知,不论是分辨率还是移相范围都能达到令人满意的结果。

1.2同步脉冲形成电路

由于触发脉冲的自然换相点要与三相电源的线电压的过零点同步,所以要由同步脉冲形成电路产生同步脉冲。

电路如图2所示,交流电经过降压后,由LM339过零比较器进等过零检测,然后经过光电隔离各微分电路输出脉冲信号,加到单片机外部中断引脚去作为同步信号。

 

同步脉冲形成电路主要由过零比较器、同步变压器及整形电路组成。三相交流电源经过变压器降压后从副边输出,然后送到过零比较器电路,在每一个电源周期的过零点将输出两个同步脉冲,一个周期内,三相电源将输出6个同步脉冲,这6个同步脉冲在相位上相差60度,在时间上就会相差3.333ms,它们就每隔3.33ms加到单片机的外部中断引脚INT0上。由于在三相桥式全控桥电路中,它的自 然换相点是线电压的过零,所以加在过零比较器电路的是线电压。

1.3 触发脉冲形成电路

根据三相桥式整流电路对触发脉冲的要求,必须对应导通的一对晶阐管同时加触发脉冲。常用的方法有两种:一种采用宽脉冲触发,它要求触发脉冲的宽度大于60度;另一种采用双脉冲触发,即触发一个晶阐管时向小一个序号的晶阐管发补脉冲。关系如下:

触发的晶阐管 V1 V2 V3 V4 V5 V6

补发的晶阐管 V6 V1 V2 V3 V4 V5

在本文中将采用双脉冲触发方式,因为60度的脉宽在单片机中所对应的定时是比较长的,所以此方法不佳。采用双脉冲触发是,就要在软件设计时用标志旗的方法来标注,特别是V1,因为它并不是V0,它是V6,其余的都是VnVn-1

1.4 驱动电路

驱动电路主要由光电隔离和脉冲变压器组成。

 

2软件设计

2.1单片机部分

软件设计的流程图如下:采用双脉冲触发是,就要在软件设计时用标志旗的方法来标注,特别是V1,因为它并不是V0,它是V6,其余的都是VnVn-1

流程图如下:

 

设控制角为α,为使可靠触发,触发脉冲脉宽为15度,那么每一个周期的第一个脉冲上升沿所对应的时间Tup=α*T/360,其下降沿时间Tlow=(α+15)*T/360。这样只要定时器定相对的时间,就可以得到准确的触发脉冲。在编程时可以用计数的方式,把定时方式改为计数,Cup 、Clow.

程序片段:

***********输出触发脉冲程序*************

ORG 0003H

AJMP P_INT0

ORG 0030H

P_INT0:

MOV TMOD,#11H

MOV TH0,#CUP_H ;上升沿计数值高位

MOV TL0,#CUP_L ;上升沿计数值低位

MOV TH1,#CLOW_H ;下降沿计数值高位

MOV TL1,#CLOW_L ;下降沿计数值低位

MOV IE, #8FH

SETB TRO

SETB TR1

SJMP $

;********定时器0中断******************

ORG 00BH

T0_SERVE:

SETB P1.6

RETI

;********定时器1中断******************

ORG 001BH

T1_SERVE:

CLR P1.6

RETI

2.2 上位机部分

VB打开一个窗口,上面建立一文本框,端口选择框,以及打开一个MSComm控件。用于上位机给下位机发触发角。

 

3外围电路

组合电路是从P1.6输出的同步脉冲与应该触发的晶阐管(P1.0~P1.5)脉冲相与,输出到驱动电路,这样就可以得到期满意的触发脉冲。

键盘显示电路是在无上位机的情况下,由自制键盘输入,并在LED上显示控制角。

采用单片机控制触发电路是未来晶阐管触发电路的趋势。但在环境恶烈的地方安全性不高。不过应用在实验室却是一种非常好的手段。

2016-01-25 11:37:09 baidu_33836580 阅读数 399
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3399 人正在学习 去看看 朱有鹏

求代码,作用是单片机控制继电器用于自动操作键盘。

要求:

P01 导通三分钟,然后断开;
P02 导通 10 秒后断开;
P03 导通 0.5 秒后断开;
P04 导通 0.2 秒后断开;
P05 导通 0.5 秒后断开;
P06 导通 0.2 秒后断开。

断开 P06 之后,循环所有。 单片机 89C52RC。

悬赏分:100 - 解决时间:2009-11-15 10:01
;-----------------------------------------------------------
最佳答案:

试试如下程序。
//--------------------------------------------------
#include
#define uchar unsigned char
#define uint unsigned int

sbit P0_1 = P0^1;
sbit P0_2 = P0^2;
sbit P0_3 = P0^3;
sbit P0_4 = P0^4;
sbit P0_5 = P0^5;
sbit P0_6 = P0^6;
//--------------------------------------------------
void delay1ms(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--) for(y = 110; y > 0; y--);
}
//--------------------------------------------------
void main(void)
{
    uint i, j;
    while(1) {
//--------------
      P0_1 = 0;
      for (i = 0; i < 3; i++)
        for (j = 0; j < 120; j++) delay1ms(500); //共延时360*0.5=180秒
      P0_1 = 1;
//--------------
      P0_2 = 0;
      for (j = 0; j < 20; j++)  delay1ms(500);   //共延时20*0.5=10秒
      P0_2 = 1;
//--------------
      P0_3 = 0; delay1ms(500);       //延时0.5秒
      P0_3 = 1;
//--------------
      P0_4 = 0; delay1ms(200);       //延时0.2秒
      P0_4 = 1;
//--------------
      P0_5 = 0; delay1ms(500);       //延时0.5秒
      P0_5 = 1;
//--------------
      P0_6 = 0; delay1ms(200);       //延时0.2秒
      P0_6 = 1;
    }
}
;-----------------------------------------------------------
回答者:  做而论道 - 十级   2009-11-14 23:25
提问者对于答案的评价:非常感谢,测试通过...
二楼写的也很不错,但是一段那么简单的程序搞那么多代码,对于我们菜鸟来说看不懂...
原文网址:http://zhidao.baidu.com/question/125558527.html
;===========================================================

没有更多推荐了,返回首页