{
DataPort=0;//清空数据,防止有交替重影
LATCH1=1;//段锁存
LATCH1=0;
DataPort=WeiMa[i+FirstBit];//取位码
LATCH2=1;//位锁存
LATCH2=0;
DataPort=TempData[i];//取显示数据,段码
LATCH1=1;//段锁存
LATCH1=0;
Delay(200);//扫描间隙延时,时间太长/会闪烁,太短会造成重影
}
}
动态显示消隐方法
if(num<1000)//如果小于1000则千位不显示
TempData[0]=0;
elseTempData[0]=dofly_DuanMa[num/1000];
//分解显示信息,如要显示68,则68/10=6/68%10=8
//如果小于100则千位和百位都不显示
if(num<100)TempData[1]=0;
else
TempData[1]=dofly_DuanMa[(num%1000)/100];
//如果小于10,则千位、百位和十位
/都不显示
if(num<10)TempData[2]=0;
else
TempData[2]=dofly_DuanMa[((num%1000)%100)/10];
使用中断实现分频器的功能
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
voidTimer0_isr(void)interrupt1using1
{
staticunsignedchari;
//重新赋值12M晶振计算,指令周期1uS,500x2=1mS方波
TH0=(65536-500)/256;
TL0=(65536-500)%256;
i++;
P1=i;
/*P1口8路输出不同频率,相当于一个分频器,高频用示波器测量,低频可以直接用led观测P1.0输出1ms方波,P1.1输出2ms,p1.2输出4ms,以此类推*/
}
按键行扫描程序
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
//键盘扫描函数,使用行列逐级扫描法
unsignedcharKeyScan(void)
{
unsignedcharVal;
KeyPort=0xf0;//高四位置高,低四位拉低
if(KeyPort!
=0xf0)//表示有按键按下
{
DelayMs(10);//去抖
if(KeyPort!
=0xf0)//表示有按键按下
{
KeyPort=0xfe;//检测第一行
if(KeyPort!
=0xfe)
{
Val=KeyPort&0xf0;
Val+=0x0e;
while(KeyPort!
=0xfe);
DelayMs(10);//去抖
while(KeyPort!
=0xfe);
returnVal;
}
KeyPort=0xfd;//检测第二行
if(KeyPort!
=0xfd)
{
Val=KeyPort&0xf0;
Val+=0x0d;
while(KeyPort!
=0xfd);
DelayMs(10);//去抖
while(KeyPort!
=0xfd);
returnVal;
}
KeyPort=0xfb;//检测第三行
if(KeyPort!
=0xfb)
{
Val=KeyPort&0xf0;
Val+=0x0b;
//松手检测
while(KeyPort!
=0xfb);
DelayMs(10);//去抖
while(KeyPort!
=0xfb);
returnVal;
}
KeyPort=0xf7;//检测第四行
if(KeyPort!
=0xf7)
{
Val=KeyPort&0xf0;
Val+=0x07;
while(KeyPort!
=0xf7);
DelayMs(10);//去抖
while(KeyPort!
=0xf7);
returnVal;
}
}
}
return0xff;
}
步进电机1相励磁驱动
//A相通电,其他相断电
#defineoil_A1{A1=1;B1=0;C1=0;D1=0;}
//B相通电,其他相断电
#defineCoil_B1{A1=0;B1=1;C1=0;D1=0;}
//C相通电,其他相断电
#defineCoil_C1{A1=0;B1=0;C1=1;D1=0;}
//D相通电,其他相断电
#defineCoil_D1{A1=0;B1=0;C1=0;D1=1;}
//全部断电
#defineCoil_OFF{A1=0;B1=0;C1=0;D1=0;}
while
(1)
{
Coil_A1
//改变以下参数可以调整电机转速,数字越小,转速越大,力矩越小
DelayMs(Speed);
Coil_B1
DelayMs(Speed);
Coil_C1
DelayMs(Speed);
Coil_D1
DelayMs(Speed);
}
}
步进电机1-2相励磁驱动
if(times==Speed)
{
times=0;
switch(i)
{
case0:
Coil_A1;i++;break;
case1:
Coil_AB1;i++;break;
case2:
Coil_B1;i++;break;
case3:
Coil_BC1;i++;break;
case4:
Coil_C1;i++;break;
case5:
Coil_CD1;i++;break;
case6:
Coil_D1;i++;break;
case7:
Coil_DA1;i++;break;
case8:
i=0;break;
default:
break;
}
}
elsetimes++;
电机按键控制
sbitDCOUT1=P1^1;//电机信号输出端口1
switch(num)
{
//电机1改变运行状态,数码管显示运行状态
case1:
DCOUT1=!
DCOUT1;
TempData[0]=0x5E;//'d'
TempData[1]=0x39;//'C'
TempData[2]=0x06;//'1'
if(DCOUT1)
{
TempData[5]=0x3F;//'O'
TempData[6]=0x54;//'n'
TempData[7]=0;
}
else
{
TempData[5]=0x3F;//'O'
TempData[6]=0x71;//'F'
TempData[7]=0x71;//'F'
}
break;
}
LCD1602*
//判断液晶忙,如果忙则等待
voidRead_Busy()
{
ucharbusy;
P0=0xff;
RS=0;
RW=1;
do
{
EN=1;
busy=P0;
EN=0;
}while(busy&0x80);
}
//写LCD1602命令一个字节
voidWrite_Cmd(ucharcmd)
{
Read_Busy();//判断忙
RS=0;
RW=0;
P0=cmd;
EN=1;
EN=0;
}
//写一个字节数据
voidWrite_Dat(uchardat)
{
Read_Busy();
RS=1;
RW=0;
P0=dat;
EN=1;
EN=0;
}
LCD1602
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bitLCD_Check_Busy(void)
{
DataPort=0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return(bit)(DataPort&0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
voidLCD_Write_Com(unsignedcharcom)
{
while(LCD_Check_Busy());//忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort=com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
voidLCD_Write_Data(unsignedcharData)
{
while(LCD_Check_Busy());//忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort=Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
voidLCD_Write_String(ucharx,uchary,uchar*s)
{
if(y==0)LCD_Write_Com(0x80+x);
elseCD_Write_Com(0xC0+x);
while(*s)
{
LCD_Write_Data(*s);
s++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
voidLCD_Write_Char(ucharx,uchary,ucharData)
{
if(y==0)LCD_Write_Com(0x80+x);
elseLCD_Write_Com(0xC0+x);
LCD_Write_Data(Data);
}
LCD1602键盘输入显示
while
(1)
{
num=KeyPro();
if(num!
=0xff)
{
if((i==0)&&(j==0))/回到第一个字符时清屏
LCD_Clear();//清屏
//依次显示输入字符
LCD_Write_Char(0+i,0+j,dofly_code[num]);
i++;
if(i==16)/如果第一行显示满,转到第二行
{
i=0;j++;
//如果2行都显示满,清屏后重新从第一行
显示
if(j==2)j=0;
}
}}
LCD1602动态显示
while
(1)
{
i=1;
p="";
LCD_Clear();
LCD_Write_String(2,0,"Welcometo");
DelayMs(250);
while(*p)
{
LCD_Write_Char(i,1,*p);
i++;
p++;
DelayMs(250);
}
DelayMs(250);
}
LCD602滚动显示
voidmain(void)
{
LCD_Init();
LCD_Clear();//清屏
LCD_Write_Char(7,0,'o');
LCD_Write_Char(8,0,'k');
LCD_Write_String(1,1,"");
while
(1)
{
DelayMs(200);
LCD_Write_Com(0x18);//左平移画面
/0x1C是右平移
}
}
LCD1602平移显示
while
(1)
{
pa="Welcometo";
pb="";
LCD_Clear();
LCD_Write_String(2,0,pa);//显示2行信息
LCD_Write_String(1,1,pb);
for(i=0;i<8;i++)DelayMs(250);/延时2s左右
LCD_Clear();//清屏显示其他信息
i=2;
while(*pa)//循环输入方式显示2行信息
{
LCD_Write_Char(i,0,*pa);
i++;
pa++;
DelayMs(250);
}
i=1;
while(*pb)
{
LCD_Write_Char(i,1,*pb);
i++;
pb++;
DelayMs(250);
}
DelayMs(250);
}
LCD1602
//*******************显示一个字节数据
voidDisplayOneChar(ucharX,ucharY,ucharDData)
{
//Y=1显示第二行,Y=0显示第一行
if(Y)X|=0X40;
X|=0X80;
Lcd1602_Write_Cmd(X);/X用来选择哪位
Lcd1602_Write_Data(DData);//DData用来
写数据
}
//显示一个字节字符
voidDisplayOneStr(ucharX,ucharY,ucharDData)
{
DisplayOneChar(X++,Y,DData/16+'0');
DisplayOneChar(X,Y,DData%16+'0');
}
//显示字符串
voidLcdShowStr(ucharx,uchary,uchar*str)
{
LcdSetCursor(x,y);//当前字符的坐标
while(*str!
=\0')Lcd1602_Write_Data(*str++);
}
voidInitLcd1602()//1602初始化
{
//打开5*8,8位数据
Lcd1602_Write_Cmd(0x38);
Lcd1602_Write_Cmd(0x0c);
Lcd1602_Write_Cmd(0x06);
Lcd1602_Write_Cmd(0x01);//清屏
}
DS1302突发模式些时钟
while
(1)
{
Read_DS1302_Time();//时钟突发模式读
DisplayOneStr(5,0,TimeData[6]);//年
DisplayOneChar(7,0,'-');//-
DisplayOneStr(8,0,TimeData[4]);//月
DisplayOneChar(10,0,'-');//-
DisplayOneStr(11,0,TimeData[3]);//日
DisplayOneChar(13,0,'-');//-
DisplayOneStr(14,0,TimeData[5]);//星期
DisplayOneStr(6,1,TimeData[2]);//时
DisplayOneChar(8,1,':
');//:
DisplayOneStr(9,1,TimeData[1]);//分
DisplayOneChar(11,1,':
');//:
DisplayOneStr(12,1,TimeData[0]);//秒
Delay_Ms(1000);//延时1秒
}
8*8点阵左移显示
while
(1)
{
for(j=0;j<16;j++)
{
for(i=0;i<50;i++)
{
temp=0x7f;
for(k=0;k<16;k++)//一个字母BYTE
{
Send_Byte(temp);//列选择
Send_Byte(Display_word[j+k]);//数据
LEDARRAY_LAT=1;//锁存数据
_nop_();
LEDARRAY_LAT=0;
_nop_();
Temp=(temp>>1)|0x80;
}}}}
红外接受1
voidint0()interrupt0//定义外部中断0
{
staticuchari;
staticbitstartflag;//开始储存脉宽标志位
if(startflag)//开始接收脉宽检测
{
/*判断是否是引导码,底电平9000us+高4500us,这个自己可以算我以11.0592来算了NEC协议的引导码低8000-10000+高4000-5000如果已经接收了引导码那么i不会被置0就会开始依次存入脉宽*/
//如果是引导码那么执行i=0把他存到
//IRdata的第一个位
if((IRtime<53)&&(IRtime>=32))i=0;
/
IRdata[i]=IRtime;//以T0的溢出次数来//计算脉宽,把这个时间//存到数组里面到后面判断
IRtime=0;//计数清零,下一个下降沿的时//候在存入脉宽
i++;//计数脉宽存入的次数
if(i==33)
{
IRok=1;//那么表示脉宽检测完毕
i=0;//把脉宽计数清零准备下次存入
}
}
else
{
IRtime=0;//引导码开始进入把脉宽计数//清零开始计数
s