#include <reg52.h> //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
unsigned char code zheng[4]={0xf8,0xf4,0xf2,0xf1};//正转表格
unsigned char code fan[4]={0xf1,0xf2,0xf4,0xf8};//反转表格
uchar flag_start ; //启动标志位 1为起动步进电机 否则关闭电机
uchar flag_z_f; //正反标志位 0为顺时钟 1为逆时史上转
uchar flag_shudu; //4种速度 0,1,2,3,
uint flag_shudu_value = 400;
uchar dangwei ; //档位标志位
sbit hw_P32=P3^2; //红外遥控接的IO口
uchar hw_table[4]; //红外解码的缓冲区
bit flag_jiema_en = 1; //红外解码成功标志位
//数码管段选定义 0 1 2 3 4 5 6 7 8 9
uchar code smg_du[]={0x28,0xee,0x32,0xa5,0xe4,0xa4,0x28,0xea,0x20,0xa0,
0x60,0x25,0x39,0x26,0x31,0x71,0xff}; //断码
uchar dis_smg[4] = {0}; //数码管显示数组的缓冲区
sbit smg_we1 = P3^7; //数码管位选IO口定义
sbit smg_we2 = P3^6; //数码管位选IO口定义
sbit smg_we3 = P3^5; //数码管位选IO口定义
sbit smg_we4 = P3^4; //数码管位选IO口定义
sbit key1 = P2^4; //按键IO口定义
sbit key2 = P2^5; //按键IO口定义
sbit key3 = P2^6; //按键IO口定义
sbit key4 = P2^7; //按键IO口定义
/***************100us的延时函数***12M晶振*****************/
void delay_100us(uchar z)
{ //12M
uchar x,y;
for(x=0;x<z;x++)
for(y=0;y<20;y++);
}
/***************************数码管位选函数****************************/
void smg_we_switch(uchar i)
{
switch(i)
{
case 0: smg_we1 = 0; smg_we2 = 1; smg_we3 = 1; smg_we4 = 1; break;
case 1: smg_we1 = 1; smg_we2 = 0; smg_we3 = 1; smg_we4 = 1; break;
case 2: smg_we1 = 1; smg_we2 = 1; smg_we3 = 0; smg_we4 = 1; break;
case 3: smg_we1 = 1; smg_we2 = 1; smg_we3 = 1; smg_we4 = 0; break;
}
}
/********************************************************************
* 名称 : display()
* 功能 : 数码管显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void display()
{
uchar i;
i++;
if(i >= 4)
i = 0;
P1 = 0xff; //消隐
smg_we_switch(i);
P1 = dis_smg[i]; //段选
}
void Delay(unsigned int i)//小延时
{
while(--i);
}
/********************独立按键程序*****************/
uchar key_can; //按键值
void key() //独立按键程序
{
key_can = 0; //按键值还原成0
if(key1 == 0 || key2 == 0 || key3 == 0 || key4 == 0) //有按键按下
{
Delay(100); //按键延时消抖动
if(key1 == 0) //确认是按键按下
key_can = 1; //得到按键值
if(key2 == 0) //确认是按键按下
key_can = 2; //得到按键值
if(key3 == 0) //确认是按键按下
key_can = 3; //得到按键值
if(key4 == 0) //确认是按键按下
key_can = 4; //得到按键值
}
}
/*************定时器0初始化程序***************/
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0、工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
TH0 = 0xf8;
TL0 = 0x30; //2ms
}
/******************外部中断0的初始化程序**********************/
void int0_init()
{
EA = 1; //开总中断
EX0 = 1; //允许外部中断0中断
IT0 = 1; //外部中断0负脉冲触发
}
/*****************红外遥控程序********************/
void hw_yaokong()
{
if(flag_jiema_en == 1)
{
flag_jiema_en = 0;
if(hw_table[2] == 0x45)
key_can = 1; //得到按键值
if(hw_table[2] == 0x47)
key_can = 2; //得到按键值
if(hw_table[2] == 0x15) //加
key_can = 3; //得到按键值
if(hw_table[2] == 0x07) //减
key_can = 4; //得到按键值
if(hw_table[2] == 0x0c)
flag_shudu = 0;
if(hw_table[2] == 0x18)
flag_shudu = 1;
if(hw_table[2] == 0x5e)
flag_shudu = 2;
if(hw_table[2] == 0x08)
flag_shudu = 3;
switch(flag_shudu)
{
case 0: flag_shudu_value = 1500; dangwei = 1; break; //速度1 最慢
case 1: flag_shudu_value = 1000; dangwei = 2; break;
case 2: flag_shudu_value = 650; dangwei = 3; break;
case 3: flag_shudu_value = 400; dangwei = 4; break; //速度4 最快
}
hw_table[2] = 0;
}
}
/******************主程序**********************/
void main()
{
unsigned char i;
time_init(); //定时器0初始化程序
int0_init();
while(1)
{
dis_smg[0] = smg_du[dangwei]; //显示档位
key(); //按键程序
hw_yaokong(); //红外遥控程序
if(key_can > 0)
{
if(key_can == 1) //启动键
{
if(flag_start == 0) //启动
{
flag_start = 1;
switch(flag_shudu)
{
case 0: flag_shudu_value = 1500; dangwei = 1; break; //速度1 最慢
case 1: flag_shudu_value = 1000; dangwei = 2; break;
case 2: flag_shudu_value = 650; dangwei = 3; break;
case 3: flag_shudu_value = 400; dangwei = 4; break; //速度4 最快
}
}
else //停止
{
flag_start = 0;
}
}
if(key_can == 2) //正反转键
{
flag_z_f = ~flag_z_f; //
if(flag_z_f == 0)
{
dis_smg[3] = smg_du[2]; //显示Z 表示正转
}
else
{
dis_smg[3] = smg_du[15]; //显示F 表示反转
}
}
if(key_can == 3)
{
flag_shudu ++; //加速
if(flag_shudu >= 4)
{
flag_shudu = 0;
}
switch(flag_shudu)
{
case 0: flag_shudu_value = 1500; dangwei = 1; break; //速度1 最慢
case 1: flag_shudu_value = 1000; dangwei = 2; break;
case 2: flag_shudu_value = 650; dangwei = 3; break;
case 3: flag_shudu_value = 400; dangwei = 4; break; //速度4 最快
}
}
if(key_can == 4)
{
if(flag_shudu == 0) //减速
flag_shudu = 4;
flag_shudu --;
switch(flag_shudu)
{
case 0: flag_shudu_value = 1500; dangwei = 1; break; //速度1 最慢
case 1: flag_shudu_value = 1000; dangwei = 2; break;
case 2: flag_shudu_value = 650; dangwei = 3; break;
case 3: flag_shudu_value = 400; dangwei = 4; break; //速度4 最快
}
}
}
if(flag_start == 1)
{
for(i=0;i<4;i++) //4相
{
if(flag_z_f == 0)
{
P2=zheng[i]; //电机正转
dis_smg[3] = smg_du[2]; //显示Z 表示正转
}
else
{
P2=fan[i]; //电机反转
dis_smg[3] = smg_du[15]; //显示F 表示反转
}
Delay(flag_shudu_value); //改变这个参数可以调整电机转速
}
}
}
}
/*****************红外解码程序********************/
void int0() interrupt 0
{
unsigned char i,j;
delay_100us(20); //防止干扰
if(hw_P32 == 0)
{ //引导码
while(hw_P32 == 0); //等待低电平过完
delay_100us(20);
if(hw_P32 == 1) //引码结束
{
delay_100us(20); // 说明高电平已经过完 引导码已经结束
for(i=0;i<4;i++)
for(j=0;j<8;j++)
{
while(hw_P32 == 0); //等待过完
delay_100us(5);
if(hw_P32 == 0) //数据0的时间
{ //数据1的时间
hw_table[i] >>= 1; //低位在前
}
else
{
delay_100us(5); // 高电平的时间过完
hw_table[i] >>= 1; //低位在前
hw_table[i] |= 0x80; //数据值1
}
}
flag_jiema_en = 1; //红外解码成功
}
}
}
/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{
TH0 = 0xF8;
TL0 = 0x30; //定时2ms中断一次
display();
}
评论0