❶ 51单片机如何用六脚自锁开关当作电源开关
开关本身是不分正负极的,只是控制个通断,你用万用表现测量下,区分出哪个脚是公共脚(一般中间的是公共脚),然后量下按下通是哪个脚,就用这俩脚就行了,希望对你有帮助
❷ 单片机可以做什么事
单片机,又称微处理器,他将一个系统所需要的RAM,Rom ,CPU等相关外设集成在一块集成电路上,我们通过汇编语言或者C语言写成我们需要的程序下载到单片机中运行,其实无论哪种单片机无非都是在控制自己的相关IO高低变化从而达到控制外设的目的。
在学习单片机的过程中,大部分人也是从点亮一个LED 灯泡开始的,完后时流水灯,控制继电器,在然后就是各种协议,IIC,,spi,usart等。
S7200-plc
例如有这么一个控制系统,要求光电检测物体,当光电检测到物体到来时,接近传感器随机检测物体是否为金属,当为金属时系统不做处理,当不为金属时系统输出报警型号,控制报警器工作3S后关闭报警器,提示人工挑拣。
方法如下:
1、利用几点器加延时继电器进行设计,完全可以达到要求,成本也不是很高。
2、采用PLC,更加简单,一个梯形图外加几个继电器就搞定,但是成本高了,而且对于PLC的IO口来说一种浪费。
3、采用单片机:我们将光电采集的信号进入单片机的外部中断,在中断程序中判断接近传感器的电平变化,没有信号就不是金属物体,我们输出一个电平信号用定时器延时3秒就可以,而且成本低廉。
接下来我们对此系统进行扩展,加入一个1602液晶显示屏成本10元以内,在液晶上我们对经过光电的物体进行技术,显示出非金属物体有过少个,我们还可以加入按键来随时调节报警输出时间。成本基本无变化。如果我们用PLC的话,就需要加HDMI,组态。
(2)51单片机可以汇编自锁吗扩展阅读:
单片机分类标准①:通用性
按通用性可分为:通用型/专用型
这是按单片机适用范围来区分的。例如,80C51是通用型单片机,它不是为某种专用途设计的;专用型单片机是针对一类产品甚至某一个产品设计生产的,例如为了满足电子体温计的要求,在片内集成ADC接口等功能的温度测量控制电路。
单片机分类标准②:总线结构
按总线结构可分为:总线型/非总线型
这是按单片机是否提供并行总线来区分的。总线型单片机普遍设置有并行地址总线、 数据总线、控制总线,这些引脚用以扩展并行外围器件都可通过串行口与单片机连接。
另外,许多单片机已把所需要的外围器件及外设接口集成一片内,因此在许多情况下可以不要并行扩展总线,大大减省封装成本和芯片体积,这类单片机称为非总线型单片机。
单片机分类标准③:应用领域
按应用领域可分为:家电类,工控类,通信类,个人信息终端类等等
一般而言,工控型寻址范围大,运算能力强;用于家电的单片机多为专用型,通常是小封装、低价格,外围器件和外设接口集成度高。
单片机分类标准④:数据总线位数
按单片机数据总线位数可分为:4位、8位、16位和32位单片机
4位单片机结构简单,价格便宜,非常适合用于控制单一的小型电子类产品,如PC机用的输入装置(鼠标、游戏杆)、电池充电器、遥控器、电子玩具、小家电等。 2. 8位单片机。
8位单片机是目前品种最为丰富、应用最为广泛的单片机,目前,8位单片机主要分为51系列及和非51系列单片机。51系列单片机以其典型的结构,众多的逻辑位操作功能,以及丰富的指令系统,堪称一代“名机”。
16位单片机 16位单片机操作速度及数据吞吐能力在性能上比8位机有较大提高。目前,应用较多的有TI的MSP430系列、凌阳SPCE061A系列、Motorola的68HC16系列、Intel的MCS-96/196系列等。
32位单片机 与51单片机相比,32位单片机运行速度和功能大幅提高,随着技术的发展以及价格的下降,将会与8位单片机并驾齐驱。32位单片机主要由ARM公司研制,因此,提及32位单片机,一般均指ARM单片机。
严格来说,ARM不是单片机,而是一种32位处理器内核,实际中使用的ARM芯片有很多型号,常见的ARM芯片主要有飞利浦的LPC2000系列、三星的S3C/S3F/S3P系列等。
❸ 关于自学51单片机需要买什么
1.建议买个带MAX232和DB9接口的最小系统板,要扩充硬件时就用杜邦线连接。这样成察高本低,袜笑结构简单可靠。
2.USB转串口的线是必须的,毕竟现在没几台电脑是有原生串口的,这个转接线在串口通信实现和程序下载时非败好尺常有用。
3.买一本51单片机教材。
4.现在比较合适的就是STC单片机了。AT89S52也不错,但这需要USBASP下载线。
5.所有的51单片机都能用汇编和C编程,实际上编译器也只是把C转变为了汇编。
❹ 单片机自锁程序
你的意思是K1按下,D1输出低电平,再按一次K1,D1输出高电平?
这……这里的按键检测就不需要使用延时了,使用while不用怕会阻塞后面的程序执行。事实在公司写程序,在检测按键时我从来不用延时,当然也不是使用这种while等待按键松开的方式。有兴趣可以一起研究一下,呵呵
#include<reg51.h>
#defineKEY1 (1<<0)
#defineKEY2 (1<<1)
#defineKEY3 (1<<2)
#defineKEY4 (1<<3)
#defineKEY5 (1<<4)
#defineKEY6 (1<<5)
sbitD1=P0^0;
sbitD2=P0^1;
sbitD3=P0^2;
sbitD4=P0^3;
sbitD5=P0^4;
sbitD6=P0^5;
voidmain(void)
{
while(1)
{
P1=0xff;
if(!(P1&KEY1))
{
D1=~D1;
while(!(P1&KEY1));
}
if(!(P1&KEY2))
{
D2=~D2;
while(!(P1&KEY2));
}
if(!(P1&KEY3))
{
D3=~D3;
while(!(P1&KEY3));
}
if(!(P1&KEY4))
{
D4=~D4;
while(!(P1&KEY4));
}
if(!(P1&KEY5))
{
D5=~D5;
while(!(P1&KEY5));
}
if(!(P1&KEY6))
{
D6=~D6;
while(!(P1&KEY6));
}
}
}
❺ 51单片机输出循环
试试下列程序:
#include <reg51.h>
sbit t = P1^0;//LED灯输出
sbit k = P3^5;//轻触开关
#define uint unsigned int
#define uchar unsigned char
//延时函数
void delay(uchar z)
{
uint x, y;
for(x = z; x > 0; x--) for(y = 110; y > 0; y--);
}
//按键检测函数
bit key()
{
bit kkk;
kkk = k; //读入按键.
if(kkk == 1) return 0;//没有按下.
delay(5); //延时.
if(k == kkk) return 1;//两次相等.
return 0;
}
//主函数
void main()
{
P1 = 0xff;
while(1) {
while(!key()); //静等按键.
t = ~t;
delay(200); //等一会再去检测,以免闪动太快.
}
}
❻ 51单片机按键控制数码管
#include <reg52.h> // 可以参考一下
#define uchar unsigned char
#include <stdio.h>
unsigned char* c;
sbit k0=P3^2;
sbit k1=P3^3;
sbit k2=P3^4;
sbit k3=P3^5;
sbit k4=P3^7;
sbit led1=P1^7;
uchar k;
bit y0,y1,y2,y3,y4,y5;
bit t,s,ld;
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d};
void SendOneChar(char c) //发送字节到PC
{
TI=0;
SBUF = c;
while(!TI);
TI=0;
}
void SendString(char *st) //发送字符串到PC
{
while(*st)
{
SendOneChar(*st++);
}
}
void main()
{
SCON = 0x50; //SCON: mode 1, 8-bit UART, enable rcvr
TMOD = 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON = 0x80; // 数据位8、停止位1。效验位无 (11.0592M)
TH1 = 0xF4; //TH1: reload value for [email protected]
TR1 = 1; //启动定时器1
ES = 1; //允许串口中断位
EA = 1; //允许总中断位
c=0;
s=1;
k=0;
P1 =~table[k];
while(1)
{
if(k0==0 && y0==0)
{
y0=1;
c = "as";
SendString(c); //发送字符串
}
if(k0==1 ) { y0=0; }
if(k1==0 && y1==0)
{
y1=1;
c = "bs";
SendString(c); //发送字符串
}
if(k1==1 ) { y1=0; }
if(k2==0 && y2==0)
{
y2=1;
c = "ds";
SendString(c); //发送字符串
}
if(k2==1 ) { y2=0; }
if(k3==0 && y3==0)
{
y3=1;
c = "es";
SendString(c); //发送字符串
}
if(k3==1 ) { y3=0; }
if(k4==0 && y4==0)
{
y4=1;
c = "fs";
SendString(c); //发送字符串
}
if(k4==1 ) { y4=0; }
// for(i = 0; i < 4000; i++); //延迟一小段时间
}
}
void chuankou(void) interrupt 4
{
if(RI==1)
{
RI = 0;
if(t==1)
{
if(SBUF=='z') { k++;ld=~ld; }
s=1; t=0;
if(k==10) { k=0;}
P1 =~table[k];
led1=ld;
}
if(SBUF=='a' && s==1) { t=1;s=0;}
}
}
/////////////////////////////////////////
#include <reg51.h> // 接收 试试
#define uchar unsigned char
unsigned char* c;
sbit led1=P3^2; // 接收 az , P.2 输出低电平, P3.3 输出高电平。
sbit led2=P3^3; // 接收 aa , P.2 输出高电平, P3.3 输出低电平。
sbit k0=P3^5;
bit y0,t,s;
uchar k;
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d};
void SendOneChar(char c) //发送字节到PC
{
TI=0;
SBUF = c;
while(!TI);
TI=0;
}
void SendString(char *st) //发送字符串到PC
{
while(*st)
{
SendOneChar(*st++);
}
}
void main (void)
{
SCON = 0x50; // REN=1允许串行接受状态,串口工作模式1
TMOD = 0x21; // 定时器工作方式2
PCON = 0x80; // 数据位8、停止位1。效验位无 (11.0592M)
TH1 = 0xF4; // TH1 = 0xFD; 波特率 2400
TH0=(65536-54253)/256; // 50 mS
TL0=(65536-54253)%256;
TR1 = 1;
ES = 1; // 开串口中断
EA = 1; // 开总中断
led1=1;led2=0;
// ET0=1;
// TR0=1;
s=1;
k=0;
P1 =~table[k];
while(1)
{
if(k0==0 && y0==0)
{
y0=1;
c = "az";
SendString(c); //发送字符串
}
if(k0==1 ) { y0=0; }
}
}
void chuankou(void) interrupt 4
{
if(RI==1)
{
RI = 0;
if(t==1)
{
if(SBUF=='s') {led1=~led1;led2=~led2; k++; }
//if(SBUF=='s') {led1=1;led2=0; k--; }
s=1; t=0;
if(k==10) { k=0;}
if(k==255) { k=9; }
P1 =~table[k];
}
// 1号 a 2号 b ---
if(SBUF=='a' && s==1) { t=1;s=0;}
}
}
void T0_time()interrupt 1
{
TH0=(65536-54253)/256; // 50 mS
TL0=(65536-54253)%256;
k++;
if(k==10) // 这里修改时间
{
k=0;
led1=1;
led2=1;
}
}
❼ 315M无线收发模块如何实际应用在51单片机上
你要是简单的控制其实315M的配上编解码芯片直接就能工作,比如PT2262(发)、PT2272(收)。。。毕竟2你只是简单的控制个电机正反,2262最高能如入6路,2272也输出6路,不过一般普通的是4路,另外分自锁输出和点动输出
如果单片机的话直接接还真没接过。。不过我感觉用51的串口通信应该就可以,一个用个AT89C2051这类的20脚小芯片,把P3.1:TXD 串口输出接在31M发射模块上,然后剩下的除了晶振和电源,复位引脚外都可以用于做按键检测用。他有15个IO,P1是个标准8位口,P3比正常的少个P3.6,然后你在用于串口1个IO,剩下14个IO,按键应该足够用了。然后在自己给编个码,比如P1.0按下正转输出0x01,P1.1反转输出0x02.。。不过用单片机的话你遥控器只能是加个总电源开关,反正节能方面差点。。
然后是接收部分,同样用串口接收,P3.0:RXD 串口输入接在接收模块的输出DATA上。根据接收到的编码来判断哪个IO输出。比如接收到0x01,认为是电机正转,接收到0x02认为电机反转。。。。
❽ 51单片机如何用一个按键和一个定时器来模拟PWM控制一个LED灯的亮度
使用定时器T0产生PWM方波,
用按键调整占空比,20级可调
控制led灯的亮度等级.
#include "my51.h"
#include "timer0.h"
#define grading 20 //亮度20级变化
sbit keyS3=P3^5; //按键调整占空比,PWM_keyChange++
sbit keyS4=P3^6; // PWM_keyChange--
u8 PWM_keyChange=10; //初值,按键调整在1~20之间变化
//占空比 PWM_keyChange/grading
void T0_work() //本函数由T0定时器中断函数调用
{
if(timeMultiple1Flag)
{
led=off(7); //关闭7号灯
timeMultiple1Flag=0; //清定时器复用置位标志
}
if(timeMultiple2Flag)
{
led=on(7); //打开7号灯
timeMultiple2Flag=0; //清定时器复用置位标志
}
}
void main() //测试
{
u8 keyFlag=1; //程序中没有消抖处理,只是简易的按键进出自锁标志
led0=ledon; //先打开0号灯,用于和7号灯对比亮度
initT0(1,10,grading); //1毫秒的基本定时,亮的时间1*10毫秒,暗1*(grading-10)毫秒
while(1)
{
if(0==keyS3)
{
if(keyFlag) //防止一次按键中多次执行
{
keyFlag=0; //清标志,类似同步锁
if(++PWM_keyChange>grading)
{
PWM_keyChange=grading; //占空比最大100%
}
initT0(1,PWM_keyChange,grading);
}
}
else if(0==keyS4)
{
if(keyFlag)
{
keyFlag=0;
if(0==--PWM_keyChange) //占空比减小
{
PWM_keyChange=1; //最小占空比 1/20
}
initT0(1,PWM_keyChange,grading); //占空比减小
}
}
else
{
keyFlag=1; //按键锁释放标志,下一次按键时允许调整占空比
}
}
}
C代码
#ifndef _MY51_H
#define _MY51_H
#include <reg52.h>
//#include <math.h>
#include <intrins.h>
#include <stdio.h>
#include "mytype.h"
#ifndef _51LED_
#define _51LED_
#define led P1 //P1总线连8个led灯,灯连573锁存器,P1置低电平点亮
#define LED led
#define ON(x) P1&(~(1<<(x))) //打开某个灯,开多个灯用 ON(m) & ON(n)
#define OFF(x) P1|(1<<(x)) //关闭某个灯,关多个灯用 OFF(m)| OFF(n)
#define on(x) ON(x) //包含大小写
#define off(x) OFF(x)
#define ledon 0 //某个灯,打开
#define ledoff 1 //某个灯,关闭
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
sbit ledLock=P2^5; //锁定当前8个led的状态,0锁定 ,1不锁定
#endif
/*************二进制输入宏****************************/
#ifndef _LongToBin_
#define LongToBin(n) \
( \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)
#define bin(n) LongToBin(0x##n##l)
#define BIN(n) bin(n)
#define B(n) bin(n)
#define b(n) bin(n)
#endif
/*************单个数据位的置位宏*********************/
#ifndef _BIT_
#define BIT(n) (1<<n)
#define bit(n) BIT(n)
#endif
#define high 1 //高电平
#define low 0 //低电平
sbit beep=P2^3; //蜂鸣器
extern void delayms(u16 ms);
extern void delayXus(u8 us); //函数执行(8+6x)个机器周期, 即t=(8+6x)*1.085
/////////////////////////////////////////////////////////////////////////////
#endif
C代码
#ifndef _TIMER0_H
#define _TIMER0_H
#include "my51.h"
extern u8 timeMultiple1Flag; //中断时间复用置位标志,须手动清零
extern u8 timeMultiple2Flag; //中断时间复用置位标志,须手动清零
extern void T0_work(); //该函数未实现,需外部实现
extern void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2) ; //定时器初始化
#endif
C代码
#include "timer0.h"
u8 TH0Cout=0 ; //初值
u8 TL0Cout=0 ;
u16 T0IntCouts1=0; //中断计数
u16 T0IntCouts2=0; //中断计数
u16 timeMultiple1=0; //中断复用时间的倍数
u16 timeMultiple2=0; //中断复用时间的倍数
u8 timeMultiple1Flag=0; //中断时间复用置位标志,须手动清零
u8 timeMultiple2Flag=0; //中断时间复用置位标志,须手动清零
//开启定时器,定时完成后需要手动关闭TR0,否则将循环定时
//参数一是定时的毫秒数,参数二和三是定时基时的倍率数(定时复用)
void initT0(u8 ms,u16 t_multiple1,u16 t_multiple2) //定时器初始化设定,ms取值不超过65
{
u16 N=11059.2*ms/12; //定时器总计数值
TR0=STOP; //停掉定时器
ET0=CLOSE; //关定时器中断
//对于110592晶振,ms为5的整数倍时没有计算误差,但ms最大不超过71毫秒
TH0Cout =(65536-N)/256; //装入计时值零头计数初值
TL0Cout =(65536-N)%256;
if(0==t_multiple1) //0倍的基准时间是不合理的,至少1倍
{
t_multiple1=1;
}
if(0==t_multiple2) //0倍的基准时间是不合理的,至少1倍
{
t_multiple2=1;
}
timeMultiple1=t_multiple1; //倍时
timeMultiple2=t_multiple2; //倍时
TMOD &= 0xf0; //清定时器0配置
TMOD |= 0x01; //配置定时器0的工作方式为1
EA =OPEN; //打开总中断
ET0=OPEN; //打开定时器中断
TH0=TH0Cout; //定时器装入初值
TL0=TL0Cout;
TR0=START; //启动定时器
}
void T0_times() interrupt 1 //T0定时器中断函数
{
TH0=TH0Cout; //重装初值
TL0=TL0Cout;
if(++T0IntCouts1==timeMultiple1) //判断是否复用定时器
{
T0IntCouts1=0; //中断次数清零,重新计时
timeMultiple1Flag=1; //复用定时器标志,须在T0_work()中手动清零
}
if(++T0IntCouts2==timeMultiple2) //判断是否复用定时器
{
T0IntCouts1=0; //这个也要清,防止到达最小公倍数时乱掉
T0IntCouts2=0; //中断次数清零,重新计时
timeMultiple2Flag=1; //复用定时器标志,须在T0_work()中手动清零
}
T0_work(); //调用工作函数
}