⑴ 如何用单片机控制机床往复运动
用中断。。。等下我写完发上来
定时器T2本身定时50ms,整个程序定时X*Y*50ms
TIME1 EQU X;定义第一级计数次数X
TIME2 EQU Y;定义第二级计数次数Y
TC1 DATA 28H;定义计数的单元
TC2 DATA 29H;定义计数的单元
ORG 0000H
LJMP MAIN
ORG 002BH
LJMP CTC2
ORG 100H;主程序
MAIN:
MOV SP,#5FH;初始化堆栈指针
MOV TC1,#TIME1;装初值
MOV TC2,#TIME2;装初值
MOV TH2,#4CH;T2装初值
MOV TL2,#0;T2装初值
MOV RCAP2H,#4CH;T2重装初值
MOV RCAP2L,#0;T2重装初值
MOV T2CON,#00000100B;初始化T2
SETB ET2
SETB EA
SJMP $
CTC2:
PUSH PSW
DJNZ TC1,EXIT;软件计数减1
MOV TC1,#TIME1;重装初值
DJNZ TC2,NEXT;软件计数第二级减1
MOV TC2,#TIME2;重装初值
**********
***********
NEXT:
INC TC1;当Tc1=1时,djnz不跳转
EXIT:
POP PSW
CLR TF2;清T2中断标志
RETI
上面星号部分是往返的,需要怎样往返就怎样写了,一到时间,它会自动循环
⑵ 单片机 按键秒表
秒表的设计程序
用89C51,外接晶振,复位电路,二个数码管,二个按键,做一个电子秒表,具体要求为用按键起停电子表,可用按键设计倒计时时间(如10S,20S,60S),并启动倒计时功能。能用按键选择以上两功能之一。
三、程序代码:
A_BIT EQU 20H ;数码管个位数存放内存位置
B_BIT EQU 21H ;数码管十位数存放内存位置
TEMP EQU 22H ;计数器数值存放内存位置 ;开机初始化
MOV P3,#0FFH;对P3口初始化,设置为高电平,用于按键输入
MOV P0,#0FFH;使显示时间数码管熄灭
CLR F0
CLR F1
MOV DPTR,#NUMTAB ;指定查表启始地址
;等待按键输入
;根据按键的输入判断执行什么功能;按键1按下则执行功能1
MOV P3,#0FFH;对P3口初始化,设置为高电平,用于按键输入
MOV P0,#0FFH;使显示时间数码管熄灭
START:JB P3.6,START1;循环判断开始按钮K1是否按下?
ACALL DELAY10;延时10毫秒触点消抖
JB P3.6,START;如果是干扰就返回
JNB P3.6,$;等待按键松开
LJMP GN1 ;按键2按下则执行功能2START1: JB P3.7,START;循环判断开始按钮K2是否按下?
ACALL DELAY10;延时10毫秒触点消抖
JB P3.7,START1;如果是干扰就返回
JNB P3.7,$
LJMP GN2;数码管显示秒表时间的程序
GN1: ;先初始化
S1:MOV A,#0
MOV TEMP,A
GOON1: MOV R2,#2
JS1: MOV R3,#250
TIME1: MOV A,TEMP ;将TEMP中的十六进制数转换成10进制
MOV B,#10 ;10进制/10=10进制
DIV AB
MOV B_BIT,A ;十位在A
MOV A_BIT,B ;个位在B LCALL DPLOP1 ;插入一段判断定时过程中是否有按键输入的程序段
C1: JB P3.6,B1
ACALL DELAY10;延时10毫秒消抖
JB P3.6,C1
JNB P3.6,$;等待按键松开
CPL F0
ZT1: ; MOV P3,#0FFH;对P3口初始化,设置为高电平,用于按键输入
JB P3.6,$;循环判断开始按钮K1是否按下?
ACALL DELAY10;延时10毫秒触点消抖
JB P3.6,ZT1;如果是干扰就返回
JNB P3.6,$;等待按键松开
LCALL DPLOP1
B1: JB P3.7,LOOP1
ACALL DELAY10;延时10毫秒消抖
JB P3.7,B1
JNB P3.7,$;等待按键松开
AJMP OVERLOOP1: DJNZ R3,TIME1 ;2毫秒循环执行250次,时间约0.5秒
DJNZ R2,JS1 ;循环执行2次,时间为1 秒钟INC TEMP;满一秒钟对时间加1
MOV A,TEMP
CLR C
SUBB A,#60
JNZ GOON1;判断TEMP的数值是否为60?不为60循环
ACALL OVER
RET
GN2: MOV A,#14H ; 设定倒计时的时间20S
MOV TEMP,A;数码管显示倒计时时间的程序
;初始化
MOV P3,#0FFH;对P3口初始化,设置为高电平,用于按键输入
MOV P0,#14H;使显示时间为设定的倒计时时间 GOON2: MOV R2,#2
JS2: MOV R3,#250
TIME2: MOV A,TEMP ;将TEMP中的十六进制数转换成10进制
MOV B,#10 ;10进制/10=10进制
DIV AB
MOV B_BIT,A ;十位在A
MOV A_BIT,B ;个位在B MOV DPTR,#NUMTAB ;指定查表启始地址
DPLOP2: MOV A,A_BIT ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P0,A ;送出个位的7段代码
CLR P2.5 ;开个位显示
ACALL DELY1;显示1毫秒
SETB P2.5;关闭个位显示,防止鬼影
MOV A,B_BIT ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
CLR P2.6 ;开十位显示
ACALL DELY1;显示1毫秒
SETB P2.6;关闭十位显示,防止鬼影 ;插入一段判断定时过程中是否有按键输入的程序段
C2: JB P3.6,B2
ACALL DELAY10;延时10毫秒消抖
JB P3.6,C2
JNB P3.6,$;等待按键松开
ZT2: MOV P3,#0FFH;对P3口初始化,设置为高电平,用于按键输入
JB P3.6,$;循环判断开始按钮K1是否按下?
ACALL DELAY10;延时10毫秒触点消抖
JB P3.6,ZT2;如果是干扰就返回
JNB P3.6,$;等待按键松开
B2: JB P3.7,LOOP2
ACALL DELAY10;延时10毫秒消抖
JB P3.7,B1
JNB P3.7,$;等待按键松开
AJMP OVERLOOP2: DJNZ R3,TIME2 ;2毫秒循环执行250次,时间约0.5秒
DJNZ R2,JS2 ;循环执行2次,时间为1 秒钟DEC TEMP;满一秒钟对时间减1
MOV A,TEMP
JNZ GOON2;判断TEMP的数值是否为0?不为0循环
ACALL OVER
RET
;结束定时
OVER: AJMP START;退到开机初始化状态;1毫秒延时子程序
DELY1: MOV R4,#2
D1:MOV R5,#248
DJNZ R5,$
DJNZ R4,D1
RET;10毫秒延时子程序
DELAY10: MOV R4,#20
D2:MOV R5,#248
DJNZ R5,$
DJNZ R4,D2
RET;实验板上的两位一体的数码管0~9各数字的显示代码
NUMTAB: DB 40H,79H,24H,30H,19H,12H,02H,78H,00H,10H
DPLOP1: MOV A,A_BIT ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P0,A ;送出个位的7段代码
CLR P2.5 ;开个位显示
ACALL DELY1;显示1毫秒
SETB P2.5;关闭个位显示,防止鬼影
MOV A,B_BIT ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
CLR P2.6 ;开十位显示
ACALL DELY1;显示1毫秒
SETB P2.6;关闭十位显示,防止鬼影
RET
END
⑶ 单片机红外解码程序问题,完全不能理解
“我并非一点基础也没有”
很遗憾,从你提的这三个问题来看,你的基础比0只多出一点点。
(1)Tc是个16位整型。这是16位整型的基本算法。Tc保存的是抓出的脉宽。
(2)引导码就是指定宽度的脉冲,数据码是短一些的脉冲——所以才会那么大费周章地抓脉宽判断是引导码还是用户码。接收是否反相要查你所用接收头的手册,有可能跟你的程序是相反的。
(3)m不是字节序号而是位序号。注意前面的/8。
加油啊
⑷ 单片机中的TC位指什么
这个是定时器模式寄存器TMOD里的一位,在D2,D6位上,叫T/C,或者叫C/T位,工作方式选择位。这一位为0为定时,为1是计数。 D2是T0,D6是T1
⑸ 单片机控制一个4位的共阴数码管通电的状态下显示时间的程序
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit PRESS1=P1^0;
sbit PRESS2=P1^1;
sbit PRESS3=P1^2;
uint a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0到9
uint b[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
int miao=45,fen=58,shi=15;
uint jishu;
uint miaog,miaos,feng,fens,shig,shis;
int ji;
void init()//初始化函数设置中断寄存器的值。
{
jishu=0;
TMOD=0x01;
TR0=1;
ET0=1;
EA=1;
TH0=0x3c;
TL0=0xb0;
}
void delay(x)//延时函数。
{
uint i,j;
for(i=x;i>0;i--)
for(j=120;j>0;j--);
}
void xian()//把时分秒送到数码管显示。
{
uint i;
miaog=miao%10;
miaos=miao/10;
feng=fen%10;
fens=fen/10;
shig=shi%10;
shis=shi/10;
for(i=0;i<8;i++)
{
switch(i)
{
case 0:P3=b[7];P2=a[miaog];break;
case 1:P3=b[6];P2=a[miaos];break;
case 2:P3=b[5];P2=0x40;break;
case 3:P3=b[4];P2=a[feng];break;
case 4:P3=b[3];P2=a[fens];break;
case 5:P3=b[2];P2=0x40;break;
case 6:P3=b[1];P2=a[shig];break;
case 7:P3=b[0];P2=a[shis];break;
}
delay(1);
};
}
void jiance()//检测键是否按下按不同键实现不同的处理。
{
if(PRESS1==0)
{
delay(2);
if(PRESS1==0)
{
while(!PRESS1);
ji++;
if(ji>=4)
ji=0;
}
}
if(ji==1)
{
if(PRESS2==0)
{
delay(1);
while(!PRESS2);
miao++;
if(miao>=60)
{
miao=0;
fen++;
}
}
if(PRESS3==0)
{
delay(1);
while(!PRESS3);
miao--;
if(miao<0)
{
miao=59;
}
}
}
if(ji==2)
{
if(PRESS2==0)
{
delay(1);
while(!PRESS2);
fen++;
if(fen>=60)
{
fen=0;
shi++;
}
}
if(PRESS3==0)
{
delay(1);
while(!PRESS3);
fen--;
if(fen<0)
{
fen=59;
}
}
}
if(ji==3)
{
if(PRESS2==0)
{
delay(1);
while(!PRESS2);
shi++;
if(shi>=24)
{
shi=0;
}
}
if(PRESS3==0)
{
delay(1);
while(!PRESS3);
shi--;
if(shi<0)
{
shi=23;
}
}
}
if(ji==0)
EA=1;
else
EA=0;
}
void main()
{
init();
while(1)
{
xian();
jiance();
}
}
void an() interrupt 1 //计时中断0工作方式1函数。
{
TH0=0x3c;
TL0=0xb0;
jishu++;
if(jishu==20)
{
jishu=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
shi=0;
}
}
}
}
⑹ 单片机 热敏电阻测温
1、单片机热敏电阻测温首先要设计电路原理图,如图所示:
上图R3为上拉电阻,T1为接热敏电阻端,TC1为单片机AD采集口、电阻R4和电热C6为阻容滤波电路。
2、上拉电阻R3的选择:根据所用温度的范围,选择热敏电阻对应阻值范围的中间值最好,这样检测的温度偏差较小。
3、上拉电阻选定后,根据热敏电阻阻值表,算出温度真值表,用于软件查表,计算出温度值。在算温度真值表前,首先要确定单片机AD模块的分辨率。
4、单片机软件编程,滤波方法一般采用多次采集求累加和,去最大值和最小值,最后求平均。
5、单片机选择:一般选用8位单片机就够。但是,单片机自带的温度采集AD模块,最好选用10位分辨率,10位的AD模块分辨率高,温度采集精确。
6、以上为单片机热敏电阻测温的一般流程。