《蓝桥杯单片机设计与开发》拓展训练题及解答_第1页
《蓝桥杯单片机设计与开发》拓展训练题及解答_第2页
《蓝桥杯单片机设计与开发》拓展训练题及解答_第3页
《蓝桥杯单片机设计与开发》拓展训练题及解答_第4页
《蓝桥杯单片机设计与开发》拓展训练题及解答_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

--------------------------第2章拓展训练题-------------------------2-1.对于图2-39所示的单片机人机接口电路,编写应用程序,驱动8个LED按“全灭→D0亮→D0D1亮→D0D1D2亮→...→D0~D7全亮→D7灭→D7D6灭→D7D6D5灭→...→全灭”的顺序循环变化。设每个状态保持时间约0.5s。应用Proteus和KeilµVision完成系统软硬件功能仿真。图2-39单片机人机接口电路----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<reg52.h>voidDelay1ms(unsignedintnum)//延时子程序{ unsignedinti; while(num--) for(i=0;i<123;i++);}//LED循环变化驱动子程序voidLEDrunning(){ unsignedchari,pattern;P1=0xFF;//全灭Delay1ms(500);//逐个点亮LED(D0到D7)pattern=0x00;//初始状态全灭for(i=0;i<8;i++){ pattern|=(0x01<<i);//点亮第i个LED P1=~pattern; Delay1ms(500);}//逐个熄灭LED(D7到D0)pattern=0xFF;//初始状态全亮for(i=0;i<8;i++) { pattern&=~(0x01<<(7-i));//熄灭第(7-i)个LEDP1=~pattern;Delay1ms(500);}}voidmain()//主函数{ while(1) { LEDrunning(); }}2-2.参考BinCnt4b_disp.c,编写驱动8个LED显示8位二进制加法计数过程的应用程序。设每个状态保持时间约为0.25s。应用Proteus和KeilµVision完成系统软硬件功能仿真。图2-39单片机人机接口电路-------------------------------------------------张俊涛解答-----------------------------------------------------//文件名CP02_BinCnt8b_disp.c#include<reg52.h>//包含头文件sbitLED_B0=P1^0;sbitLED_B1=P1^1;sbitLED_B2=P1^2;sbitLED_B3=P1^3;sbitLED_B4=P1^4;sbitLED_B5=P1^5;sbitLED_B6=P1^6;sbitLED_B7=P1^7;unsignedcharLOOPcnt=0;//12T单片机延时子程序定义(1ms,@12MHz)voidDelay1ms(unsignedintxms){unsignedchari;while(xms--)for(i=0;i<123;i++);}//主函数voidmain(){while(1){LOOPcnt++;Delay1ms(250);LED_B0=~LED_B0;if((LOOPcnt%2)==0)LED_B1=~LED_B1;if((LOOPcnt%4)==0)LED_B2=~LED_B2;if((LOOPcnt%8)==0)LED_B3=~LED_B3;if((LOOPcnt%16)==0)LED_B4=~LED_B4;if((LOOPcnt%32)==0)LED_B5=~LED_B5;if((LOOPcnt%64)==0)LED_B6=~LED_B6;if((LOOPcnt%128)==0){LED_B7=~LED_B7;LOOPcnt=0;}}}--------------------------第3章拓展训练题-------------------------3-1.对于图2-39所示的人机接口应用电路,编写应用程序,驱动8个数码管稳定显示数字“19491001”的同时,依次循环点亮发光二极管LED~LED8。设每个LED的显示时间约为500ms。应用Proteus和KeilµVision完成系统软硬件的功能仿真。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<reg52.h>unsignedcharcodeSEGcode[10]=//共阳极数码管段码表:0~9{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};unsignedcharDTbuf[8]={1,9,4,9,1,0,0,1};voidDelay1ms(unsignedintxms){ unsignedchari;while(xms--)for(i=0;i<123;i++);}//数码管动态扫描子程序voidDTdisp_dynamic(void){unsignedchari;for(i=0;i<8;i++) {P0=SEGcode[DTbuf[i]];P2=0x01<<i;Delay1ms(2);P2=0x00;}}//LED循环点亮控制子程序voidLEDrunning(void){staticunsignedcharled_index=0;staticunsignedintled_count=0;led_count++;if(led_count>=25) {led_count=0; P1=0xFF;//熄灭所有LEDP1&=~(0x01<<led_index);led_index=(led_index+1)%8;}}//主函数voidmain(){ P1=0xFF;//LED熄灭while(1) {DTdisp_dynamic();//持续刷新数码管显示LEDrunning();//控制LED循环点亮}}--------------------------第4章拓展训练题--------------------------4-1.对于图2-39所示的人机接口应用电路,编写应用程序,驱动8个数码管从右向左流动显示十六进制数码“0~9、A、b、C、d、E、F”。设数码管的初始状态为全灭,数码流动速度为0.5s。应用Proteus和KeilµVision完成系统软硬件的功能仿真。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<reg52.h>unsignedcharcodeDTseg_tab[24]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//8个灭码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,//0-70x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e//8-F};//数码管位选码表unsignedcharcodeDTbit_tab1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};bitSEG_dir=0;//流动方向控制变量voidTimer1Init(){TMOD=TMOD&0x0f|0x10;//设置定时器1为模式1TH1=(65536-2000)/256;//定时初值TL1=(65536-2000)%256;ET1=1;//使能定时器1中断EA=1;//开总中断TR1=1;//启动定时器1}voidTimer1isr()interrupt3{staticunsignedcharDTno=0xff;staticunsignedcharoffset=0;staticunsignedinttimes=0;TH1=(65536-2000)/256;//重新装载初值TL1=(65536-2000)%256;P2=0x00;//消隐DTno++;DTno&=0x07;if((DTno+offset)<24)P0=DTseg_tab[DTno+offset];elseP0=DTseg_tab[DTno+offset-24];P2=DTbit_tab1[DTno];times++;if(times==250){times=0; offset++;if(offset>=24)offset=0;}}voidmain(){Timer1Init();while(1);}4-2.在拓展训练题4-1的基础上,应用按键K0控制数码显示的流动方向。预设K0未按时显示数码从右向左流动,按下K0后切换显示数码从当前位置开始向右流动,再次按下K0后显示数码恢复向左流动。设数码显示的流动速度为0.5s。编写驱动程序,应用Proteus和KeilµVision完成系统软硬件的功能仿真。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<reg52.h>sbitK0=P3^0;//定义按键引脚bittime=0;unsignedcharcodeDTseg_tab[24]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//8个灭码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,//0-70x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e//8-F};//数码管位选码表unsignedcharcodeDTbit_tab1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};bitSEG_dir=0;//流动方向控制变量voidTimer1Init(){TMOD=TMOD&0x0f|0x10;//设置定时器1为模式1TH1=(65536-2000)/256;//定时初值TL1=(65536-2000)%256;ET1=1;//使能定时器1中断EA=1;//开总中断TR1=1;//启动定时器1}voidDelay1ms(unsignedintxms){ unsignedinti; while(xms--)for(i=0;i<628;i++);}//按键检测函数voidKeyScan(){if(K0==0) { Delay1ms(10); if(K0==0) { SEG_dir=~SEG_dir; time=1; } else time=0; }}voidTimer1isr()interrupt3{staticunsignedcharDTno=0xff;staticunsignedcharoffset=0;staticunsignedinttimes=0;TH1=(65536-2000)/256;//重新装载初值TL1=(65536-2000)%256;P2=0x00;//消隐DTno++;DTno&=0x07;if((DTno+offset)<24)P0=DTseg_tab[DTno+offset];elseP0=DTseg_tab[DTno+offset-24];P2=DTbit_tab1[DTno];times++;if(times==250){times=0;if(SEG_dir==0){offset++;if(offset>=24)offset=0;}else{if(offset==0)offset=24;offset--;}}}voidmain(){Timer1Init();while(1) { KeyScan(); }}--------------------------第5章拓展训练题---------------------------5-1.在应用程序DTdrv_dynamic.c基础上,应用按键S4切换数码显示页面。预设S4未按下前8位数码管显示“19491001”,按下S4后8位数码管显示“18931226”,再次按下S4后8个数码管恢复显示“19491001”。编写应用程序,并下载到开发板进行功能测试。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"/*变量定义*/sbitS4=P3^3;//定义按键S4//定义数码显示数据缓冲区,预设显示“19491001”unsignedcharDTbuf[8]={1,9,4,9,1,0,0,1};bitmode=0;//数码管动态扫描子程序voidDTdisp_dynamic(){ DT_drv(0,DTbuf[0]);Delay1ms(2);DT_drv(1,DTbuf[1]);Delay1ms(2);DT_drv(2,DTbuf[2]);Delay1ms(2);DT_drv(3,DTbuf[3]);Delay1ms(2);DT_drv(4,DTbuf[4]);Delay1ms(2);DT_drv(5,DTbuf[5]);Delay1ms(2);DT_drv(6,DTbuf[6]);Delay1ms(2);DT_drv(7,DTbuf[7]);Delay1ms(2);}voidScanKeys(){if(S4==0){Delay1ms(20);if(S4==0){while(S4==0){DTdisp_dynamic();} mode^=1; if(mode==0){//显示"19491001"DTbuf[0]=1;DTbuf[1]=9;DTbuf[2]=4;DTbuf[3]=9;DTbuf[4]=1;DTbuf[5]=0;DTbuf[6]=0;DTbuf[7]=1;}else{//显示"18931226"DTbuf[0]=1;DTbuf[1]=8;DTbuf[2]=9;DTbuf[3]=3;DTbuf[4]=1;DTbuf[5]=2;DTbuf[6]=2;DTbuf[7]=6;} } }}//主函数voidmain(){ BEEP_off(); //关蜂鸣器 LED_drv(0xff); //关LED while(1) { ScanKeys(); DTdisp_dynamic(); //循环调用数码管动态扫描子程序 } }5-2.在应用程序DTdrv_dynamic.c基础上,应用按键S4切换数码显示页面。预设S4未按下前8个数码管显示“19491001”,按下S4期间8位数码管显示“18931226”,释放后8个数码管恢复显示“19491001”。编写应用程序,并下载到开发板进行功能测试。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c" sbitS4=P3^3;//定义数码显示数据缓冲区unsignedcharDTbuf[8]={1,9,4,9,1,0,0,1};//预设显示"19491001"voidDTdisp_dynamic(){DT_drv(0,DTbuf[0]);Delay1ms(2);DT_drv(1,DTbuf[1]);Delay1ms(2);DT_drv(2,DTbuf[2]);Delay1ms(2);DT_drv(3,DTbuf[3]);Delay1ms(2);DT_drv(4,DTbuf[4]);Delay1ms(2);DT_drv(5,DTbuf[5]);Delay1ms(2);DT_drv(6,DTbuf[6]);Delay1ms(2);DT_drv(7,DTbuf[7]);Delay1ms(2);}//主函数voidmain(){BEEP_off(); //关蜂鸣器LED_drv(0xff); //关LEDwhile(1){//检测按键状态并更新显示内容if(S4==0){//按键按下//显示"18931226"DTbuf[0]=1;DTbuf[1]=8;DTbuf[2]=9;DTbuf[3]=3;DTbuf[4]=1;DTbuf[5]=2;DTbuf[6]=2;DTbuf[7]=6;}else{//按键释放//恢复显示"19491001"DTbuf[0]=1;DTbuf[1]=9;DTbuf[2]=4;DTbuf[3]=9;DTbuf[4]=1;DTbuf[5]=0;DTbuf[6]=0;DTbuf[7]=1;}DTdisp_dynamic(); //循环调用数码管动态扫描子程序}}--------------------------第6章拓展训练题---------------------------6-1.在拓展训练题4-1的基础上,应用中断方式检测按键S4的状态,用于控制显示数码的流动方向。预设显示数码从右向左流动。按下S4后显示数码从目前状态切换为向右流动,再次按下S4后显示数码恢复向左流动。编写应用程序,并下载到开发板进行功能测试。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"sbitS4=P3^3;//数码管段码表(0-9,A-F,灭码)unsignedcharcodeDTseg_tab[24]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//8个灭码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,//0-70x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e//8-F};//数码管位选码表unsignedcharcodeDTbit_tab1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};unsignedcharS4buf=0xff;unsignedcharDTno=0xff;unsignedcharoffset=0;bittime=0;//0不按下1按下bitSEG_dir=0;//显示方向标志:0=向左流动,1=向右流动voidTimer1Init(void) {TMOD&=0x0F;TH1=(65536-2000)/256;TL1=(65536-2000)%256;ET1=1;//允许T1中断EA=1;//开放总中断TR1=1;//启动T1 }//定时器T1中断服务函数voidTimer1isr()interrupt3{staticunsignedchartimes=0;//中断次数统计变量S4buf=(S4buf<<1)|S4; DTno++;DTno&=0x07;DTseg_en;//打开段码通道 if((DTno+offset)<24) P0=DTseg_tab[DTno+offset]; else P0=DTseg_tab[DTno+offset-24];ALL_off; DTbit_en;P0=DTbit_tab1[DTno];ALL_off;times++;if(times>=250) { times=0;//刷新次数清零 if(SEG_dir==0) { offset++; if(offset>=24) offset=0; } else { offset--; if(offset==0)offset=24; } }}//主程序voidmain(){BEEP_off();//关闭蜂鸣器RELAY_off();//断开继电器LED_drv(0xff);//熄灭LEDTimer1Init();//定时器初始化while(1){if(S4buf==0x00)SEG_dir^=1; }}6-2.在拓展训练题4-1的基础上,应用中断方式检测按键S4和S5的状态,用于控制显示数码的流动方向。预设显示数码从右向左流动。按下S5后显示数码从目前状态切换为向右流动,按下S4后显示数码恢复向左流动。编写应用程序,并下载到开发板进行功能测试。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"sbitS4=P3^3;sbitS5=P3^2;//数码管段码表(0-9,A-F,灭码)unsignedcharcodeDTseg_tab[24]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//8个灭码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,//0-70x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e//8-F};//数码管位选码表unsignedcharcodeDTbit_tab1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};unsignedcharS4buf=0xff;unsignedcharS5buf=0xff;unsignedcharDTno=0xff;unsignedcharoffset=0;bittime=0;//0不按下1按下bitSEG_dir=0;//显示方向标志:0=向左流动,1=向右流动voidTimer1Init(void){TMOD&=0x0F;TH1=(65536-2000)/256;TL1=(65536-2000)%256;ET1=1;//允许T1中断EA=1;//开放总中断TR1=1;//启动T1}//定时器T1中断服务函数voidTimer1isr()interrupt3{staticunsignedchartimes=0;//中断次数统计变量 S4buf=(S4buf<<1)|S4; S5buf=(S5buf<<1)|S5; DTno++;DTno&=0x07;DTseg_en;//打开段码通道 if((DTno+offset)<24) P0=DTseg_tab[DTno+offset]; else P0=DTseg_tab[DTno+offset-24];ALL_off; DTbit_en; P0=DTbit_tab1[DTno];ALL_off;times++;if(times>=250) { times=0;//刷新次数清零 if(SEG_dir==0) { offset++; if(offset>=24) offset=0; } else { offset--; if(offset==0) offset=24; } } }//主程序voidmain(){BEEP_off();//关闭蜂鸣器RELAY_off();//断开继电器LED_drv(0xff);//熄灭LEDTimer1Init();//定时器初始化while(1) {if(S4buf==0x00) SEG_dir=0; if(S5buf==0x00) SEG_dir=1; }}--------------------------第8章拓展训练题--------------------------8-1.设计电子秒表,具有启动、暂停和清零功能。具体功能要求描述如下:1.数码管显示用8个数码管显示秒表的分、秒和毫秒值,具体显示格式如表题8-1所示,其中毫秒值以10ms基本单位。表题8-1电子钟时间格式01-23-45分分隔符秒分隔符450毫秒2.按键功能描述(1)定义按键S4为“启动和停止”功能。按下S4时,秒表启动计时,再次按下S4时,秒表暂停。(2)定义按键S7为“清零”功能。在秒表暂时的情况下,按下S7将分、秒和毫秒值清零。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"/*变量定义*/sbitS4=P3^3;//定义按键S4sbitS7=P3^0;unsignedchart_min=0;//分钟unsignedchart_s=0;//秒unsignedchart_ms=0;//毫秒bitwatch_running=0;//秒表运行标志/*数码管显示*/voidSMG_display(){DT_drv(7,t_ms%10);//显示毫秒个位Delay1ms(1);DT_drv(6,t_ms/10);//显示毫秒十位Delay1ms(1);DT_drv(5,26);//显示分隔符Delay1ms(1);DT_drv(4,t_s%10);//显示秒个位Delay1ms(1);DT_drv(3,t_s/10);//显示秒十位Delay1ms(1);DT_drv(2,26);//显示分隔符Delay1ms(1);DT_drv(1,t_min%10);//显示分钟个位Delay1ms(1);DT_drv(0,t_min/10);//显示分钟十位Delay1ms(1);}/*定时器0初始化*/voidInitTimer0(){AUXR&=0x7F; //定时器时钟12T模式 TMOD&=0xF0; //设置定时器模式 TL0=0xF0; //设置定时初值 TH0=0xD8; TF0=0; //清除TF0标志TR0=1; //定时器0开始计时ET0=1; //使能定时器0中断EA=1; //全局中断使能}/*定时器0中断服务*/voidServiceTimer0()interrupt1{if(watch_running){t_ms++;if(t_ms>=100)//100*10ms=1s{t_ms=0;t_s++;if(t_s>=60){t_s=0;t_min++;if(t_min>=60){t_min=0;}}}}}/*按键扫描*/voidScanKeys(){if(S4==0){Delay1ms(20);if(S4==0){while(S4==0){SMG_display();}watch_running=!watch_running; } } if(S7==0){Delay1ms(20);if(S7==0){ while(S7==0){SMG_display();}if(!watch_running){t_ms=0;t_s=0;t_min=0;} } }}//主函数voidmain(){InitTimer0();//初始化定时器while(1){SMG_display();//显示时间ScanKeys();//扫描按键}}--------------------------第9章拓展训练题---------------------------9-1.对于拓展训练题8-1设计的电子秒表,重新定义按键S4具有启动、暂停和清零三种功能。短按S4用于控制秒表的启动和停止。在秒表停止的情况下,长按S4用于将秒表清零。编写应用程序,并下载开发板进行测试。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"/*变量定义*/sbitS4=P3^3;//定义按键S4unsignedchart_min=0;//分钟unsignedchart_s=0;//秒unsignedchart_ms=0;//毫秒bitwatch_running=0;//秒表运行标志bitkey_pressed=0;//按键按下标志unsignedintkey_press_time=0;//按键按下时间/*数码管显示*/voidSMG_display(){DT_drv(7,t_ms%10);//显示毫秒个位Delay1ms(1);DT_drv(6,t_ms/10);//显示毫秒十位Delay1ms(1);DT_drv(5,26);//显示分隔符Delay1ms(1);DT_drv(4,t_s%10);//显示秒个位Delay1ms(1);DT_drv(3,t_s/10);//显示秒十位Delay1ms(1);DT_drv(2,26);//显示分隔符Delay1ms(1);DT_drv(1,t_min%10);//显示分钟个位Delay1ms(1);DT_drv(0,t_min/10);//显示分钟十位Delay1ms(1);}/*定时器0初始化*/voidInitTimer0(){AUXR&=0x7F; //定时器时钟12T模式 TMOD&=0xF0; //设置定时器模式 TL0=0xF0; //设置定时初值 TH0=0xD8; TF0=0; //清除TF0标志TR0=1; //定时器0开始计时ET0=1; //使能定时器0中断EA=1; //全局中断使能}/*定时器0中断服务*/voidServiceTimer0()interrupt1{if(watch_running){t_ms++;if(t_ms>=100)//100*10ms=1s{t_ms=0;t_s++;if(t_s>=60){t_s=0;t_min++;if(t_min>=60){t_min=0;}}}}if(key_pressed){key_press_time++;}}/*按键扫描*/voidScanKeys(){if(S4==0){Delay1ms(20);if(S4==0){key_pressed=1;key_press_time=0;while(S4==0){SMG_display();}key_pressed=0;if(key_press_time<100)//短按{watch_running=!watch_running;}else//长按{if(!watch_running){t_ms=0;t_s=0;t_min=0;}}}}}//主函数voidmain(){InitTimer0();//初始化定时器while(1){SMG_display();//显示时间ScanKeys();//扫描按键}}--------------------------第12章拓展训练题-------------------------12-1.在10.3节脉冲信号频率测量应用程序freqdector1.c或freqdector2.c中,添加串口功能,将测量的频率值实时上传到STC-ISP串口助手中实时显示。设显示格式为“x4x3x2x1x0Hz”,例如“12345Hz”。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"//内部变量定义unsignedintpulse_cnt=0;//脉冲计数值unsignedintfreq_value=0;//频率值//数码显示数据缓存区。设初始显示为"F(灭灭)00000"unsignedcharDTbuf[]={15,17,17,0,0,0,0,0};unsignedcharfreq_str[8];//频率字符串缓冲区bitflag_send_freq=0;//频率发送标志位voidFreqValue2buf(void);//函数声明//T0和T1初始化子程序voidTimer01Init(){TMOD=0x06;//T0计数模式2,T1定时模式0TH0=0xff;TL0=0xff;//计数器T0初值TH1=(65536-2000)/256;//T1用于2ms定时TL1=(65536-2000)%256;ET0=1;ET1=1;//允许T0和T1中断TR0=1;TR1=1;//启动T0和T1}voidUartInit(void)//9600bps@12.000MHz{SCON=0x50;//8位数据,可变波特率AUXR|=0x01;//串口1选择定时器2为波特率发生器AUXR&=0xFB;//定时器2时钟为Fosc/12,即12TT2L=0xE6;//设定定时初值T2H=0xFF;//设定定时初值AUXR|=0x10;//启动定时器2ES=1;EA=1;}//数字转字符串函数voidIntToStr(unsignedintnum,unsignedchar*str){unsignedchari=0;unsignedcharj=0;unsignedchartemp;if(num==0) {str[0]='0';str[1]='\0';return; }while(num>0) {str[i++]=(num%10)+'0';num/=10; } str[i]='\0';for(j=0;j<i/2;j++) {temp=str[j];str[j]=str[i-j-1];str[i-j-1]=temp;}}//串口发送一个字节voidSend_byte(unsignedcharTxData){SBUF=TxData;while(!TI);TI=0;}//串口发送字符串voidSend_string(unsignedchar*str){while(*str!='\0'){Send_byte(*str++);}}//定时器0中断服务程序voidTimer0isr()interrupt1{pulse_cnt++;}//定时器1中断服务程序voidTime1isr()interrupt3{staticunsignedinttimes=0;staticunsignedcharDTno=0xff;//数码管显示处理DTno++;DTno&=0x07;switch(DTno){case3:if(DTbuf[3])DT_drv(3,DTbuf[3]);elseDT_drv(3,17);break;case4:if(DTbuf[3]|DTbuf[4])DT_drv(4,DTbuf[4]);elseDT_drv(4,17);break;case5:if(DTbuf[3]|DTbuf[4]|DTbuf[5])DT_drv(5,DTbuf[5]);elseDT_drv(5,17);break;case6:if(DTbuf[3]|DTbuf[4]|DTbuf[5]|DTbuf[6])DT_drv(6,DTbuf[6]);elseDT_drv(6,17);break;default:DT_drv(DTno,DTbuf[DTno]);}//频率测量处理times++;if(times==500) {//1秒时间到freq_value=pulse_cnt;//获取频率值pulse_cnt=0;times=0;FreqValue2buf();flag_send_freq=1;//设置发送标志 }TH1=(65536-2000)/256;TL1=(65536-2000)%256;}//串口中断服务函数voidUART_RecvByte(void)interrupt4{if(RI) RI=0;//清除接收中断标志if(TI) TI=0;//清除发送中断标志}//将频率值分解为BCD存入数码显示缓冲区子程序voidFreqValue2buf(void){DTbuf[3]=freq_value/10000;DTbuf[4]=(freq_value/1000)%10;DTbuf[5]=(freq_value/100)%10;DTbuf[6]=(freq_value/10)%10;DTbuf[7]=freq_value%10;}//主程序voidmain(){LED_drv(0xff);//关LEDBEEP_off();//关蜂鸣器RELAY_off();//关继电器Timer01Init();//定时器初始化UartInit();//串口初始化while(1) {//检测到需要发送频率标志if(flag_send_freq) {flag_send_freq=0;IntToStr(freq_value,freq_str);Send_string(freq_str);Send_string("Hz\r\n");}}}--------------------------第13章拓展训练题-------------------------13-1.在超声波测距应用程序Ultrasound_DisMeasure.c中添加串口功能,将超声波测量的距离值上传到STC-ISP串口助手中实时显示。设显示格式为“x2x1x0.x-1cm”,例如“102.3cm”。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<stdio.h>sbitTX=P1^0;//超声波发射引脚sbitRX=P1^1;//超声波接收引脚unsignedcharDTbuf[8]={18,17,17,17,17,17,17,17};//数码管缓冲区,首位固定为'L'(18)chardistance_str[10];//串口输出缓冲区bitmeasure_flag=0;//测量标志unsignedintmeasure_count=0;//测量计数器//串口初始化(9600bps@12MHz)voidUartInit() {SCON=0x50;//8位数据,可变波特率AUXR|=0x01;//使用定时器2作为波特率发生器AUXR&=0xFB;//定时器2时钟为Fosc/12T2L=0xE6;//波特率设置T2H=0xFF;AUXR|=0x10;//启动定时器2 }charputchar(charc) {SBUF=c;while(!TI);TI=0;returnc; }//12us延时@12MHzvoidDelay12us() {unsignedchari=33;while(--i); }//发送8个40kHz脉冲voidSendWave() {unsignedchari;for(i=0;i<8;i++) {TX=1;Delay12us();TX=0;Delay12us();}}//测量距离voidMeasureDistance() {unsignedinttime,distance;unsignedchardecimal;//初始化定时器1(16位模式)TMOD&=0x0F;TMOD|=0x10;TH1=TL1=0;TF1=0;SendWave();//发送超声波TR1=1;//启动计时while(RX&&!TF1);//等待回波或超时TR1=0;//停止计时if(!TF1) {//有效测量time=(TH1<<8)|TL1;distance=(time*17)/1000;//计算整数部分(cm)decimal=((time*17)%1000)/100;//计算小数部分(0-9)//更新数码管显示DTbuf[0]=18;//'L'//百位DTbuf[4]=(distance>=100)?distance/100:17;//十位DTbuf[5]=(distance>=10)?(distance/10)%10:17;//个位和小数位DTbuf[6]=distance%10;DTbuf[7]=decimal;//手动构造串口输出字符串if(distance>=100) {distance_str[0]=(distance/100)+'0';distance_str[1]=((distance/10)%10)+'0';distance_str[2]=(distance%10)+'0';distance_str[3]='.';distance_str[4]=decimal+'0';distance_str[5]='c';distance_str[6]='m';distance_str[7]='\0'; }elseif(distance>=10) {distance_str[0]=((distance/10)%10)+'0';distance_str[1]=(distance%10)+'0';distance_str[2]='.';distance_str[3]=decimal+'0';distance_str[4]='c';distance_str[5]='m';distance_str[6]='\0'; }else {distance_str[0]=(distance%10)+'0';distance_str[1]='.';distance_str[2]=decimal+'0';distance_str[3]='c';distance_str[4]='m';distance_str[5]='\0'; }printf("%s\r\n",distance_str);}else {//超出范围TF1=0;DTbuf[0]=15;//'F'DTbuf[4]=DTbuf[5]=DTbuf[6]=DTbuf[7]=17;printf("Outofrange!\r\n"); }}voidDisplay(){staticunsignedchardigit=0;//当前显示的数码管位置ALL_off;switch(digit) {case0://显示标识位'L'DT_drv(0,DTbuf[0]);break;case4://显示百位if(DTbuf[4]!=17) {DT_drv(4,DTbuf[4]); }break;case5://显示十位if(DTbuf[5]!=17) {DT_drv(5,DTbuf[5]);}break; case6://显示个位(带小数点) if(DTbuf[6]!=17) {P0=SEGcode[DTbuf[6]]&0x7F;//带小数点DTseg_en;ALL_off;P0=0x40;//第6位数码管DTbit_en;}break;case7://显示小数位if(DTbuf[7]!=17) {DT_drv(7,DTbuf[7]); }break;}//指向下一个数码管digit++;if(digit>7)digit=0;}//定时器0初始化-用于数码管刷新voidTimer0Init() {TMOD&=0xF0;//清除定时器0模式位TMOD|=0x01;//设置定时器0为模式1(16位)TH0=0xFC;//设置定时初值,约1msTL0=0x66;ET0=1;//使能定时器0中断TR0=1;//启动定时器0 }//定时器0中断服务程序voidTimer0_ISR()interrupt1 {TH0=0xFC;//重新加载初值TL0=0x66;Display();//刷新数码管显示//测量计数器measure_count++;if(measure_count>=500) {//约500ms测量一次measure_count=0;measure_flag=1;//设置测量标志 }}voidmain(){BEEP_off();RELAY_off();LED_drv(0xFF);UartInit();Timer0Init();EA=1;//开总中断while(1){//检查测量标志if(measure_flag) {measure_flag=0;MeasureDistance(); } }}--------------------------第14章拓展训练题-------------------------14-1.在温度检测与显示应用程序CP14_DS18B20demo.c中添加串口功能,将检测的温度值上传至STC-ISP串口助手中实时显示。设温度显示的格式定义为“x1x0.x-1℃”,例如“23.5℃”。----------------------------------陕西科技大学信工231班赵馨怡同学解答-----------------------------#include<STC15F2K60S2.H>#include"user.c"sbitDQ=P1^4;//单总线DQ连接定义#include"onewire.c"//包含DS18B20底层驱动代码文件#include<stdio.h>unsignedcharBCDs,BCDg,BCDx;//温度值十位、个位和小数位BCDvoidUartInit(void) //9600bps@12.000MHz{ SCON=0x50; //8位数据,可变波特率 AUXR|=0x01; //串口1选择定时器2为波特率发生器 AUXR&=0xFB; //定时器2时钟为Fosc/12,即12T T2L=0xE6; //设定定时初值 T2H=0xFF; //设定定时初值 AUXR|=0x10; //启动定时器2 ES=1; EA=1;}externcharputchar(charch){ SBUF=ch; while(TI==0); TI=0; returnch;}//定时器T1初始化子程序voidTimer1Init(){//设置T1为定时器,模式0 TMOD&=0x0f;//位与后赋值TH1=(65535-50000)/256;//[12T]50ms定时,装初值TL1=(65535-50000)%256;ET1=1;//允许T1中断EA=1;//开放总中断 TR1

温馨提示

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

评论

0/150

提交评论