资讯详情

单片机红外遥控+步进电机+1602液晶显示c语言源程序

这是我做的红外遥控控制的1602显示转速和转向的c语言原程序,已经调试成功!有些模块是以前做其他实验时做的 ,现在是直接调用的,包括1602液晶显示技术,TC9012红外解码,然后就是四相步进的控制程序了,我是把这些东西结合起来。对这个东西有兴趣的或者要做毕业设计的可以看看啊,不懂的请上单片机论坛http://www.51hei.com/bbs/ 公开讨论,我会给大家做出详细的解答。

#include <AT89X51.h>

#include<stdio.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int static unsigned int count; //计数 unsigned int hour,minute,second,count;

sbit RS = P2^3;//Pin4 sbit RW = P2^2; //Pin5 sbit E = P2^4;//Pin6

#define Data P0 //数据端口 static int step_index; //步进索引数,值为0-7 bit k=0; //红外解码判断标志位,为0则为有效信号,为1则为无效 uchar n=0; //用来控制外部中断 static bit turn; //步进电机转动方向 static bit stop_flag; //步进电机停止标志 static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快 static int spcount; //步进电机转速参数计数 void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒 void gorun(); //步进电机控制步进函数 uchar data date[4]; //date数组为存放地址原码,反码,数据原码,反码 char data Test1[]=" "; #define _RE P3_2 void DelayUs(unsigned char us)//delay us { unsigned char uscnt; uscnt=us>>1;/* Crystal frequency in 12MHz*/ while(--uscnt); } /******************************************************************/ void DelayMs(unsigned char ms)//delay Ms { while(--ms) { DelayUs(250); DelayUs(250); DelayUs(250); DelayUs(250); } } void WriteCommand(unsigned char c) { DelayMs(5);//short delay before operation E=0; RS=0; RW=0; _nop_(); E=1; Data=c; E=0; } /****************************************************************/ void WriteData(unsigned char c) { DelayMs(5); //short delay before operation E=0; RS=1; RW=0; _nop_(); E=1; Data=c; E=0; RS=0; } /***********http://www.51hei.com单片机原创作品******************/ void ShowChar(unsigned char pos,unsigned char c) { unsigned char p; if (pos>=0x10) p=pos+0xb0; //是第二行则命令代码高4位为0xc else p=pos+0x80; //是第二行则命令代码高4位为0x8 WriteCommand (p);//write command WriteData (c); //write data } /*************************************************************************/ void ShowString (unsigned char line,char *ptr) { unsigned char l,i; l=line<<4; for (i=0;i<16;i++) ShowChar (l++,*(ptr+i));//循环显示16个字符 } /*********************************************************************/ void InitLcd() { DelayMs(15); WriteCommand(0x38); //display mode WriteCommand(0x38); //display mode WriteCommand(0x38); //display mode WriteCommand(0x06); //显示光标移动位置 WriteCommand(0x0c); //显示开及光标设置 WriteCommand(0x01); //显示清屏

}

/*--------------------------延时1ms程子程序-----------------------*/ delay1000() { uint i,j; for(i=0;i<1;i++) for(j=0;j<124;j++) ; }

/*---------------------------延时882us子程序-----------------------*/

delay882() { uint i,j; for(i=0;i<1;i++) for(j=0;j<109;j++) ; }

/*--------------------------延时2400ms程子程序-----------------------*/

