标题:
按钮 温度 红外三种方式控制电机转速的单片机程序
[打印本页]
作者:
wongj
时间:
2019-6-16 21:03
标题:
按钮 温度 红外三种方式控制电机转速的单片机程序
电路原理图如下:
[}CY6B5[M~U0}KKHDEJBY[N.png
(194.83 KB, 下载次数: 48)
下载附件
图
2019-6-16 21:02 上传
单片机源程序如下:
#include <reg51.h>
#include <intrins.h>
unsigned int times;
unsigned int controlway;
unsigned int flag=0;
unsigned int flaghongwai=0;
//电机控制
sbit out3=P2^2;
sbit out1=P2^0;
sbit out2=P2^1;
//按钮控制
sbit button=P1^0;
sbit buttonup=P1^6;
sbit buttondown=P1^7;
//温度控制
sbit DQ=P3^7;
sbit temp=P1^1;
//红外控制
sbit hongwai=P1^2;
sbit IR = P3^2;
unsigned char N[4];//识别码,操作码存放
unsigned char X1,X2,X3,X4;
void delay(unsigned char n){
do{
_nop_();
_nop_();
_nop_();
n--;
}while(n);
}
//温度控制
void init_ds18b20(){
unsigned char x=0;
DQ=0;
delay(120);
DQ=1;
delay(16);
delay(80);
}
unsigned char readbyte(){
unsigned char i=0;
unsigned char date=0;
for(i=8;i>0;i--){
DQ=0;
delay(1);
DQ=1;
date>>=1;
if(DQ)
date|=0x80;
delay(11);
}
return (date);
}
void writebyte(unsigned char dat){
unsigned char i=0;
for(i=8;i>0;i--){
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
delay(5);
}
}
unsigned char retemp(){
unsigned char a,b,tt;
unsigned int t;
init_ds18b20();
writebyte(0xcc);
writebyte(0x44);
init_ds18b20();
writebyte(0xcc);
writebyte(0xbe);
a=readbyte();
b=readbyte();
t=b;
//t=t<<8;
t<<=8;
t=t|a;
tt=t*0.0625;
return (tt);
}
//按键检测,电机转速控制
timer0 () interrupt 1 {
unsigned char tempread=0;
if(button==0){
controlway=1;
}else if(temp==0){
controlway=2;
}else if(hongwai==0){
controlway=3;
}else{
controlway=1;
}
switch(controlway){
case 1:
if(buttonup==0){
if(times<10000){
times+=1000;
}
}else if(buttondown==0){
if(times>0){
times-=1000;
}
}
delay(100);
break;
case 2:
flag++;
if(flag==20)
{
tempread=retemp();
if(tempread>24&&tempread<34){
times=1000*(tempread-24);
}else{
times=10000;
}
flag=0;
}
break;
case 3:
//转换为外部中断
IT0 = 0;
EX0 = 1;
break;
}
TH0=0x3c;
TL0=0xb0;
}
//红外接收信号
/********************** 外部中断函数************************/
void exint0() interrupt 0
{
unsigned int cnt;
unsigned char i;
EX0 = 0;
cnt = 0;
while(!IR) cnt++; //记录引导码时间
if(cnt < 1000){EX0=1;return;} //9ms的计数值(12MHz:1000< cnt <1500)
cnt = 0;
while(IR) if(cnt++ > 400){EX0=1;return;} //防卡死,超时保护(12MHz: > 300)
if(cnt < 200){EX0=1;return;} //(12MHz不分频: <260)
for(i=0; i<32; i++) //读取32位位码
{
cnt = 0;
while(!IR);
while(IR) if(cnt++ > 200){EX0=1;return;} //超时保护(12MHz:>=200)
N[i/8] >>= 1;
if(cnt>60) N[i/8] |= 0x80; //0和1的计数界线(12MHz:< 109)
}
if(N[0] == ~N[1] && N[2] == ~N[3]) //校验识别码,操作码
{
/*
X1 = N[0]/16;
X2 = N[0]%16;
X3 = N[2]/16;
*/
X4 = N[2]%16;
flaghongwai=1;
}
EX0 = 1;
}
main(){
TMOD = 0x01;
TH0=0x3c;
TL0=0xb0;
//TH0 = (65536-50000)/256;
//TL0 = (65536-50000)%256;
EA=1;
ET0=1;
//TR0=1;
X1=X2=X3=X4 = 0;
times=0;
delay(1000);
while(1){
TR0=1; //转换为定时器
if(flaghongwai==1)
{ TR0=0;
if(X4==1&×<10000){
times=times+1000;
}else if(X4==2&×>100){
times=times-1000;
}
X4 = 0;
flaghongwai=0;
}
out2=1;
out1=0;
out3=0;
delay(times);
out1=1;
out3=1;
delay(10000-times);
}
}
复制代码
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sendup=P1^0;
sbit senddown=P1^1;
#define SBM 0x80 //识别码
#define m9 (65536-9000) //约9mS
#define m4_5 (65536-4500) //约4.5mS
#define m1_6 (65536-1630) //约1.65mS
#define m_65 (65536-580) //约0.65mS
#define m_56 (65536-560) //约0.56mS
#define m40 (65536-40000) //约40mS
#define m56 (65536-56000) //56mS
#define m2_25 (65536-2250) //约2.25mS
sbit IR = P3^6; //定义发射引脚(接PNP三极管基极)
uchar KEY(void);
void SanZhuan(void);
void ZZ(uchar x);
void Z0(uchar temp);
void TT0(bit BT,uint x);
void YS(uchar time);
void delay(unsigned char n){
do{
_nop_();
_nop_();
_nop_();
n--;
}while(n);
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:主函数
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{
TMOD = 0x01; //T0 16位工作方式
IR=1; //发射端口常态为高电平
while(1)
{
SanZhuan();
}
}
uchar KEY(void)
{
P1 = 0xff; //将键盘端口行值设为1,列值设为0
if(sendup==0){
return 1;
}else if(senddown==0){
return 2;
}
return 0;
}
/***************************************************************
函数功能:散转程序
入口参数:v
//
// 13 14 15 16
// 9 10 11 12
// 5 6 7 8
// 1 2 3 4
***************************************************************/
void SanZhuan(void)
{
uchar v;
v = KEY();
switch(v)
{
case 1:ZZ(0x01);v=0;break; //" "
case 2:ZZ(0x02);v=0;break; //" "
default:v=0;
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:发送主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uchar x)
{
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS
/*┈ 发送4帧数据 ┈*/
Z0(SBM);
Z0(~SBM);
Z0(x);
Z0(~x);
/*┈┈ 结束码 ┈┈*/
TT0(1,m_65);
TT0(0,m40);
/*┈┈ 重复码 ┈┈*/
while(KEY())
{
TT0(1,m9);
TT0(0,m2_25);
TT0(1,m_56);
TT0(0,m40);
TT0(0,m56);
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:单帧发送程序
入口参数:1帧数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uchar temp)
{
uchar v;
for (v=0;v<8;v++) //循环8次移位
{
TT0(1,m_65); //高电平0.65mS
if(temp&0x01) TT0(0,m1_6); //发送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:38KHz脉冲发射 + 延时程序
入口参数:(是否发射脉冲,延时约 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint x)
{
TH0 = x>>8; //输入T0初始值
TL0 = x;
TF0=0; //清0
TR0=1; //启动定时器0
if(BT == 0) while(!TF0); //BT=0时不发射38KHz脉冲只延时;BT=1发射38KHz脉冲且延时;
else while(1) //38KHz脉冲,占空比5:26
{
IR = 0;
if(TF0)break;
if(TF0)break;
IR = 1;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
}
TR0=0; //关闭定时器0
TF0=0; //标志位溢出则清0
IR =1; //脉冲停止后,发射端口常态为高电平
}
/***************************************************************
函数功能:按键消抖 延时程序
入口参数:1ms×time (晶振=12MHz)
***************************************************************/
void YS(uchar time)
{
uchar i,j;
for(i=0; i<time; i++)
for(j=0; j<247; j++)_nop_();
}
复制代码
作者:
jovew
时间:
2019-12-17 09:18
请教一下,第二个文件的第192行,和第194行是什么错误?
编译不能通过。
作者:
jovew
时间:
2019-12-17 09:20
刚刚发错了。是程序的第一部分。
作者:
心素如简c
时间:
2020-6-28 18:10
用户码0080 对应的什么型号的遥控器啊 对应的码值表是什么啊
作者:
Jeff_BlindCat
时间:
2020-6-30 18:45
谢谢楼主指点,这个要慢慢消化下。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1