单片机程序知识点剖析_第1页
单片机程序知识点剖析_第2页
单片机程序知识点剖析_第3页
单片机程序知识点剖析_第4页
单片机程序知识点剖析_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机程序知识点第11页按键扫描支持连续按一般思路u8 KEY_Sca n( void)if(KEY 按下)delay_ms(10); 延时 10-20ms,防抖。 if(KEY 确实按下)return KEY_Value ; return无效值;按键扫描不支持连续按一般思路u8 KEY_Sca n(void)static u8 key_up=1;if ( key_up & KEY 按下)delay_ms(10); 延时,防抖 key_up=0;标记这次key已经按下 if(KEY确实按下)return KEY_V ALUE;else if(KEY 没有按下)key_up=1; return没

2、有按下串口通讯2void UART() in terrupt 4if(RI)检测是否接收完成num = SBUF;/num 取出接收缓存器的值P1 = SBUF;nu m+;RI = 0;SBUF = num;while(!TI);TI = 0;两个等于控制占空比timer0() in terrupt 1t+;/每次定时器溢出加1if(t=250) /PWM 周期 100 个单位t=0;/使t=0,开始新的PWM周期P仁0x00;/输出端口/按照当前占空比切换输出为高电平if(PWM_T=t)P仁 0xff;数码管动态显示un sig ned char codeDua nM a=0x3f,0x

3、06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x 79,0x71;/显示段码值0Fun sig ned char codeWeiMa=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/分别对应相应的数码管点亮,即位码 while(1)DataPort=WeiMai; / 取位码LATCH2=1;/ 位锁存LATCH2=0;/取显示数据,段码DataPort=Dua nM a nu m+i;LATCH1=1;/ 段锁存LATCH 仁0;/扫描间隙延时,时间太长会闪烁,太短 会造成重

4、影Delay(200);i+;/检测8位扫描完全结束?如扫描完成则从第一个开始再次扫描8位if(8=i) i=0;数码管动态显示动态显示消隐方法/*显示函数,用于动态扫描数码管输入参数FirstBit表示需要显示的第 一位,如赋值2表示从第三个数码管开始显 示,如输入0表示从第一个显示。Num表示需要显示的位数,如需要显示 99两位数值则该值输入 2*/存储显示值的数组un sig ned char TempData10;/分解显示信息,如要显示68,则 68/10=668%10=8TempData0=dofly_Dua nM a num/10;TempData1=dofly_Dua nMan

5、u m%10; void Display (un sig ned char FirstBit, un sig ned char Num)un sig ned char i;for(i=0;iNum;i+)DataPort=0; /清空数据,防止有交替重影LATCH1=1;/段锁存LATCH 仁0;DataPort=WeiMai+FirstBit; / 取位码LATCH2=1;/位锁存LATCH2=0;DataPort=TempDatai; / 取显示数据,段码LATCH1=1;/段锁存LATCH 仁0;Delay(200);/扫描间隙延时,时间太长/会闪烁,太短会造成重影if(num1000)

6、 /如果小于1000则千位不显示TempData0=0;elseTempData0=dofly_Dua nM a nu m/1000;/分解显示信息,如要显示68,则68/10=6/ 68%10=8/如果小于100则千位和百位都不显示if(num100) TempData1=0;elseTempData1=dofly_Dua nM a( nu m%1000)/100;/如果小于10,则千位、百位和十位/都不显示if(num10) TempData2=0;elseTempData2=dofly_Dua nM a( num%1000) %100)/10;使用中断实现分频器的功能/*定时器中断子程序

7、*/void Timer0_isr(void) in terrupt 1 using 1static un sig ned char i;重新赋值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,以此类推*/按键行扫描程序/*按键扫描函数,返回扫描键值*/键盘扫描函数,使用行列逐级扫描法un sig ned char KeySca

8、n( void)un sig ned char Val;KeyPort=OxfO;高四位置高,低四位拉低 if(KeyPort!=OxfO)表示有按键按下DelayMs(10); / 去抖 if(KeyPort!=OxfO)表示有按键按下 KeyPort=0xfe; / 检测第一行 if(KeyPort!=0xfe)Val=KeyPort&0xf0;Val+=0x0e; while(KeyPort!=0xfe); DelayMs(10); / 去抖 while(KeyPort!=0xfe); return Val;KeyPort=0xfd; / 检测第二行 if(KeyPort!=0xfd)V

9、al=KeyPort&0xf0;Val+=0x0d; while(KeyPort!=0xfd); DelayMs(10); / 去抖 while(KeyPort!=0xfd); return Val;KeyPort=0xfb; /检测第三行 if(KeyPort!=0xfb)Val=KeyPort&0xf0; Val+=0x0b;/松手检测while(KeyPort!=0xfb);DelayMs(10); / 去抖 while(KeyPort!=0xfb);return Val;KeyPort=0xf7; /检测第四行if(KeyPort!=0xf7)Val=KeyPort&0xf0;Val+

