标题:
51单片机代码实现按键-PC串口通讯-红外遥控控制电机
[打印本页]
作者:
l920348949
时间:
2017-4-24 20:52
标题:
51单片机代码实现按键-PC串口通讯-红外遥控控制电机
51单片机代码实现按键-PC串口通讯-红外遥控控制电机
0.png
(51.9 KB, 下载次数: 55)
下载附件
2017-4-24 21:55 上传
完整代码下载:
红外无线-PC机串口-按键控制PWM变化.rar
(39.91 KB, 下载次数: 67)
2017-4-24 20:51 上传
点击文件名下载附件
中断嵌套实现多功能控制电机
下载积分: 黑币 -5
部分源码预览:
#include<reg51.h> //51头文件,
#include<intrins.h>
//---------常用的两个宏定义--------------
typedef unsigned char u8;
typedef unsigned int u16;
//------------函数的声明-----------------
void DelayMS(u16 dly);
//--定义使用的IO口--//
sbit LED=P1^3;
sbit KEY1=P1^1;
sbit KEY2=P1^2;
sbit PWM=P2^1;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit IRIN=P3^2;
//--定义一个全局变量--//
u16 num,j,k,pwm,i; //定时器返回值
u8 myKEY; //存放电脑发送过来的按键
u8 IrValue[6];
u8 Time;
u8 DisplayData[8];
u8 code smgduan[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码
//void Timer0Interrupt();
//void InitTimer1();
//void Keyscan();
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
void Delay10ms(u8 c) //误差 0us
{
u8 a, b;
for (;c>0;c--) //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
/*******************************************************************************
* 函数名 :DigDisplay()
* 函数功能 :数码管显示函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<3;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
}
P0=DisplayData[i];//发送数据
delay(10); //间隔一段时间扫描
P0=0x00;//消隐
}
}
/*******************************************************************************
* 函数名 : IrInit()
* 函数功能 : 初始化红外线接收
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1; //打开总中断
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0 = 0xFF;
TL0 = 0xff; //60ms
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : UsartInit()
* 函数功能 : 串口初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void UsartInit()
{
SCON=0x50; //设置串口工作模式1,允许接收
TMOD=0x20; //设置定时器1工作方式2
PCON=0x80; //波特率加倍
TH1=0xF3; //设置定时器1初始值,波特率是4800bps
TL1=0xF3;
TR1=1; //启动定时器1
EA=1; //打开总中断
ES=1; //打开接收中断
}
void main(void)
{
IrInit();
k=2;
Timer0Init(); //定时器0初始化
UsartInit(); // 串口初始化
IP=0x10; //设置串口中断为高优先级
i=100;
while(1)
{
DisplayData[0] = smgduan[IrValue[2]/16];
DisplayData[1] = smgduan[IrValue[2]%16];
DisplayData[2] = smgduan[16];
DigDisplay();
if (KEY1==0) //检测按键K1是否按下
{
Delay10ms(1); //消除抖动
num=0;
while (KEY1==0) //再次检测按键是否按下
{
Delay10ms(1);
num++; //记录按键按下的时间
}
if(5<num&&num<50) //此处一定不能定成0<num<50否则程序会认为是0<num而不会判定num<50;
LED=~LED;
i=i+5;
if(num>50)
k++;
while(!KEY1)
{
}
}
if (myKEY=='x' || myKEY=='X') //检测键盘按键是否按下
{
Delay10ms(1); //消除抖动
if (myKEY=='x' || myKEY=='X') //再次检测键盘按键是否按下
{
LED=~LED;
i=i+5;
myKEY=0;
}
}
if (IrValue[2]/16==0&&IrValue[2]%16==9) //检测遥控按键是否按下
{
LED=~LED;
i=i+10;
IrValue[2]=0x11;
}
else if (KEY2==0)
{
Delay10ms(1);
if (KEY2==0)
{
LED=~LED;
i=i-5;
j=0;
while ((j<30) && (KEY2==0)) //检测按键是否松开
{
Delay10ms(1);
j++;
}
}
}
P2=~k;
if(myKEY=='y' || myKEY=='Y') //按下键盘的Y键就亮,按其它键则灭
{
LED=~LED;
i=i-5;
myKEY=0;
}
if (IrValue[2]/16==1&&IrValue[2]%16==5) //检测按键K1是否按下
{
LED=~LED;
i=i-10;
IrValue[2]=0x00;
}
}
}
/*******************************************************************************
* 函数名 : ReadIr()
* 函数功能 : 读取红外数值的中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void ReadIr() interrupt 0
{
u8 j,k;
u16 err;
Time=0;
delay(700); //7ms
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=1000; //1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
{
delay(1);
err--;
}
if(IRIN==1) //如果正确等到9ms低电平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
{
delay(1);
err--;
}
for(k=0;k<4;k++) //共有4组数据
{
for(j=0;j<8;j++) //接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
delay(10); //0.1ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}
}
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0xff;
TL0 = 0xff;
pwm++;
if(i>=200) //改变i这个值可以改变直流电机的速度
{
i=200;
}
if(pwm>200) //PWM周期为100*0.5ms
{
pwm=0;
}
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
作者:
cheny736
时间:
2019-1-31 23:47
唔,小白一个,不会用。。。。
作者:
菠菜195
时间:
2019-2-6 13:15
楼主程序注释得很详细,感谢
作者:
yasi666
时间:
2019-4-9 10:22
非常感谢,学习了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1