delay2400() { uint i,j; for(i=0;i<3;i++) for(j=0;j<99;j++) ; } void IR_decode() { uchar i,j; while(IR_RE==0); delay2400(); if(IR_RE==1) //延时2.4ms后如果是高电平则是新码 { delay2400(); //延时4.8ms避开4.5ms的高电平 for(i=0;i<4;i++) { for(j=0;j<8;j++) { while(IR_RE==0); //等待地址码第1位高电平到来 delay882(); //延时882ms判断此时引脚电平 ///CY=IR_RE; if(IR_RE==0) { date[i]>>=1; date[i]=date[i]&0x7f; } else if(IR_RE==1) { delay1000(); date[i]>>=1; date[i]=date[i]|0x80; } } //1位数据接收结束 } //32位二进制码接收结束 } if (date[2]==0x16) TR0 = 0; else if(date[2]==0x14) {TR0 = 1; } else if(date[2]==0x10) {if (speedlevel>1) speedlevel--; else speedlevel=1; } else if(date[2]==0x1A) {if(speedlevel<5) speedlevel++; else speedlevel=5; } else if(date[2]==0x11) turn=~turn;

} void int0() interrupt 0 using 1 { uint i; for(i=0;i<4;i++) { delay1000(); if(IR_RE==1){k=~k;} //刚开始为4.5ms的引导码,如果4ms内出现高电平则退出解码程序 }

if(k==0) { EX0=0; //检测到有效信号关中断,防止干扰 IR_decode(); //如果接收到的是有效信号,则调用解码程序 //解码成功,调用显示程序,显示该键值 } EX0=1; //开外部中断,允许新的遥控按键 } void main(void) { InitLcd();// DelayMs(15);

sprintf(Test1,"P MOTOR EED");//the first line ShowString(0,Test1); ShowChar(0x19,'r'); ShowChar(0x1a,'p'); ShowChar(0x1b,'m'); count = 0; step_index = 0; spcount = 0; stop_flag = 0;

P1_0 = 0; P1_1 = 0; P1_2 = 0; P1_3 = 0; SP=0x60; EA = 1; //允许中断 TMOD = 0x11; //设定时器0和1为16位模式1 ET0 = 1; //定时器0中断允许 EX0=1; TH0 = 0xFE; TL0 = 0x0C; //设定时每隔0.5ms中断一次 TR0 = 1; //开始计数 turn=0;

speedlevel=1; while(1) { if(turn==0) ShowChar(0x14,'+'); else ShowChar(0x14,'-'); if(TR0 ==0) { ShowChar(0x15,'0'); ShowChar(0x16,'0'); ShowChar(0x17,'0'); ShowChar(0x18,'0'); } else { if(speedlevel==1) { ShowChar(0x15,'3'); ShowChar(0x16,'0'); ShowChar(0x17,'0'); ShowChar(0x18,'0'); } else if(speedlevel==2) { ShowChar(0x15,'1'); ShowChar(0x16,'5'); ShowChar(0x17,'0'); ShowChar(0x18,'0'); } else if(speedlevel==3) { ShowChar(0x15,'1'); ShowChar(0x16,'0'); ShowChar(0x17,'0'); ShowChar(0x18,'0'); } else if(speedlevel==4) { ShowChar(0x15,'0'); ShowChar(0x16,'7'); ShowChar(0x17,'5'); ShowChar(0x18,'0'); } else if(speedlevel==5) { ShowChar(0x15,'0'); ShowChar(0x16,'6'); ShowChar(0x17,'0'); ShowChar(0x18,'0'); } } } } //定时器0中断处理 void timeint(void) interrupt 1 using 0 { TH0=0xFE; TL0=0x0C; //设定时每隔0.5ms中断一次

count++;

spcount--; if(spcount<=0) { spcount = speedlevel; gorun(); }

}

void delay(unsigned int endcount) { count=0; do{}while(count<endcount); }

void gorun() { if (stop_flag==1) { P1_0 = 0; P1_1 = 0; P1_2 = 0; P1_3 = 0; return; }

switch(step_index) { case 0: //0 P1_0 = 1; P1_1 = 0; P1_2 = 0; P1_3 = 0; break; case 1: //0、1 P1_0 = 1; P1_1 = 1; P1_2 = 0; P1_3 = 0; break; case 2: //1 P1_0 = 0; P1_1 = 1; P1_2 = 0; P1_3 = 0; break; case 3: //1、2 P1_0 = 0; P1_1 = 1; P1_2 = 1; P1_3 = 0; break; case 4: //2 P1_0 = 0; P1_1 = 0; P1_2 = 1; P1_3 = 0; break; case 5: //2、3 P1_0 = 0; P1_1 = 0; P1_2 = 1; P1_3 = 1; break; case 6: //3 P1_0 = 0; P1_1 = 0; P1_2 = 0; P1_3 = 1; break; case 7: //3、0 P1_0 = 1; P1_1 = 0; P1_2 = 0; P1_3 = 1; }

if (turn==0) { step_index++; if (step_index>7) step_index=0; } else { step_index--; if (step_index<0) step_index=7; } }

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台