10、=0x07; while(KeyPort!=0xf7);DelayMs(10); / 去抖while(KeyPort!=0xf7); return Val;return 0xff;步进电机1相励磁驱动/A相通电,其他相断电#defi ne oil_A1 A仁 1;B1=0;C1=0;D 仁0;/B相通电,其他相断电#defi ne Coil_B1 A仁 0;B1=1;C1=0;D 仁0;/C相通电,其他相断电#defi ne Coil_C1 A仁 0;B1=0;C1=1;D 仁0;/D相通电,其他相断电#defi ne Coil_D1A 仁0;B1=0;C1=0;D 仁1; 全部断电#defi

11、 ne Coil_OFF A仁 0;B1=0;C1=0;D 仁0; while(1)Coil_A1/改变以下参数可以调整电机转速,数字越小,转速越大,力矩越小DelayMs(Speed);Coil_B1DelayMs(Speed);Coil_C1DelayMs(Speed);Coil_D1 DelayMs(Speed);步进电机1-2相励磁驱动if(times=Speed)times=0;switch(i)case 0:Coil_A1;i+;break;case 1:Coil_AB1;i+;break;case 2:Coil_B1;i+;break;case 3:Coil_BC1;i+;bre

12、ak;case 4:Coil_C1;i+;break;case 5:Coil_CD1;i+;break;case 6:Coil_D1;i+;break;case 7:Coil_DA1;i+;break;case 8:i=0;break;default:break;else times+;电机按键控制sbit DCOUT1 = P1A1;/电机信号输出端口 1 switch( num)/电机1改变运行状态,数码管显示运行状态case 1:DC0UT仁!DC0UT1;TempData0=0x5E; dTempData1=0x39; CTempData2=0x06; 1if(DC0UT1)TempD

13、ata5=0x3F; /OTempData6=0x54; nTempData7=0;elseTempData5=0x3F; /OTempData6=0x71; FTempData7=0x71; Fbreak;LCD1602*/判断液晶忙,如果忙则等待void Read_Busy()uchar busy;P0 = 0xff;RS = 0;RW = 1;doEN = 1;busy = P0;EN = 0;while(busy & 0x80);/写LCD1602命令一个字节 void Write_Cmd(uchar cmd) Read_Busy(); 判断忙RS = 0;RW = 0;P0 = cm

