还剩57页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例《单片机C语言程序设计实训100例—基于8051+Proteus仿真》案例第01篇基础程序设计01闪烁的LED/*名称闪烁的LED说明LED按设定的时间间隔闪烁*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED=P1^0;//延时voidDelayMSuintx{uchari;whilex--{fori=0;i120;i++;}}//主程序voidmain{while1{LED=~LED;DelayMS150;}}02从左到右的流水灯/*名称从左到右的流水灯说明接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint上海师范大学信息与机电工程学院—倪继锋1//延时voidDelayMSuintx{uchari;whilex--{《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}}fori=0;i120;i++;//主程序voidmain{P0=0xfe;while1{P0=_crol_P01;//P0的值向左循环移动DelayMS150;}}038只LED左右来回点亮/*名称8只LED左右来回点亮说明程序利用循环移位函数_crol_和_cror_形成来回滚动的效果*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//延时voidDelayMSuintx{uchari;whilex--{fori=0;i120;i++;}}//主程序voidmain{uchari;P2=0x01;while1{上海师范大学信息与机电工程学院—倪继锋2}}《单片机C语言程序设计实训100例---基于fori=0;i7;i++{P2=_crol_P21;//P2的值向左循环移动DelayMS150;}fori=0;i7;i++{P2=_cror_P21;//P2的值向右循环移动DelayMS150;}8051和PROTEUS仿真》案例04花样流水灯/*名称花样流水灯说明16只LED分两组按预设的多种花样变换显示*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintucharcodePattern_P0[]={0xfc0xf90xf30xe70xcf0x9f0x3f0x7f0xff0xff0xff0xff0xff0xff0xff0xff0xe70xdb0xbd0x7e0xbd0xdb0xe70xff0xe70xc30x810x000x810xc30xe70xff0xaa0x550x180xff0xf00x0f0x000xff0xf80xf10xe30xc70x8f0x1f0x3f0x7f0x7f0x3f0x1f0x8f0xc70xe30xf10xf80xff0x000x000xff0xff0x0f0xf00xff0xfe0xfd0xfb0xf70xef0xdf0xbf0x7f0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0x7f0xbf0xdf0xef0xf70xfb0xfd0xfe0xfe0xfc0xf80xf00xe00xc00x800x000x000x000x000x000x000x000x000x000x000x000x000x000x000x000x000x000x000x800xc00xe00xf00xf80xfc0xfe0x000xff0x000xff0x000xff0x000xff};ucharcodePattern_P2[]={0xff0xff0xff0xff0xff0xff0xff0xfe0xfc0xf90xf30xe70xcf0x9f0x3f0xff0xe70xdb0xbd0x7e0xbd0xdb0xe70xff0xe70xc30x810x000x810xc30xe70xff0xaa0x550x180xff0xf00x0f0x000xff0xf80xf10xe30xc70x8f0x1f0x3f0x7f0x7f0x3f0x1f0x8f0xc70xe30xf10xf80xff0x000x000xff0xff0x0f0xf00xff0xff0xff0xff0xff0xff0xff0xff0xff0xfe0xfd0xfb0xf70xef0xdf0xbf0x7f0x7f0xbf0xdf0xef0xf70xfb0xfd0xfe0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xff0xfe0xfc0xf80xf00xe00xc00x800x000x000x800xc00xe00xf00xf80xfc0xfe0xff0xff0xff0xff0xff0xff0xff0xff上海师范大学信息与机电工程学院—倪继锋3《单片机C语言程序设计实训100例---基于0x000xff0x000xff0x000xff0x000xff};//延时voidDelayMSuintx{uchari;whilex--{fori=0;i120;i++;}}//主程序voidmain{uchari;while1{//从数组中读取数据送至P0和P2口显示fori=0;i136;i++{P0=Pattern_P0[i];P2=Pattern_P2[i];DelayMS100;}}}05LED模拟交通灯/*名称LED模拟交通灯说明东西向绿灯亮若干秒,黄灯闪烁5次后红灯亮,红灯亮后,南北向由红灯变为绿灯,若干秒后南北向黄灯闪烁5此后变红灯,东西向变绿灯,如此重复*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitRED_A=P0^0;//东西向灯sbitYELLOW_A=P0^1;sbitGREEN_A=P0^2;sbitRED_B=P0^3;//南北向灯sbitYELLOW_B=P0^4;sbitGREEN_B=P0^5;8051和PROTEUS仿真》案例ucharFlash_Count=0Operation_Type=1;//闪烁次数,操作类型变量上海师范大学信息与机电工程学院—倪继锋4//延时voidDelayMSuintx{uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}whilex--fori=0;i120;i++;//交通灯切换voidTraffic_Light{switchOperation_Type{case1://东西向绿灯与南北向红灯亮RED_A=1;YELLOW_A=1;GREEN_A=0;RED_B=0;YELLOW_B=1;GREEN_B=1;DelayMS2000;Operation_Type=2;break;case2://东西向黄灯闪烁,绿灯关闭DelayMS300;YELLOW_A=~YELLOW_A;GREEN_A=1;if++Flash_Count!=10return;//闪烁5次Flash_Count=0;Operation_Type=3;break;case3://东西向红灯,南北向绿灯亮RED_A=0;YELLOW_A=1;GREEN_A=1;RED_B=1;YELLOW_B=1;GREEN_B=0;DelayMS2000;Operation_Type=4;break;case4://南北向黄灯闪烁5次DelayMS300;YELLOW_B=~YELLOW_B;GREEN_B=1;if++Flash_Count!=10return;Flash_Count=0;Operation_Type=1;}}//主程序voidmain{while1Traffic_Light;}06单只数码管循环显示0~9上海师范大学信息与机电工程学院—倪继锋5《单片机C语言程序设计实训100例---基于/*名称单只数码管循环显示0~98051和PROTEUS仿真》案例*/说明主程序中的循环语句反复将0~9的段码送至P0口,使数字0~9循环显示#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xff};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//主程序voidmain{uchari=0;P0=0x00;while1{P0=~DSY_CODE[i];i=i+1%10;DelayMS300;}}078只数码管滚动显示单个数字/*名称8只数码管滚动显示单个数字说明数码管从左到右依次滚动显示0~7,程序通过每次仅循环选通一只数码管*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x90};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;上海师范大学信息与机电工程学院—倪继锋6}//主程序voidmain{《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}uchariwei=0x80;while1{fori=0;i8;i++{P2=0xff;//关闭显示wei=_crol_wei1;P0=DSY_CODE[i];发送数字段码P2=wei;//发送位码DelayMS300;}}088只数码管动态显示多个不同字符/*名称8只数码管动态显示多个不同字符说明数码管动态扫描显示0~7*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint电路如上图ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x90};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//主程序voidmain{uchariwei=0x80;while1{fori=0;i8;i++{P0=0xff;P0=DSY_CODE[i];发送段码wei=_crol_wei1;上海师范大学信息与机电工程学院—倪继锋7}}}《单片机C语言程序设计实训100例---基于P2=wei;//发送位码DelayMS2;8051和PROTEUS仿真》案例098只数码管闪烁显示数字串/*名称8只数码管闪烁显示数字串电路如上图*/说明数码管闪烁显示由0~7构成的一串数字本例用动态刷新法显示一串数字,在停止刷新时所有数字显示消失#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//段码表ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x90};//位码表ucharcodeDSY_IDX[]={0x010x020x040x080x100x200x400x80};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//主程序voidmain{ucharij;while1{fori=0;i30;i++{forj=0;j8;j++{P0=0xff;P0=DSY_CODE[j];//发送段码P2=DSY_IDX[j];//发送位码DelayMS2;}}P2=0x00;//关闭所有数码管并延时DelayMS1000;}}上海师范大学信息与机电工程学院—倪继锋8《单片机C语言程序设计实训100例---基于108只数码管滚动显示数字串电路如上图/*名称8只数码管滚动显示数字串说明数码管向左滚动显示3个字符构成的数字串*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//段码表8051和PROTEUS仿真》案例ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xff};//下面数组看作环形队列,显示从某个数开始的8个数(10表示黑屏)ucharNum[]={1010101010101010298};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//主程序voidmain{ucharijk=0m=0x80;while1{//刷新若干次,保持一段时间的稳定显示fori=0;i15;i++{forj=0;j8;j++{//发送段码,采用环形取法,从第k个开始取第j个P0=0xff;P0=DSY_CODE[Num[k+j%11]];m=_crol_m1;P2=m;//发送位码DelayMS2;}}k=k+1%11;//环形队列首支针k递增,Num下标范围0~10,故对11取余}}11K1-K4控制LED移位/*名称K1-K4控制LED移位说明按下K1时,P0口LED上移一位;上海师范大学信息与机电工程学院—倪继锋9*/《单片机C语言程序设计实训100例---基于按下K2时,P0口LED下移一位;按下K3时,P2口LED上移一位;按下K4时,P2口LED下移一位;8051和PROTEUS仿真》案例#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}//根据P1口的按键移动LEDvoidMove_LED{ifP10x10==0P0=_cror_P01;//K1elseifP10x20==0P0=_crol_P01;//K2elseifP10x40==0P2=_cror_P21;//K3elseifP10x80==0P2=_crol_P21;//K4}//主程序voidmain{ucharRecent_Key;最近按键P0=0xfe;P2=0xfe;P1=0xff;Recent_Key=0xff;while1{ifRecent_Key!=P1{Recent_Key=P1;//保存最近按键Move_LED;DelayMS10;}}}12K1-K4按键状态显示上海师范大学信息与机电工程学院—倪继锋10《单片机C语言程序设计实训100例---基于/*名称K1-K4按键状态显示说明K
1、K2按下时LED点亮,松开时熄灭,8051和PROTEUS仿真》案例*/K
3、K4按下并释放时LED点亮,再次按下并释放时熄灭;#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED1=P0^0;sbitLED2=P0^1;sbitLED3=P0^2;sbitLED4=P0^3;sbitK1=P1^0;sbitK2=P1^1;sbitK3=P1^2;sbitK4=P1^3;//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}//主程序voidmain{P0=0xff;P1=0xff;while1{LED1=K1;LED2=K2;ifK3==0{whileK3==0;LED3=~LED3;}ifK4==0{whileK4==0;LED4=~LED4;}DelayMS10;}}13K1-K4分组控制LED上海师范大学信息与机电工程学院—倪继锋11《单片机C语言程序设计实训100例---基于/*名称K1-K4分组控制LED8051和PROTEUS仿真》案例*/说明每次按下K1时递增点亮一只LED,全亮时再次按下则再次循环开始,K2按下后点亮上面4只LED,K3按下后点亮下面4只LED,K4按下后关闭所有LED#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}//主程序voidmain{ucharktKey_State;P0=0xff;P1=0xff;while1{t=P1;ift!=0xff{DelayMS10;ift!=P1continue;//取得4位按键值,由模式XXXX1111X中有一位为0,其他均为1//变为模式0000XXXXX中有一位为1,其他均为0Key_State=~t4;k=0;//检查1所在位置,累加获取按键号kwhileKey_State!=0{k++;Key_State=1;}//根据按键号k进行4种处理switchk{case1:ifP0==0x00P0=0xff;P0=1;DelayMS200;break;case2:P0=0xf0;break;上海师范大学信息与机电工程学院—倪继锋12}}}}《单片机C语言程序设计实训100例---基于case3:P0=0x0f;break;case4:P0=0xff;8051和PROTEUS仿真》案例14K1-K4控制数码管移位显示/*名称K1-K4控制数码管移位显示说明按下K1时加1计数并增加显示位,按下K2时减1计数并减少显示位,按下K3时清零*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//段码ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xff};//位码ucharcodeDSY_Index[]={0x800x400x200x100x080x040x020x01};//待显示到各数码管的数字缓冲(开始仅在0位显示0,其他黑屏)ucharDisplay_Buffer[]={010101010101010};//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}voidShow_Count_ON_DSY{uchari;fori=0;i8;i++{P0=0xff;P0=DSY_CODE[Display_Buffer[i]];P2=DSY_Index[i];DelayMS2;}}//主程序voidmain{uchariKey_NOKey_Counts=0;上海师范大学信息与机电工程学院—倪继锋13P0=0xff;P1=0xff;P2=0x00;while1{《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}}Show_Count_ON_DSY;P1=0xff;Key_NO=P1;//P1口按键状态分别为K1-0xfe,K2-0xfdK3-0xfbswitchKey_NO{case0xfe:Key_Counts++;ifKey_Counts8Key_Counts=8;Display_Buffer[Key_Counts-1]=Key_Counts;break;case0xfd:ifKey_Counts0Display_Buffer[--Key_Counts]=10;break;case0xfb:Display_Buffer
[0]=0;fori=1;i8;i++Display_Buffer[i]=10;Key_Counts=0;}//若键未释放则仅刷新显示,不进行键扫描whileP1!=0xffShow_Count_ON_DSY;15K1-K4控制数码管加减演示/*名称K1-K4控制数码管加减演示说明按下K1后加1计数,按下K2后减1计数,按下K3后清零*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//段码ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xff};//待显示的3位缓冲ucharNum_Buffer[]={000};//按键代码,按键计数ucharKey_CodeKey_Counts=0;//延时voidDelayMSuintx{上海师范大学信息与机电工程学院—倪继锋14uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}whilex--fori=0;i120;i++;//显示函数voidShow_Counts_ON_DSY{ucharij=0x01;Num_Buffer
[2]=Key_Counts/100;Num_Buffer
[1]=Key_Counts/10%10;Num_Buffer
[0]=Key_Counts%10;fori=0;i3;i++{j=_cror_j1;P0=0xff;P0=DSY_CODE[Num_Buffer[i]];P2=j;DelayMS1;}}//主程序voidmain{uchari;P0=0xff;P1=0xff;P2=0x00;Key_Code=0xff;while1{Show_Counts_ON_DSY;P1=0xff;Key_Code=P1;//有键按下时,数码管刷新显示30次,该行代码同时起到延时作用ifKey_Code!=0xfffori=0;i30;i++Show_Counts_ON_DSY;switchKey_Code{case0xfe:ifKey_Counts255Key_Counts++;break;case0xfd:ifKey_Counts0Key_Counts--;break;case0xfb:Key_Counts=0;}Key_Code=0xff;}上海师范大学信息与机电工程学院—倪继锋15}《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例164X4矩阵键盘控制条形LED显示/*名称4X4矩阵键盘控制条形LED显示说明运行本例时,按下的按键值越大点亮的LED越多*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//矩阵键盘按键特征码表ucharcodeKeyCodeTable[]={0x110x120x140x180x210x220x240x280x410x420x440x480x810x820x840x88};//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}//键盘扫描ucharKeys_Scan{ucharsCodekCodeik;//低4位置0,放入4行P1=0xf0;//若高4位出现0,则有键按下ifP10xf0!=0xf0{DelayMS2;ifP10xf0!=0xf0{sCode=0xfe;//行扫描码初值fork=0;k4;k++//对4行分别进行扫描{P1=sCode;ifP10xf0!=0xf0{kCode=~P1;fori=0;i16;i++//查表得到按键序号并返回ifkCode==KeyCodeTable[i]上海师范大学信息与机电工程学院—倪继锋16}《单片机C语言程序设计实训100例---基于returni;8051和PROTEUS仿真》案例}}}elsesCode=_crol_sCode1;}return-1;//主程序voidmain{uchariP2_LEDP3_LED;ucharKeyNo=-1;//按键序号,-1表示无按键while1{KeyNo=Keys_Scan;//扫描键盘获取按键序号KeyNoifKeyNo!=-1{P2_LED=0xff;P3_LED=0xff;fori=0;i=KeyNo;i++键值越大,点亮的LED越多{ifi8P3_LED=1;elseP2_LED=1;}P3=P3_LED;//点亮条形LEDP2=P2_LED;}}}17数码管显示4X4矩阵键盘按键号/*名称数码管显示4X4矩阵键盘按键号说明按下任意键时,数码管都会显示其键的序号,扫描程序首先判断按键发生在哪一列,然后根据所发生的行附加不同的值,从而得到按键的序号*/上海师范大学信息与机电工程学院—倪继锋17#includereg
51.h《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例#defineucharunsignedchar#defineuintunsignedint//段码ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900x880x830xc60xa10x860x8e0x00};sbitBEEP=P3^7;//上次按键和当前按键的序号,该矩阵中序号范围0~15,16表示无按键ucharPre_KeyNo=16KeyNo=16;//延时voidDelayMSuintx{uchari;whilex--fori=0;i120;i++;}//矩阵键盘扫描voidKeys_Scan{ucharTmp;P1=0x0f;//高4位置0,放入4行DelayMS1;Tmp=P1^0x0f;//按键后0f变成0000XXXX,X中一个为0,3个仍为1,通过异或把3个1变为0,唯一的0变为1switchTmp//判断按键发生于0~3列的哪一列{case1:KeyNo=0;break;case2:KeyNo=1;break;case4:KeyNo=2;break;case8:KeyNo=3;break;default:KeyNo=16;//无键按下}P1=0xf0;//低4位置0,放入4列DelayMS1;Tmp=P14^0x0f;//按键后f0变成XXXX0000,X中有1个为0,三个仍为1;高4位转移到低4位并异或得到改变的值switchTmp//对0~3行分别附加起始值0,4,8,12{case1:KeyNo+=0;break;case2:KeyNo+=4;break;case4:KeyNo+=8;break;case8:KeyNo+=12;}}//蜂鸣器voidBeep18上海师范大学信息与机电工程学院—倪继锋{uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}fori=0;i100;i++{DelayMS1;BEEP=~BEEP;}BEEP=0;//主程序voidmain{P0=0x00;BEEP=0;while1{P1=0xf0;ifP1!=0xf0Keys_Scan;//获取键序号ifPre_KeyNo!=KeyNo{P0=~DSY_CODE[KeyNo];Beep;Pre_KeyNo=KeyNo;}DelayMS100;}}18开关控制LED/*名称开关控制LED说明开关S1和S2分别控制LED1和LED2*/#includereg
51.hsbitS1=P1^0;sbitS2=P1^1;sbitLED1=P0^0;sbitLED2=P0^1;//主程序voidmain{while1{LED1=S1;上海师范大学信息与机电工程学院—倪继锋19}}LED2=S2;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例19继电器控制照明设备/*名称继电器控制照明设备说明按下K1灯点亮,再次按下时灯熄灭*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitK1=P1^0;sbitRELAY=P2^4;//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//主程序voidmain{P1=0xff;RELAY=1;while1{ifK1==0{whileK1==0;RELAY=~RELAY;DelayMS20;}}}20数码管显示拨码开关编码/*名称数码管显示拨码开关编码说明系统显示拨码开关所设置的编码000~255*/#includereg
51.h#includeintrins.h#defineucharunsignedchar上海师范大学信息与机电工程学院—倪继锋20《单片机C语言程序设计实训100例---基于#defineuintunsignedint//各数字的数码管段码(共阴)8051和PROTEUS仿真》案例ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f};//显示缓冲ucharDSY_Buffer
[3]={000};//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//主程序voidmain{ucharimNum;P0=0xff;P2=0xff;while1{m=0xfe;Num=P1;//读取拨码开关的值DSY_Buffer
[0]=Num/100;DSY_Buffer
[1]=Num/10%10;DSY_Buffer
[2]=Num%10;fori=0;i3;i++//刷新显示在数码管上{m=_crol_m1;P2=m;P0=DSY_CODE[DSY_Buffer[i]];DelayMS10;}}}21开关控制报警器/*名称开关控制报警器说明用K1开关控制报警器,程序控制P
1.0输出两种不同频率的声音,模拟很逼真的报警效果*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitSPK=P1^0;sbitK1=P1^7;//发声函数上海师范大学信息与机电工程学院—倪继锋21voidAlarmuchart{ucharij;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}fori=0;i200;i++{SPK=~SPK;forj=0;jt;j++;//由参数t行成不同的频率}voidmain{SPK=0;while1{ifK1==1{Alarm90;Alarm120;}}}22按键发音/*名称按键发音说明按下不同的按键会是SOUNDER发出不同频率的声音本例使用延时函数实现不同频率的声音输出,以后也可使用定时器*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitBEEP=P3^7;sbitK1=P1^4;sbitK2=P1^5;sbitK3=P1^6;sbitK4=P1^7;//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//按周期t发音voidPlayuchart{22上海师范大学信息与机电工程学院—倪继锋uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}fori=0;i100;i++{BEEP=~BEEP;DelayMSt;}BEEP=0;voidmain{P1=0xff;BEEP=0;while1{ifK1==0Play1;ifK2==0Play2;ifK3==0Play3;ifK4==0Play4;}}23播放音乐/*名称播放音乐说明程序运行时播放生日快乐歌,未使用定时器中断,所有频率完全用延时实现*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitBEEP=P3^7;//生日快乐歌的音符频率表,不同频率由不同的延时来决定ucharcodeSONG_TONE[]={2122121902121591692122121902121421592122121061261591691901191191261591421590};//生日快乐歌节拍表,节拍决定每个音符的演奏长短ucharcodeSONG_LONG[]={9312121224931212122493121212121293121212240};//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//播放函数voidPlayMusic{上海师范大学信息与机电工程学院—倪继锋23uinti=0jk;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}whileSONG_LONG[i]!=0||SONG_TONE[i]!=0{//播放各个音符,SONG_LONG为拍子长度forj=0;jSONG_LONG[i]*20;j++{BEEP=~BEEP;//SONG_TONE延时表决定了每个音符的频率fork=0;kSONG_TONE[i]/3;k++;}DelayMS10;i++;}voidmain{BEEP=0;while1{PlayMusic;//播放生日快乐DelayMS500;//播放完后暂停一段时间}}24INT0中断计数/*名称INT0中断计数说明每次按下计数键时触发INT0中断,中断程序累加计数,计数值显示在3只数码管上,按下清零键时数码管清零*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//0~9的段码ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f0x00};//计数值分解后各个待显示的数位ucharDSY_Buffer[]={000};ucharCount=0;sbitClear_Key=P3^6;//数码管上显示计数值voidShow_Count_ON_DSY{DSY_Buffer
[2]=Count/100;//获取3个数上海师范大学信息与机电工程学院—倪继锋24《单片机C语言程序设计实训100例---基于DSY_Buffer
[1]=Count%100/10;DSY_Buffer
[0]=Count%10;ifDSY_Buffer
[2]==0//高位为0时不显示{DSY_Buffer
[2]=0x0a;8051和PROTEUS仿真》案例}ifDSY_Buffer
[1]==0//高位为0,若第二位为0同样不显示DSY_Buffer
[1]=0x0a;}P0=DSY_CODE[DSY_Buffer
[0]];P1=DSY_CODE[DSY_Buffer
[1]];P2=DSY_CODE[DSY_Buffer
[2]];//主程序voidmain{P0=0x00;P1=0x00;P2=0x00;IE=0x81;//允许INT0中断IT0=1;while1{//下降沿触发}}ifClear_Key==0Count=0;//清0Show_Count_ON_DSY;//INT0中断函数voidEX_INT0interrupt0{Count++;计数值递增}25外部INT0中断控制LED/*名称外部INT0中断控制LED说明每次按键都会触发INT0中断,中断发生时将LED状态取反,产生LED状态由按键控制的效果*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED=P0^0;//主程序voidmain上海师范大学信息与机电工程学院—倪继锋25{}LED=1;EA=1;EX0=1;IT0=1;while1;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例//INT0中断函数voidEX_INT0interrupt0{LED=~LED;LED亮灭}26INT0及INT1中断计数/*名称INT0及INT1中断计数说明每次按下第1个计数键时,第1组计数值累加并显示在右边3只数码管上,每次按下第2个计数键时,第2组计数值累加并显示在左边3只数码管上,后两个按键分别清零*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitK3=P3^4;//2个清零键sbitK4=P3^5;//数码管段码与位码ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xff};ucharcodeDSY_Scan_Bits[]={0x200x100x080x040x020x01};//2组计数的显示缓冲,前3位一组,后3位一组uchardataBuffer_Counts[]={000000};uintCount_ACount_B=0;//延时voidDelayMSuintx{uchart;whilex--fort=0;t120;t++;}//数据显示voidShow_Counts{uchari;Buffer_Counts
[2]=Count_A/100;Buffer_Counts
[1]=Count_A%100/10;Buffer_Counts
[0]=Count_A%10;上海师范大学信息与机电工程学院—倪继锋26{}《单片机C语言程序设计实训100例---基于ifBuffer_Counts
[2]==0Buffer_Counts
[2]=0x0a;ifBuffer_Counts
[1]==0Buffer_Counts
[1]=0x0a;8051和PROTEUS仿真》案例}Buffer_Counts
[5]=Count_B/100;Buffer_Counts
[4]=Count_B%100/10;Buffer_Counts
[3]=Count_B%10;ifBuffer_Counts
[5]==0{Buffer_Counts
[5]=0x0a;ifBuffer_Counts
[4]==0Buffer_Counts
[4]=0x0a;}fori=0;i6;i++{P2=DSY_Scan_Bits[i];P1=DSY_CODE[Buffer_Counts[i]];DelayMS1;}//主程序voidmain{IE=0x85;PX0=1;中断优先IT0=1;IT1=1;while1{ifK3==0Count_A=0;ifK4==0Count_B=0;Show_Counts;}}//INT0中断函数voidEX_INT0interrupt0{Count_A++;}//INT1中断函数voidEX_INT1interrupt2{Count_B++;上海师范大学信息与机电工程学院—倪继锋27}《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例27定时器控制单只LED/*名称定时器控制单只LED说明LED在定时器的中断例程控制下不断闪烁*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED=P0^0;ucharT_Count=0;//主程序voidmain{TMOD=0x00;//定时器0工作方式0TH0=8192-5000/32;//5ms定时TL0=8192-5000%32;}IE=0x82;TR0=1;while1;//允许T0中断//T0中断函数voidLED_Flashinterrupt1{TH0=8192-5000/32;//恢复初值TL0=8192-5000%32;if++T_Count==100//
0.5s开关一次LED{LED=~LED;T_Count=0;}}28TIMER0控制流水灯/*名称TIMER0控制流水灯说明定时器控制P
0、P2口的LED滚动显示,本例未使用中断函数*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint上海师范大学信息与机电工程学院—倪继锋28//主程序voidmain{《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例ucharT_Count=0;P0=0xfe;P2=0xfe;TMOD=0x01;//定时器0工作方式1TH0=65536-40000/256;//40ms定时TL0=65536-40000%256;TR0=1;while1{ifTF0==1{TF0=0;//启动定时器}}}TH0=65536-40000/256;//恢复初值TL0=65536-40000%256;if++T_Count==5{P0=_crol_P01;P2=_crol_P21;T_Count=0;}29定时器控制4个LED滚动闪烁/*名称定时器控制4个LED滚动闪烁说明4只LED在定时器控制下滚动闪烁*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitB1=P0^0;sbitG1=P0^1;sbitR1=P0^2;sbitY1=P0^3;uintijk;//主程序voidmain{i=j=k=0;P0=0xff;上海师范大学信息与机电工程学院—倪继锋29}《单片机C语言程序设计实训100例---基于TMOD=0x02;//定时器0工作方式2TH0=256-200;//200us定时TL0=256-200;IE=0x82;TR0=1;//启动定时器while1;8051和PROTEUS仿真》案例//T0中断函数voidLED_Flash_and_Scrollinterrupt1{if++k35return;//定时中断若干次后执行闪烁k=0;switchi{case0:B1=~B1;break;case1:G1=~G1;break;case2:R1=~R1;break;case3:Y1=~Y1;break;default:i=0;}if++j300return;//每次闪烁持续一段时间j=0;P0=0xff;关闭显示i++;//切换到下一个LED}30T0控制LED实现二进制计数/*名称T0控制LED实现二进制计数说明本例对按键的计数没有使用查询法,没有使用外部中断函数,没有使用定时或计数中断函数而是启用了计数器,连接在T0引脚的按键每次按下时,会使计数寄存器的值递增,其值通过LED以二进制形式显示*/#includereg
51.h//主程序voidmain{TMOD=0x05;定时器0为计数器,工作方式1,最大计数值65535TH0=0;//初值为0TL0=0;TR0=1;while1//启动定时器30上海师范大学信息与机电工程学院—倪继锋}{}P1=TH0;P2=TL0;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例31TIMER0与TIMER1控制条形LED/*名称TIMER0与TIMER1控制条形LED说明定时器T0定时控制上一组条形LED,滚动速度较快定时器T1定时控制下一组条形LED,滚动速度较慢*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintuchartc0=0tc1=0;//主程序voidmain{P0=0xfe;P2=0xfe;TMOD=0x11;//定时器
0、定时器1均工作于方式1TH0=65536-15000/256;TL0=65536-15000%256;TH1=65536-50000/256;TL1=65536-50000%256;IE=0x8a;//定时器015ms//定时器150ms}TR0=1;TR1=1;while1;//启动定时器//T0中断函数voidTime0interrupt1{TH0=65536-15000/256;TL0=65536-15000%256;//恢复定时器0初值}{}if++tc0==10tc0=0;P0=_crol_P01;//150ms转换状态//T1中断函数上海师范大学信息与机电工程学院—倪继锋31《单片机C语言程序设计实训100例---基于voidTime1interrupt3{TH0=65536-50000/256;//恢复定时器1初值TL0=65536-50000%256;if++tc1==10//500ms转换状态{tc1=0;P2=_crol_P21;}}3210s的秒表/*名称10s的秒表8051和PROTEUS仿真》案例*/说明首次按键计时开始,再次按键暂停,第三次按键清零#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitK1=P3^7;uchariSecond_CountsKey_Flag_Idx;bitKey_State;ucharDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f};//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//处理按键事件voidKey_Event_Handle{ifKey_State==0{Key_Flag_Idx=Key_Flag_Idx+1%3;switchKey_Flag_Idx{case1:EA=1;ET0=1;TR0=1;break;case2:EA=0;ET0=0;TR0=0;break;case0:P0=0x3f;P2=0x3f;i=0;Second_Counts=0;}上海师范大学信息与机电工程学院—倪继锋32}}《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例//主程序voidmain{P0=0x3f;P2=0x3f;i=0;Second_Counts=0;Key_Flag_Idx=0;//显示00//按键次数(取值0,1,2,3)Key_State=1;//按键状态TMOD=0x01;TH0=65536-50000/256;//定时器0方式1//定时器015ms}TL0=65536-50000%256;while1{ifKey_State!=K1{DelayMS10;Key_State=K1;Key_Event_Handle;}}//T0中断函数voidDSY_Refreshinterrupt1{TH0=65536-50000/256;TL0=65536-50000%256;//恢复定时器0初值{if++i==2i=0;Second_Counts++;//50ms*2=
0.1s转换状态}}P0=DSY_CODE[Second_Counts/10];P2=DSY_CODE[Second_Counts%10];ifSecond_Counts==100Second_Counts=0;//满100(10s)后显示0033用计数器中断实现100以内的按键计数/*名称用计数器中断实现100以内的按键计数说明本例用T0计数器中断实现按键技术,由于计数寄存器初值为1,因此P
3.4引脚的每次负跳变都会触发T0中断,实现计数值累加计数器的清零用外部中断0控制上海师范大学信息与机电工程学院—倪继锋33*/#includereg
51.h《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例#defineucharunsignedchar#defineuintunsignedint//段码ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f0x00};ucharCount=0;//主程序voidmain{P0=0x00;P2=0x00;TMOD=0x06;TH0=TL0=256-1;ET0=1;EX0=1;EA=1;//计数器T0方式2//计数值为1//允许T0中断//允许INT0中断//允许CPU中断IP=0x02;IT0=1;TR0=1;while1{//设置优先级,T0高于INT0//INT0中断触发方式为下降沿触发//启动T0}}P0=DSY_CODE[Count/10];P2=DSY_CODE[Count%10];//T0计数器中断函数voidKey_Counterinterrupt1{Count=Count+1%100;//因为只有两位数码管,计数控制在100以内(00~99)}//INT0中断函数voidClear_Counterinterrupt0{Count=0;}上海师范大学信息与机电工程学院—倪继锋34《单片机C语言程序设计实训100例---基于34100000s以内的计时程序/*名称100000s以内的计时程序说明在6只数码管上完成0~
99999.9s*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//段码ucharcode8051和PROTEUS仿真》案例DSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f};//6只数码管上显示的数字ucharDigits_of_6DSY[]={000000};ucharCount;sbitDot=P0^7;//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//主程序voidmain{ucharij;P0=0x00;P3=0xff;Count=0;TMOD=0x01;//计数器T0方式1TH0=65536-50000/256;//50ms定时TL0=65536-50000%256;IE=0x82;TR0=1;while1{j=0x7f;//启动T0//显示Digits_of_6DSY
[5]~Digits_of_6DSY
[0]的内容//前面高位,后面低位,循环中i!=-1亦可写成i!=0xfffori=5;i!=-1;i--{j=_crol_j1;上海师范大学信息与机电工程学院—倪继锋35P3=j;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例P0=DSY_CODE[Digits_of_6DSY[i]];}}}ifi==1Dot=1;DelayMS2;//加小数点//T0中断函数voidTimer0interrupt1{uchari;TH0=65536-50000/256;//恢复初值TL0=65536-50000%256;if++Count!=2return;Count=0;Digits_of_6DSY
[0]++;位累加fori=0;i=5;i++//进位处理{ifDigits_of_6DSY[i]==10{Digits_of_6DSY[i]=0;ifi!=5Digits_of_6DSY[i+1]++;如果0~4位则分别向高一位进位}elsebreak;//若某低位没有进位,怎循环提前结束}}35定时器控制数码管动态显示/*名称定时器控制数码管动态显示说明8个数码管上分两组动态显示年月日与时分秒,本例的位显示延时用定时器实现*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint//段码最后一位是“-”的段码ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x900xbf};//待显示的数据09-12-25与23-59-58(分两组显示)ucharcodeTable_of_Digits[]
[8]={{0910121025}{2310591058}};ucharij=0;上海师范大学信息与机电工程学院—倪继锋36uintt=0;//主程序voidmain{P3=0x80;《单片机C语言程序设计实训100例---基于//位码初值8051和PROTEUS仿真》案例TMOD=0x00;//计数器T0方式0TH0=8192-4000/32;//4ms定时TL0=8192-4000%32;IE=0x82;}TR0=1;while1;//启动T0//T0中断函数控制数码管刷新显示voidDSY_Showinterrupt1{TH0=8192-4000/32;//恢复初值TL0=8192-4000%32;P0=0xff;//输出位码和段码P0=DSY_CODE[Table_of_Digits[i][j]];P3=_crol_P31;j=j+1%8;//数组第i行的下一字节索引if++t!=350return;//保持刷新一段时间t=0;}i=i+1%2;//数组行i=0时显示年月日,i=1时显示时分秒368X8LED点阵显示数字/*名称8X8LED点阵显示数字说明8X8LED点阵屏循环显示数字0~9,刷新过程由定时器中断完成*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintucharcodeTable_of_Digits[]={0x000x3e0x410x410x410x3e0x000x000x000x000x000x210x7f0x010x000x000x000x270x450x450x450x390x000x00//20x000x220x490x490x490x360x000x00//30x000x0c0x140x240x7f0x040x000x00上海师范大学信息与机电工程学院—倪继锋37};《单片机C语言程序设计实训100例---基于0x000x720x510x510x510x4e0x000x000x000x3e0x490x490x490x260x000x000x000x400x400x400x4f0x700x000x000x000x360x490x490x490x360x000x00//80x000x320x490x490x490x3e0x000x008051和PROTEUS仿真》案例uchari=0t=0Num_Index;//主程序voidmain{P3=0x80;Num_Index=0;TMOD=0x00;//从0开始显示//T0方式0TH0=8192-2000/32;//2ms定时TL0=8192-2000%32;IE=0x82;}TR0=1;while1;//启动T0//T0中断函数voidLED_Screen_Displayinterrupt1{TH0=8192-2000/32;//恢复初值TL0=8192-2000%32;P0=0xff;//输出位码和段码P0=~Table_of_Digits[Num_Index*8+i];P3=_crol_P31;if++i==8i=0;//每屏一个数字由8个字节构成{if++t==250t=0;//每个数字刷新显示一段时间}}if++Num_Index==10Num_Index=0;//显示下一个数字37按键控制8X8LED点阵屏显示图形/*名称按键控制8X8LED点阵屏显示图形说明每次按下K1时,会使8X8LED点阵屏循环显示不同图形本例同时使用外部中断和定时中断*/#includereg
51.h上海师范大学信息与机电工程学院—倪继锋38#includeintrins.h《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例#defineucharunsignedchar#defineuintunsignedint//待显示图形编码ucharcodeM[]
[8]={{0x000x7e0x7e0x7e0x7e0x7e0x7e0x00}//图1{0x000x380x440x540x440x380x000x00}//图2{0x000x200x300x380x3c0x3e0x000x00}//图3};ucharij;//主程序voidmain{P0=0xff;P1=0xff;TMOD=0x01;//T0方式1TH0=65536-2000/256;//2ms定时TL0=65536-2000%256;}IT0=1;IE=0x83;i=0xff;while1;//下降沿触发//允许定时器
0、外部0中断//i的初值设为0xff,加1后将从0开始//T0中断控制点阵屏显示voidShow_Dot_Matrixinterrupt1{TH0=65536-2000/256;//恢复初值TL0=65536-2000%256;}P0=0xff;P0=~M[i][j];P1=_crol_P11;j=j+1%8;//输出位码和段码//INT0中断(定时器由键盘中断启动)voidKey_Downinterrupt0{P0=0xff;P1=0x80;j=0;}i=i+1%3;TR0=1;//i在0,1,2中取值,因为只要3个图形38用定时器设计的门铃上海师范大学信息与机电工程学院—倪继锋39《单片机C语言程序设计实训100例---基于/*名称用定时器设计的门铃说明按下按键时蜂鸣器发出叮咚的门铃声*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitKey=P1^7;sbitDoorBell=P3^0;uintp=0;//主程序voidmain{DoorBell=0;TMOD=0x00;//T0方式0TH0=8192-700/32;//700us定时TL0=8192-700%32;IE=0x82;while1{ifKey==0//按下按键启动定时器{TR0=1;whileKey==0;}}}//T0中断控制点阵屏显示voidTimer0interrupt1{DoorBell=~DoorBell;p++;8051和PROTEUS仿真》案例ifp400{//若需要拖长声音,可以调整400和800}{}else{TH0=8192-700/32;//700us定时TL0=8192-700%32;elseifp800TH0=8192-1000/32;//1ms定时TL0=8192-1000%32;TR0=0;40上海师范大学信息与机电工程学院—倪继锋}}p=0;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例39演奏音阶/*名称演奏音阶说明本例使用定时器演奏一段音阶,播放由K1控制*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitK1=P1^0;sbitSPK=P3^4;uinti=0;//音符索引//14个音符放在方式2下的定时寄存器(TH0TL0)ucharcodeHI_LIST[]={0226229232233236238240241242244245246247248};ucharcodeLO_LIST[]={04131020386223526143};//定时器0中断函数voidT0_INTinterrupt1{TL0=LO_LIST[i];TH0=HI_LIST[i];SPK=~SPK;}//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//主程序voidmain{TMOD=0x00;IE=0x82;SPK=0;while1{//T0方式0whileK1==1;//未按键等待whileK1==0;//等待释放fori=1;i15;i++{上海师范大学信息与机电工程学院—倪继锋41}}}《单片机C语言程序设计实训100例---基于TR0=1;//播放一个音符DelayMS500;//播放延时TR0=0;DelayMS50;8051和PROTEUS仿真》案例40按键控制定时器选播多段音乐/*名称按键控制定时器选播多段音乐说明本例内置3段音乐,K1可启动停止音乐播放,K2用于选择音乐段*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintsbitK1=P1^0;sbitSPK=P3^7;//播放和停止键//蜂鸣器ucharSong_Index=0Tone_Index=0;//当前音乐段索引,音符索引//数码管段码表ucharcodeDSY_CODE[]={0xc00xf90xa40xb00x990x920x820xf80x800x90};//标准音符频率对应的延时表ucharcodeHI_LIST[]={0226229232233236238240241242244245246247248};ucharcodeLO_LIST[]={04131020386223526143};//三段音乐的音符ucharcodeSong[]
[50]={{1231123134534556535653532121-1}{33345555653532156533211-1}{32132112311231345345565353213211-1}};//三段音乐的节拍ucharcodeLen[]
[50]={{1111111111211211111111111212-1}{11111121111111211111122-1}{11211211111111112112111111121122-1}};//外部中断0voidEX0_INTinterrupt0{TR0=0;播放结束或者播放中途切换歌曲时停止播放Song_Index=Song_Index+1%3;跳到下一首的开头上海师范大学信息与机电工程学院—倪继锋42《单片机C语言程序设计实训100例---基于Tone_Index=0;8051和PROTEUS仿真》案例}P2=DSY_CODE[Song_Index];//数码管显示当前音乐段号//定时器0中断函数voidT0_INTinterrupt1{TL0=LO_LIST[Song[Song_Index][Tone_Index]];TH0=HI_LIST[Song[Song_Index][Tone_Index]];SPK=~SPK;}//延时voidDelayMSuintms{uchart;whilems--fort=0;t120;t++;}//主程序voidmain{P2=0xc0;SPK=0;TMOD=0x00;IE=0x83;IT0=1;IP=0x02;while1{//T0方式0whileK1==1;//未按键等待whileK1==0;//等待释放TR0=1;//开始播放Tone_Index=0;//从第0个音符开始//播放过程中按下K1可提前停止播放(K1=0)//若切换音乐段会触发外部中断,导致TR0=0,播放也会停止whileSong[Song_Index][Tone_Index]!=-1K1==1TR0==1{DelayMS300*Len[Song_Index][Tone_Index];播放延时(节拍)}Tone_Index++;//当前音乐段的下一音符索引TR0=0;//停止播放}}whileK1==0;//若提前停止播放,按键未释放时等待41定时器控制交通指示灯上海师范大学信息与机电工程学院—倪继锋43《单片机C语言程序设计实训100例---基于/*名称定时器控制交通指示灯8051和PROTEUS仿真》案例*/说明东西向绿灯亮5s后,黄灯闪烁,闪烁5次亮红灯,红灯亮后,南北向由红灯变成绿灯,5s后南北向黄灯闪烁,闪烁5次后亮红灯,东西向绿灯亮,如此往复#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitRED_A=P0^0;//东西向指示灯sbitYELLOW_A=P0^1;sbitGREEN_A=P0^2;sbitRED_B=P0^3;//南北向指示灯sbitYELLOW_B=P0^4;sbitGREEN_B=P0^5;//延时倍数,闪烁次数,操作类型变量ucharTime_Count=0Flash_Count=0Operation_Type=1;//定时器0中断函数voidT0_INTinterrupt1{TL0=-50000/256;TH0=-50000%256;switchOperation_Type{case1://东西向绿灯与南北向红灯亮5sRED_A=0;YELLOW_A=0;GREEN_A=1;RED_B=1;YELLOW_B=0;GREEN_B=0;if++Time_Count!=100return;//5s(100*50ms)切换Time_Count=0;Operation_Type=2;break;case2://东西向黄灯开始闪烁,绿灯关闭if++Time_Count!=8return;Time_Count=0;YELLOW_A=~YELLOW_A;GREEN_A=0;if++Flash_Count!=10return;//闪烁Flash_Count=0;Operation_Type=3;break;case3://东西向红灯与南北向绿灯亮5sRED_A=1;YELLOW_A=0;GREEN_A=0;RED_B=0;YELLOW_B=0;GREEN_B=1;if++Time_Count!=100return;//5s(100*50ms)切换Time_Count=0;Operation_Type=4;上海师范大学信息与机电工程学院—倪继锋44《单片机C语言程序设计实训100例---基于break;case4://南北向黄灯开始闪烁,绿灯关闭if++Time_Count!=8return;Time_Count=0;8051和PROTEUS仿真》案例}}YELLOW_B=~YELLOW_B;GREEN_A=0;if++Flash_Count!=10return;//闪烁Flash_Count=0;Operation_Type=1;break;//主程序voidmain{TMOD=0x01;IE=0x82;TR0=1;while1;}42报警与旋转灯/*名称报警与旋转灯说明定时器控制报警灯旋转显示,并发出仿真警报声*/#includereg
51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedintsbitSPK=P3^7;ucharFRQ=0x00;//延时voidDelayMSuintms{uchari;//T0方式1}whilems--fori=0;i120;i++;//INT0中断函数voidEX0_INTinterrupt0{TR0=~TR0;//开启或停止两定时器,分别控制报警器的声音和LED旋转TR1=~TR1;ifP2==0x00上海师范大学信息与机电工程学院—倪继锋45}else《单片机C语言程序设计实训100例---基于P2=0xe0;//开3个旋转灯P2=0x00;//关闭所有LED8051和PROTEUS仿真》案例//定时器0中断voidT0_INTinterrupt1{TH0=0xfe;TL0=FRQ;SPK=~SPK;}//定时器1中断voidT1_INTinterrupt3{TH1=-45000/256;TL1=-45000%256;P2=_crol_P21;}//主程序voidmain{P2=0x00;SPK=0x00;TMOD=0x11;//T
0、T1方式1TH0=0x00;TL0=0xff;IT0=1;IE=0x8b;//开启0,1,3号中断IP=0x01;//INT0设为最高优先TR0=0;}TR1=0;while1{FRQ++;DelayMS1;}//定时器启停由INT0控制,初始关闭43串行数据转换为并行数据/*名称串行数据转换为并行数据说明串行数据由RXD发送给串并转换芯片74164,TXD则用于输出移位时钟脉冲,74164将串行输入的1字节转换为并行数据,并将转换的数据通过8只LED显示出来本例串口工作模式0,即移位寄存器I/O模式*/46上海师范大学信息与机电工程学院—倪继锋#includereg
51.h#includeintrins.h《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例#defineucharunsignedchar#defineuintunsignedintsbitSPK=P3^7;ucharFRQ=0x00;//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//主程序voidmain{ucharc=0x80;SCON=0x00;串口模式0,即移位寄存器输入/输出方式TI=1;while1{c=_crol_c1;SBUF=c;whileTI==0;//等待发送结束}}TI=0;DelayMS400;//TI软件置位44并行数据转换为串行数据/*名称并行数据转换为串行数据说明切换连接到并串转换芯片74LS165的拨码开关,该芯片将并行数据以串行方式发送到8051的RXD引脚,移位脉冲由TXD提供,显示在P0口*/#includereg
51.h#includeintrins.h#includestdio.h#defineucharunsignedchar#defineuintunsignedintsbitSPL=P2^5;//延时voidDelayMSuintms{//shift/load47上海师范大学信息与机电工程学院—倪继锋uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}whilems--fori=0;i120;i++;//主程序voidmain{SCON=0x10;串口模式0,允许串口接收while1{SPL=0;//置数load,读入并行输入口的8位数据SPL=1;//移位shift,并口输入被封锁,串行转换开始whileRI==0;//未接收1字节时等待}}RI=0;P0=SBUF;DelayMS20;//RI软件置位//接收到的数据显示在P0口,显示拨码开关的值45甲机通过串口控制乙机LED/*名称甲机发送控制命令字符说明甲单片机负责向外发送控制命令字符“A”、“B”、“C”,或者停止发送,乙机根据所接收到的字符完成LED1闪烁、LED2闪烁、双闪烁、或停止闪烁*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED1=P0^0;sbitLED2=P0^3;sbitK1=P1^0;//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//向串口发送字符voidPutc_to_SerialPortucharc{SBUF=c;whileTI==0;TI=0;上海师范大学信息与机电工程学院—倪继锋48}//主程序voidmain{《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}ucharOperation_No=0;SCON=0x40;串口模式1TMOD=0x20;//T1工作模式2PCON=0x00;波特率不倍增TH1=0xfd;TL1=0xfd;TI=0;TR1=1;while1{ifK1==0//按下K1时选择操作代码0,1,2,3{whileK1==0;Operation_No=Operation_No+1%4;}switchOperation_No//根据操作代码发送A/B/C或停止发送{case0:LED1=LED2=1;break;case1:Putc_to_SerialPortA;LED1=~LED1;LED2=1;break;case2:Putc_to_SerialPortB;LED2=~LED2;LED1=1;break;case3:Putc_to_SerialPortC;LED1=~LED1;LED2=LED1;break;}DelayMS100;}/*名称乙机程序接收甲机发送字符并完成相应动作说明乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED1=P0^0;sbitLED2=P0^3;上海师范大学信息与机电工程学院—倪继锋49//延时《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//主程序voidmain{SCON=0x50;串口模式1,允许接收TMOD=0x20;//T1工作模式2PCON=0x00;波特率不倍增TH1=0xfd;TL1=0xfd;RI=0;TR1=1;LED1=LED2=1;while1{//波特率9600ifRI//如收到则LED闪烁{RI=0;switchSBUF//根据所收到的不同命令字符完成不同动作{caseA:LED1=~LED1;LED2=1;break;//LED1闪烁caseB:LED2=~LED2;LED1=1;break;//LED2闪烁}}caseC:LED1=~LED1;LED2=LED1;//双闪烁}}elseLED1=LED2=1;DelayMS100;//关闭LED46单片机之间双向通信/*名称甲机串口程序说明甲机向乙机发送控制命令字符,甲机同时接收乙机发送的数字,并显示在数码管上*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED1=P1^0;上海师范大学信息与机电工程学院—倪继锋50sbitLED2=P1^3;sbitK1=P1^7;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例ucharOperation_No=0;//操作代码//数码管代码ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f};//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//向串口发送字符voidPutc_to_SerialPortucharc{SBUF=c;whileTI==0;TI=0;}//主程序voidmain{LED1=LED2=1;P0=0x00;SCON=0x50;串口模式1,允许接收TMOD=0x20;//T1工作模式2PCON=0x00;波特率不倍增TH1=0xfd;TL1=0xfd;TI=RI=0;TR1=1;IE=0x90;//允许串口中断while1{DelayMS100;ifK1==0//按下K1时选择操作代码0,1,2,3{whileK1==0;Operation_No=Operation_No+1%4;switchOperation_No根据操作代码发送A/B/C或停止发送{case0:Putc_to_SerialPortX;LED1=LED2=1;break;case1:Putc_to_SerialPortA;上海师范大学信息与机电工程学院—倪继锋51}}}}《单片机C语言程序设计实训100例---基于LED1=~LED1;LED2=1;break;case2:Putc_to_SerialPortB;LED2=~LED2;LED1=1;break;case3:Putc_to_SerialPortC;LED1=~LED1;LED2=LED1;break;8051和PROTEUS仿真》案例//甲机串口接收中断函数voidSerial_INTinterrupt4{ifRI{RI=0;ifSBUF=0SBUF=9P0=DSY_CODE[SBUF];elseP0=0x00;}}/*名称乙机程序接收甲机发送字符并完成相应动作说明乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitLED1=P1^0;sbitLED2=P1^3;sbitK2=P1^7;ucharNumX=-1;//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//主程序voidmain{LED1=LED2=1;SCON=0x50;串口模式1,允许接收TMOD=0x20;//T1工作模式2上海师范大学信息与机电工程学院—倪继锋52TH1=0xfd;TL1=0xfd;《单片机C语言程序设计实训100例---基于//波特率96008051和PROTEUS仿真》案例}PCON=0x00;波特率不倍增RI=TI=0;TR1=1;IE=0x90;while1{DelayMS100;ifK2==0{whileK2==0;NumX=++NumX%11;//产生0~10范围内的数字,其中10表示关闭SBUF=NumX;whileTI==0;TI=0;}}voidSerial_INTinterrupt4{ifRI//如收到则LED则动作{RI=0;switchSBUF//根据所收到的不同命令字符完成不同动作{caseX:LED1=LED2=1;break;//全灭caseA:LED1=0;LED2=1;break;//LED1亮caseB:LED2=0;LED1=1;break;//LED2亮}}}caseC:LED1=LED2=0;//全亮47单片机向主机发送字符串/*名称单片机向主机发送字符串说明单片机按一定的时间间隔向主机发送字符串,发送内容在虚拟终端显示*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//延时voidDelayMSuintms上海师范大学信息与机电工程学院—倪继锋53{uchari;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}whilems--fori=0;i120;i++;//向串口发送字符voidPutc_to_SerialPortucharc{SBUF=c;whileTI==0;TI=0;}//向串口发送字符串voidPuts_to_SerialPortuchar*s{while*s!=\0{Putc_to_SerialPort*s;s++;DelayMS5;}}//主程序voidmain{ucharc=0;SCON=0x40;串口模式1TMOD=0x20;//T1工作模式2TH1=0xfd;TL1=0xfd;//波特率9600PCON=0x00;波特率不倍增TI=0;TR1=1;DelayMS200;//向主机发送数据Puts_to_SerialPortReceivingFrom
8051...\r\n;Puts_to_SerialPort-------------------------------\r\n;DelayMS50;while1{Putc_to_SerialPortc+A;DelayMS100;Putc_to_SerialPort;DelayMS100;ifc==25//每输出一遍后加横线{上海师范大学信息与机电工程学院—倪继锋54《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}Puts_to_SerialPort\r\n-------------------------------\r\n;DelayMS100;}}c=c+1%26;ifc%10==0//每输出10个字符后换行{Puts_to_SerialPort\r\n;DelayMS100;}48单片机与PC通信/*名称单片机与PC通信说明单片机可接收PC发送的数字字符,按下单片机的K1键后,单片机可向PC发送字符串在Proteus环境下完成本实验时,需要安装VirtualSerialPortDriver和串口调试助手本例缓冲100个数字字符,缓冲满后新数字从前面开始存放(环形缓冲)*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedintucharReceive_Buffer
[101];//接收缓冲ucharBuf_Index=0;//数码管编码//缓冲空间索引ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f0x00};//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//主程序voidmain{uchari;P0=0x00;Receive_Buffer
[0]=-1;SCON=0x50;串口模式1,允许接收上海师范大学信息与机电工程学院—倪继锋55}《单片机C语言程序设计实训100例---基于TMOD=0x20;//T1工作模式2TH1=0xfd;//波特率9600TL1=0xfd;PCON=0x00;波特率不倍增EA=1;EX0=1;IT0=1;ES=1;IP=0x01;TR1=1;while1{fori=0;i100;i++{//收到-1为一次显示结束ifReceive_Buffer[i]==-1break;P0=DSY_CODE[Receive_Buffer[i]];DelayMS200;}DelayMS200;}8051和PROTEUS仿真》案例//串口接收中断函数voidSerial_INTinterrupt4{ucharc;ifRI==0return;ES=0;RI=0;c=SBUF;ifc=0c=9//关闭串口中断//清接收中断标志}{//缓存新接收的每个字符,并在其后放-1为结束标志Receive_Buffer[Buf_Index]=c-0;Receive_Buffer[Buf_Index+1]=-1;Buf_Index=Buf_Index+1%100;}ES=1;voidEX_INT0interrupt0//外部中断0{uchar*s=这是由8051发送的字符串!\r\n;uchari=0;whiles[i]!=\0{SBUF=s[i];whileTI==0;TI=0;i++;}上海师范大学信息与机电工程学院—倪继锋56}《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例19用ADC0808控制PWM输出/*名称用ADC0808控制PWM输出第02篇硬件应用*/说明使用数模转换芯片ADC0808,通过调节可变电阻RV1来调节脉冲宽度,运行程序时,通过虚拟示波器观察占空比的变化#includereg
51.h#defineucharunsignedchar#defineuintunsignedintsbitCLK=P2^4;//时钟信号sbitST=P2^5;//启动信号sbitEOC=P2^6;//转换结束信号sbitOE=P2^7;//输出使能sbitPWM=P3^0;//PWM输出//延时voidDelayMSuintms{uchari;whilems--fori=0;i40;i++;}//主程序voidmain{ucharVal;TMOD=0x02;//T1工作模式2TH0=0x14;TL0=0x00;IE=0x82;TR0=1;while1{ST=0;ST=1;ST=0;//启动A/D转换while!EOC;//等待转换完成OE=1;Val=P1;OE=0;ifVal==0{PWM=0;DelayMS0xff;continue;//读转换值//PWM输出(占空比为0%)57上海师范大学信息与机电工程学院—倪继锋}《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例ifVal==0xff{PWM=1;//PWM输出(占空比为100%)}DelayMS0xff;continue;}}PWM=1;DelayMSVal;PWM=0;DelayMS0xff-Val;//PWM输出(占空比为0%~100%)//T0定时器中断给ADC0808提供时钟信号voidTimer0_INTinterrupt1{CLK=~CLK;}20ADC0809数模转换与显示/*名称ADC0809数模转换与显示说明ADC0809采样通道3输入的模拟量,转换后的结果显示在数码管上*/#includereg
51.h#defineucharunsignedchar#defineuintunsignedint//各数字的数码管段码(共阴)ucharcodeDSY_CODE[]={0x3f0x060x5b0x4f0x660x6d0x7d0x070x7f0x6f};sbitCLK=P1^3;//时钟信号sbitST=P1^2;//启动信号sbitEOC=P1^1;//转换结束信号sbitOE=P1^0;//输出使能//延时voidDelayMSuintms{uchari;whilems--fori=0;i120;i++;}//显示转换结果voidDisplay_Resultuchard{P2=0xf7;第4个数码管显示个位数P0=DSY_CODE[d%10];上海师范大学信息与机电工程学院—倪继锋58DelayMS5;《单片机C语言程序设计实训100例---基于8051和PROTEUS仿真》案例}P2=0xfb;第3个数码管显示十位数P0=DSY_CODE[d%100/10];DelayMS5;P2=0xfd;第2个数码管显示百位数P0=DSY_CODE[d/100];DelayMS5;//主程序voidmain{TMOD=0x02;//T1工作模式2TH0=0x14;TL0=0x00;IE=0x82;TR0=1;P1=0x3f;//选择ADC0809的通道3
(0111)(P
1.4~P
1.6)while1{}}ST=0;ST=1;ST=0;whileEOC==0;OE=1;Display_ResultP3;OE=0;//启动A/D转换//等待转换完成//T0定时器中断给ADC0808提供时钟信号voidTimer0_INTinterrupt1{CLK=~CLK;}上海师范大学信息与机电工程学院—倪继锋59。