14、d;EN = 1;EN = 0;/写一个字节数据void Write_Dat(uchar dat)Read_Busy();RS = 1;RW = 0;P0 = dat;EN = 1;EN = 0;LCD1602/*判忙函数*/bit LCD_Check_Busy(void)DataPort= OxFF;RS_CLR;RW_SET;EN_CLR;_no p_();EN_SET;return (bit)(DataPort & 0x80);/*写入命令函数*/void LCD_Write_Com (un sig ned char com)while(LCD_Check_Busy(); / 忙则等待D

15、elayMs(5);RS_CLR;RW_CLR;EN_SET;DataPort= com;_no p_();EN_CLR;/*写入数据函数*/void LCD_Write_Data(u nsig ned char Data) while(LCD_Check_Busy(); / 忙则等待 DelayMs(5);RS_SET;RW_CLR;EN_SET;DataPort= Data;_no p_();EN_CLR;/*写入字符串函数*/void LCD_Write_Stri ng(uchar x,uchar y,uchar *s)if (y = 0) LCD_Write_Com(0x80 + x)

16、;else CD_Write_Com(0xC0 + x);while (*s)LCD_Write_Data( *s);s +;/*写入字符函数 */void LCD_Write_Char(uchar x,uchar y,uchar Data)if (y = 0) LCD_Write_Com(0x80 + x); else LCD_Write_Com(OxCO + x); LCD_Write_Data( Data);LCD1602键盘输入显示while (1)num=KeyPro();if(n um!=0xff)if(i=0)&(j=0)/回到第一个字符时清屏 LCD_Clear(); 清屏/依

17、次显示输入字符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 i = 1;p = www.doflye. net;LCD_Clear();LCD_Write_Stri ng(2,0,Welcome to);DelayMs(250);while (*p)LCD_Write_Char(i,1,*p);i +;p +;DelayMs(250);DelayMs(250);LCD602滚动显示void ma

18、i n(void)LCD_I nit();LCD_Clear(); 清屏LCD_Write_Char(7,0,o);LCD_Write_Char(8,0,k);LCD_Write_Stri ng(1,1,www.doflye. net); while (1)DelayMs(200);LCD_Write_Com(0x18); / 左平移画面 /0x1C是右平移LCD1602平移显示while (1)pa = Welcome to;pb = www.doflye. net;LCD_Clear();LCD_Write_String(2,0,pa); / 显示 2 行信息LCD_Write_Stri

19、ng(1,1,pb);for(i=0;i8;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/*显示一个字节数据void Display On eChar (uchar X,uchar Y ,uchar DData)/Y=1显示第二行,Y=

20、0显示第一行if(Y) X|=0X40;X|=0X80;Lcd1602_Write_Cmd(X); /X 用来选择哪位Lcd1602_Write_Data(DData); /DData 用来 写数据 /显示一个字节字符void Display On eStr (uchar X,uchar Y ,uchar DData)DisplayOneChar (X+,Y ,DData/16 + 0);Display On eChar (X,Y ,DData%16 + 0);/显示字符串void LcdShowStr(uchar x,uchar y,uchar *str) LcdSetCursor(x,y)

21、; /当前字符的坐标 while(*str !=0)Lcd1602_Write_Data(*str+); void InitLcd1602()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();时钟突发模式读 Display On eStr (5,0,TimeData6); / 年 DisplayO neChar (7,0,-);/

22、-Display On eStr (8,0,TimeData4); / 月 DisplayO neChar (10,0,-);/-DisplayOneStr (11,0,TimeData3); 日 DisplayO neChar (13,0,-);/-DisplayOneStr (14,0,TimeData5); 星期 Display On eStr (6,1,TimeData2); / 时 DisplayO neChar (8,1,:);/:DisplayOneStr (9,1,TimeData1); / 分 DisplayO neChar (11,1,:);/:DisplayOneStr

23、(12,1,TimeData0); 秒 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 Sen d_Byte(temp);列选择Se nd_Byte(Display_wordj+k);/ 数据LEDARRAY_LAT = 1;/ 锁存数据_no p_();LEDARRAY_LAT = 0;_no p_();Temp = (temp1)|0x80;红外接受1void in t0() in

24、terrupt 0/ 定义外部中断 0static uchar i;static bit startflag;/开始储存脉宽标志位if(startflag)开始接收脉宽检测/*判断是否是引导码,底电平 9000us+高/ IRdata的第一个位if( (IRtime = 32) )i = 0;/IRdatai = IRtime; /以T0的溢出次数来/计算脉宽,把这个时间/存到数组里面到后面判断IRtime = 0;/计数清零,下一个下降沿的时/候在存入脉宽i+;/计数脉宽存入的次数if(i = 33)IRok = 1;/那么表示脉宽检测完毕i = 0;把脉宽计数清零准备下次存入elseIRt

25、ime = 0; /引导码开始进入把脉宽计数/清零开始计数startflag = 1;/开始处理标志位置1提取它的33次脉宽进行数据解码void IRcordpro()uchar i, j, k, cord, value;k = 1;从第一位脉宽开始取丢弃引导码脉宽for(i = 0; i 4; i+)for(j = 0; j 5) value = value | 0x80;4500us,这个自己可以算我以 11.0592来算了 NEC协议的引导码低 8000-10000+高4000-5000如果已经接收了引导码那么 i不 会被置0就会开始依次存入脉宽*/如果是引导码那么执行i=0把他存到/v

26、alue位左移依次接 收8位数据。if(j 1;k+; 每执行一次脉宽位加1IRcordi = value;。value = 0;/清零value方便下次在存入数据 IRpro_ok = 1;/ 接收完 4 个字节后 IRpro ok/置1表示红外解码完成数据转字符在1602显示char code Tab16=0123456789ABCDEF;void Ir_work(void)/处理客户码TempData0 = TabIRcord0/16;TempData1 = TabIRcord0%16;TempData2=-;/处理客户码TempData3 = TabIRcord1/16;TempDat

27、a4 = TabIRcord1%16;TempData5=-;/处理数据码TempData6 = TabIRcord2/16;TempData7 = TabIRcord2%16;TempData8=-;/处理数据反码TempData9 = TabIRcord3/16; TempData10 = TabIRcord3%16;LCD_Write_Stri ng(5,1,TempData);irpro_ok=0;/处理完成标志8*8点阵流动显示while(1)for(k=0;k0;l-)for(i=0;i=7;i+)8 列显示Se ndSeg(segout7-i);/写入字节方向改变Se nd2Byte(*(tab+i+k),0xff,1);Out595();DelayMs(1);Se nd2Byte(0xff,0xff,0);/delay(10);防止重影Out595();串口通讯1/*发送一个字节*/void Sen dByte( un sig ned char dat)SBUF = dat;while(!TI);TI = 0

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论