




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1第12章单片机应用实例2212.1单片机控制直流电机12.2单片机控制步进电机12.3单片机电子音乐设计12.4单片机频率计设计12.5SPI射频收发芯片NRF24L01接口设计12.6温度PID控制设计12.7GPS定位设计(增加?)12.8GSM远程报警设计(增加?)33第12章单片机应用实例本章介绍80C51单片机各种常用的测控应用设计案例,内容主要包括单片机与直流电机、步进电机接口设计,以及单片机电子音乐设计、频率计设计、SPI接口射频通信设计,通过案例介绍,使读者了解单片机系统的的各种常见的应用设计。12.1直流电动机的控制设计直流电动机是指将直流电能转换成机械能的旋转电机,多用在无交流电源、方便移动场合,具有低速大力矩等特点,因其良好的调速性能而在电力拖动中得到广泛应用。下面介绍单片机控制直流电机的工作原理、接口技术和应用案例。441.直流电动机的结构及其工作原理直流电机的结构应可分为定子和转子两大部分。直流电机运行时静止不动的部分称为定子,其作用是产生磁场,由机座、主磁极、换向极、端盖、轴承和电刷装置等组成。运行时转动的部分称为转子,其作用是产生电磁转矩和感应电动势,是直流电机能量转换的枢纽,又称为电枢,由转轴、电枢铁心、电枢绕组、换向器和风扇等组成。电动机定子提供磁场,直流电源向转子的绕组提供电流,换向器使转子电流与磁场产生的转矩保持方向不变。根据是否配置有电刷-换向器,可以将直流电动机分为两类,包括有刷直流电动机和无刷直流电动机。按照产生磁场的方式(励磁方式),直流电动机分为永磁、他励和自励3类,其中自励又分为并励、串励和复励3种。并励式直流电动机和串励式直流电动机如图12-1所示。55
直流电动机的工作原理:直流电机里边固定有环状永磁体,电流通过转子上的线圈产生安培力,当转子上的线圈与磁场平行时,再继续转受到的磁场方向将改变,因此此时转子末端的电刷跟换向片交替接触,从而线圈上的电流方向也改变,产生的洛伦兹力方向不变,所以电机能保持一个方向转动。66772.直流电动机的驱动方式直流电动机的驱动是通过把直流电源加到直流电动机上,使之旋转。常用的驱动元件有继电器、达林顿晶体管等,以晶体管控制直流电动机方向的桥式驱动为例,电路如图12-2所示,若送一个高电平信号到input1端,同时送一个低电平信号到input2端时,则电流从右向左流过此直流电动机。反之,若送一个低电平信号到input1端,同时送一个高电平信号到input2端时,则电流从左向右流过此直流电动机。88(a)晶体管控制电流由从右向左流过直流电动机99图12-2晶体管控制直流电动机方向的桥式驱动电路(a)晶体管控制电流从左向右流过直流电动机10103.直流电动机的PWM控制某些场合往往要求直流电机的转速在一定范围内可调节,例如,电车、机床等,调节范围根据负载的要求而定。调速可以有三种方法:(1)改变电机两端电压;(2)改变磁通;(3)在电枢回路中,串联调节电阻。其中,通过改变施加于电机两端的电压大小达到调节直流电机转速的目的是常用的方法。直流电机转速与施加电压成正比,输出转矩与电流成正比。在直流电机工作期间改变其速度的常见方法是施加一个PWM(脉冲宽度调制)脉冲波,其占空比对应于所需速度。此时电机相当于一个低通滤波器,将PWM信号转换为有效直流电平。1111
PWM控制是改变脉冲宽度来控制其平均值的方法,施加在直流电机的脉冲的电压平均值如图12-3所示,图中A脉冲平均电压为0.5,B脉冲平均电压为0.25。图12-3PWM脉冲波形及平均值1212
直流电机的转速与电机两端的电压成比例,而电动机两端的电压与PWM控制波形的占空比成正比,因此电动机的转速与PWM波形占空比成比例。占空比越大,电动机转得越快,当占空比α=1时,电动机转速最大。直流电机转速与PWM脉冲占空比关系图如图12-4所示。图12-4电动机转速与PWM脉冲占空比关系图13134.单片机与直流电动机的接口技术【例12-1】单片机以PWM方式输出模拟量控制直流电动机,电路图如图12-5所示,通过外接A/D转换电路,对应外部不同的电压,单片机产生占空比不同的控制脉冲,驱动直流电动机以不同的转速转动。通过外接的单刀双掷开关,控制电动机的正转和反转。图中直流电动机采用桥式驱动电路,调节电位器RV1,可以看到电机转速随着电位器的调节发生变化,电位器电压越高,速度越快,转速变化时的PWM信号变化如图12-6和图12-7所示。切换SW1状态可切换电机的正、反转。1414图12-5单片机以PWM方式控制直流电动机1515
参考程序如下:#include<reg51.h>#include<absacc.h>//定义绝对地址访问#defineucharunsignedchar#defineP0809XBYTE[0x0000]//通道0的地址sbitEOC=P2^0;sbitCLOCK=P2^3;sbitPWM=P1^0;voidDelay(unsignedintx)//延时1ms函数{ucharj;while(x--){for(j=0;j<60;j++);}}voidmain(void){uchartemp;PWM=1;1616EOC=1;TMOD=0x02; TH0=20; TL0=00; IE=0x82; TR0=1;while(1){ P0809=2;//启动通道2转换while(!EOC);temp=P0809; PWM=0; Delay(temp); PWM=1; temp=255-temp; Delay(temp); }}1717voidtime0()interrupt1{ CLOCK=~CLOCK;}图12-6转速较小时对应PWM信号1818图12-7转速较大时对应PWM信号191912.2单片机控制步进电机步进电机是将脉冲信号转变为角位移或线位移的开环控制电机,是数字控制系统中的主要执行元件。在非超载时,其转速、停止位置仅取决于脉冲信号的频率和脉冲数,不受负载变化的影响。步进驱动器每接收一个脉冲信号,驱动步进电机按一定方向转动一个固定的“步距角”,通过控制脉冲个数来控制角位移量,从而达到准确定位;例如某三相步进电机每个励磁信号前进7.5度,则每旋转一圈360度,需要48个励磁信号完成。步进电机也称为脉冲电机,可直接接收来自计算机的数字脉冲,使电机旋转过相应的角度。步进电机在要求快速启停,精确定位的场合做为执行部件,得到了广泛采用。
1.步进电机驱动原理步进电机的驱动是通过微控制器控制每相线圈中的电流的顺序切换来使电机作步进式旋转,改变各相脉冲的通断顺序,可以改变步进电机的旋转方向;调节脉冲信号的频率可改变步进电机的转速。2020
常用的四相步进电机的电机线圈由A、B、C、D四相组成,驱动方式有单相四拍工作方式、双四拍工作方式和四相八拍工作方式等3种,3种工作方式的线圈通电顺序如表12-1、表12-2和表12-3所示。
(1)单相四拍工作方式若电机正转,必须控制绕组A、B、C、D中通电顺序为:A→B→C→D→A;反转时,需要通电顺序为:A→D→C→B→A。步进电机在单相四拍方式下,每一瞬间只有一个线圈导通。消耗电力小,精确度良好,但转矩小,振动较大。
(2)四相八拍工作方式正转时,绕组通电顺序为:A→AB→B→BC→C→CD→D→DA→A;反向时,通电顺序为:A→AD→D→DC→C→CB→B→BA→A,在这种方式下,1相与2相轮流交替导通。分辨率较高,且运转平滑。
(3)双四拍工作方式正转时,需要控制绕组通电顺序为:AB→BC→CD→DA→AB;反向时,通电顺序为:BA→AD→DC→CB→BA。步进电机在这种方式下,每一瞬间会有二个线圈同时导通。因其转矩大,振动小,故为目前使用最多的励磁方式。2121表12-1单相四拍励磁顺序A→B→C→D→A顺序ABCD1100020100300104000151000
表12-2四相八拍工作方式A→AB→B→BC→C→CD→D→DA→A顺序ABCD1100021100301004011050010600117000181001910002222表12-3双四拍励磁顺序:AB→BC→CD→DA→AB顺序ABCD1110020110300114100151100综上所述,步进电机有如下特点:(1)其旋转角度与脉冲数成正比;(2)通过控制脉冲频率控制电机转动的速度和加速度,从而实现调速。(3)电机的正、反转可由脉冲顺序来控制。(4)改变各相的通电方式,可以改变电机的运行方式。23232.步进电机的应用实例【例12-2】为提高步进电机负载能力和运行平稳,可使用四相八拍驱动方式控制步进电机,电路图如图12-8所示,图中设置正、反转开关,另外设置6个开关K1-K6,用来控制6级转速。单片机读取正、反转命令信息,以及6级转速指示,由ULN2003A驱动步进电机转动。2424图12-8单片机6级转速控制步进电机2525
参考程序如下:#include"reg51.h"#defineucharunsignedchar#defineuintunsignedint#definekeyP2sbitz=P2^0; //正转控制P2.0sbitf=P2^1; //反转控制P2.1sbitspeed1=P2^2; //速度1sbitspeed2=P2^3; //速度2sbitspeed3=P2^4; //速度3sbitspeed4=P2^5; //速度4sbitspeed5=P2^6; //速度5sbitspeed6=P2^7; //速度6ucharcodephase[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};voidDelay(unsignedintx)//延时1ms函数{ucharj;while(x--){for(j=0;j<125;j++);}}2626voidmain(void){ uchari; uintm; key=0xff; while(1) { if(speed1==0){m=500;} elseif(speed2==0){m=200;} elseif(speed3==0){m=100;} elseif(speed4==0){m=50;} elseif(speed5==0){m=20;} elseif(speed6==0){m=5;} else{m=5;}
if(!z)//如果正转按键按下 { i=i<8?i+1:0;//如果i<8,则i=i+1;否则i=0 P1=phase[i]; Delay(m);}2727
elseif(!f) { i=i>0?i-1:7; P1=phase[i]; Delay(m); } }}12.3单片机电子音乐设计单片机控制扬声器,可以演奏各种电子音乐。1.音调产生原理单片机产生电子音调,可通过定时器产生不同频率的音符信号,控制音符延长时间,经过扬声器驱动电路,发出不同的音调。2.音符与频率的关系音乐的十二平均率规定:每两个八度音(如简谱中的中音1与高音1)之间的频率相差一倍。在两个八度音之间,又可分为十二个半音,每两个半音的频率之比为2的12次方根(1.0595)。2828C调音符与频率对照表如表12-4所示,音名A(简谱中的低音6)的频率为440HZ,音名B到C之间、E到F之间为半音,其余为全音。由此可以计算出简谱中从低音1至高音7之间每个音名符的频率,各信号频率不同,但都是从同一个基准频率分频得到的。由于分频系数不能为小数,计算得到的频率四舍五入取整。3.电子音调设计电子音阶可由不同音符对应不同频率的音频方波信号,其中,音频信号的高低电平持续时间可由定时器T0控制,T0设置初值后,每当定时时间到后,将单片机I/O口电平取反即得到音频信号。以低音"1"音频信号产生为例,低音"1"对应频率f=262Hz,则该音频信号高、低波形持续时间均为1/2*(1/f),设晶振fosc=11.0592Hz时,设定时器T0工作在方式1,定时器初值为X,则可得(1/2)*(1/f)=(12/fosc)*(216-X)即初值X=63777=0xF921
除了产生音频信号,还需要考虑音符的节拍,可以由延时子程序来实现,延时子程序实现基本延时时间,节拍值采用整数延时。2929表12-4C调音符与频率的关系表音符频率(Hz)音符频率(Hz)音符频率(Hz)低音1262中音1523高音11046低音1#277中音1#554高音1#1109低音2294中音2587高音21175低音2#311中音2#622高音2#1245低音3330中音3659高音31318低音4349中音4698高音41397低音4#370中音4#740高音4#1480低音5392中音5784高音51568低音5#415中音5#831高音5#1661低音6440中音6880高音61760低音6#466中音6#932高音6#1865低音7494中音7988高音719763030
【例12-3】单片机控制扬声器演奏电子音乐世上只有妈妈好。利用P3.0输出不同音频信号脉冲,控制音符延时,通过扬声器发出不同频率音调,电路图如图12-9所示。
程序设计思想:将简谱音乐的每个音符、该音符频率(由音符与频率表计算得到的定时器初值)、该音符节拍时间常数组成歌曲数组mother。主程序循环调用演奏函数Plays(uchar*Sound)。在演奏函数设计中,按照歌曲数组依次取得音符频率FH和FL,据此设置定时器T0初值,在定时时间到时,产生定时中断,在中断服务函数中将P3.0口取反产生音频信号,并控制扬声器通断,演奏函数中,通过该音符节拍时间常数控制该音频信号的出现时间。顺序播放整首乐曲。3131图12-9单片机控制扬声器演奏电子音乐3232参考程序如下:#include"Reg52.H"#include"stdio.H"typedef unsignedcharuchar;typedefunsignedintuint; sbitSpeaker=P3^0;uchar S_TH0,S_TL0;//定时器初值ucharSTime;//一拍时间 ucharcodeFH[]={//音阶频率表高八位 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音1,2,3,4,5,6,70xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音1,2,3,4,5,6,70xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF/高音1,2,3,4,5,6,7};ucharcodeFL[]={//音阶频率表低八位0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,//低音1,2,3,4,5,6,70x8F,0xEE,0x44,0x6B,0xB4,0xF4,0x2D,//中音1,2,3,4,5,6,733330x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16//高音1,2,3,4,5,6,7};ucharcodemother[]={6,2,3,5,2,1,3,2,2,5,2,2,1,3,2,6,2,1,5,2,1, 6,2,4,3,2,2,5,2,1,6,2,1,5,2,2,3,2,1,2,2,1, 1,2,1,6,1,1,5,2,1,3,2,1,2,2,4,2,2,3,3,2,1, 5,2,2,5,2,1,6,2,1,3,2,2,2,2,2,1,2,4,5,2,3, 3,2,1,2,2,1,1,2,1,6,1,1,1,2,1,5,1,6,0,0,0};voidDelayms(uintx){ uinti; while(x--) {for(i=0;i<125;i++); }}voidBeepTimer0()interrupt1{ Speaker=!Speaker; TH0=S_TH0;//重新赋定时器初值 TL0=S_TL0;}3434voidPlays(uchar*Sound){uinti=0,j;ucharb;uintSoundL; //歌曲长度 SoundL=0;while(Sound[SoundL++]!=0x00);//计算歌曲长度 while(i<SoundL){j=Sound[i]+7*(Sound[i+1]-1)-1; S_TH0=FH[j]; //音符频率S_TL0=FL[j];STime=Sound[i+2];//该音符时常 TH0=S_TH0;//定时器初值TL0=S_TL0;TR0=1;i+=3;//指向下一音符3535while(STime--)//控制音符时间{for(b=0;b<200;b++){ Delayms(1); } }TR0=0;Speaker=0;//关闭蜂鸣器 } }voidmain(){ TMOD=0x01;ET0=1; EA=1; while(1){Plays(mother);Delayms(500);}}363612.4单片机频率计设计利用单片机定时器与计数器配合或者定时器与外部中断配合,可实现信号频率测量。频率测量常用的方法有定时计数法(测频法)和定数计时法(测周法)、同步计数计时法(频率周期法)及其各种改进方法。测频法在计数时有±1的误差,频率低时误差比较大;测周法也有±1个时间单位误差,频率高时误差大;同步计数计时法综合了上述2种方法的优点,精度较高。本例采用较为常用的测频法。【例12-4】单片机测量数字时钟频率的电路原理图如图12-10所示,设单片机晶振频率为12MHz,利用计数器T0的P3.4引脚接入数字时钟信号,当按下开关K时,单片机计算出数字时钟信号频率,并在LCD1206上显示。
编程思路是:单片机利用T0计数中断和T1定时中断方式,设计T1定时50ms,选择方式1,每当T1定时时间50ms到时,统计定时到的次数,当1s时间到时,计算T0所计数的数字时钟个数,从而实现对频率的测定。LCD1206初始显示“PressKtostart”,当按下开关K后,开始T1定时和T0计数。由于T1定时时间50ms,T1初值为0x3cb0。TMOD=00010101B(0x15)。3737图12-10单片机测量方波频率3838参考程序如下:#include<reg51.h>#include<math.h>#include<stdio.h> #include<absacc.h>#include<intrins.h> //包含_nop_()空函数指令的头文件#defineucharunsignedchar#defineuintunsignedint#defineoutP1sbitRS=P2^2; //位变量sbitRW=P2^1; //位变量sbitE=P2^0; //位变量sbitK=P2^3;voidlcd_initial(void); //LCD初始化函数sbitDQ=P3^0;ucharconstasc[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};3939ucharT[8]="888888Hz";voidcheck_busy(void); //检查忙标志函数voidwrite_command(ucharcom); //写命令函数voidwrite_data(uchardat); //写数据函数voidstring(ucharad,uchar*s);voidLCD_initial(void);voidDelayus(ucharUs); //延时函数voidDelayms(uintMs);ucharPresencePlus;unsignedlongsum;uinttime_c,frey;ucharhunthbit,tenthbit,thdbit,hdbit,tenbit,unitbit;voidmain(){LCD_initial(); string(0x80,"PressKtostart");sum=0;frey=0;time_c=0; TMOD=0x15;//00010101,T1dingshiT0jishu4040TH1=0x3c;//50msTL1=0xb0;TH0=0x00;TL0=0x00;EA=1;ET0=1;ET1=1;while(K==1);//等待按键Kwrite_command(0x01); TR0=1;TR1=1;while(1){if(time_c==19)//1s到{time_c=0;TR1=0;Delayms(17);TR0=0;sum=frey*65536+TH0*256+TL0;}4141hunthbit=sum%1000000/100000;tenthbit=sum%100000/10000;thdbit=sum%10000/1000;hdbit=sum%1000/100;tenbit=sum%100/10;unitbit=sum%10; T[0]=asc[hunthbit];T[1]=asc[tenthbit];T[2]=asc[thdbit];T[3]=asc[hdbit];T[4]=asc[tenbit];T[5]=asc[unitbit];T[6]='H';T[7]='z';string(0x82,"frequency:");string(0xC2,T); }}
4242voidI0(void)interrupt1{frey++;} voidc0(void)interrupt3{TH1=0x3c;TL1=0xb0; time_c++; }voidcheck_busy(void) //检查忙标志函数{ uchardt; do { dt=0xff; E=0; RS=0; RW=1;E=1;4343dt=out;}while(dt&0x80);E=0;}voidwrite_command(ucharcom) //写命令函数{check_busy();E=0;RS=0;RW=0;out=com;E=1;_nop_();E=0;Delayms(1);}4444voidwrite_data(uchardat) //写数据函数{ check_busy(); E=0; RS=1; RW=0; out=dat; E=1; _nop_(); E=0; Delayms(1); }voidLCD_initial(void) //液晶显示器初始化函数{write_command(0x38);//写入命令0x38:8位两行显示,5×7点阵字符4545write_command(0x0C);//写入命令0x0C:开整体显示,光标关,无黑块write_command(0x06);//写入命令0x06:光标右移write_command(0x01);//写入命令0x01:清屏Delayms(1);}voidstring(ucharad,uchar*s) //输出显示字符串的函数{write_command(ad);while(*s>0){write_data(*s++); //输出字符串,且指针增1}}voidDelayms(uintMs)//毫秒延时{ uchari; while(Ms--) { for(i=0;i<112;i++);/*大概1MS,不精确*/ }}464612.5SPI射频收发芯片nRF24L01接口设计nRF24L01是挪威NORDIC公司出品的一款新型射频收发器件,采用4mm*4mmQFN20封装;nRF24L01无线射频模块工作于ISM频段:2.4~2.5GHz。该芯片具有功率放大器、频率合成器、调制器和晶体振荡器等功能,它还兼容了增强型ShockBurst技术,其中通信频道、输出功率和地址都可以通过程序进行配置,适合用于多机通信。nRF24L01功耗低,不仅有接收模式和发送模式,还有多种低功耗工作模式,即掉电模式和空闲模式,发射功率-6dBm时,工作电流仅9mA;接收数据时,工作电流仅12.3mA。nRF24L01这种低功耗特点在世界领先,nRF24L01更加适合采用纽扣电池供电的2.4G应用。1.nRF24L01无线模块的引脚nRF24L01模块有20个引脚,表12-5为nRF24L01无线模块的8个主要管脚说明。内置2.4GHz天线。模块内置专门的稳压电路,使用不同电源都能实现很好通信效果。4747
表12-5nRF24L01管脚说明2.nRF24L01工作模式nRF24L01有四种工作模式:收发模式、配置模式、空闲模式、关机模式。具体工作模式说明见表12-6所示。1)收发模式:有EnhancedShockBurstTM收发模式、ShockBurstTM收发模式和直接收发模式3种。2)空闲模式:空闲模式即待机模式,工作电流由外部的晶振频率决定。可以减少平均工作电流,避免浪费能源,减少启动时间。3)关机模式:既掉电模式,最小工作电流仅900nA,并保证配置字内容不会丢失。4)配置模式:通过SPI完成配置工作,共30字节的配置字。48483.nRF24L01配置寄存器及模式转换单片机系统通过I/O口模拟SPI方式控制nRF24L01无线模块,通过配置字控制nRF24L01处理射频协议,实现各种模式间的转换,改变最低位字就可以切换接收和发送模式,常用配置寄存器见表12-6。表12-6常用配置寄存器地址(H)寄存器名称功能00CONFIG设置nRF24L01工作模式01EN_AA设置接收通道及自动应答02EN_RXADDR使能接收通道地址03SETUP_AW设置地址宽度04SETUP_RETR设置自动重发数据时间和次数07STATUS状态寄存器,用于判断状态0A~0FRX_ADDR_PO~P5设置接收通道地址10TX_ADDR设置发送地址11~16RX_PW_P0~P5设置接收通道的有效数据宽度
nRF24L01工作模式由发射/接收控制引脚CE和CONFIG寄存器内部PWR_UP、PRIM_RX共同控制,具体如表12-7所示。4949表12-7nRF24L01无线模块工作模式模式PWR_UPPRIM_RXCEFIFO寄存器状态接收模式111-发射模式I101数据在TXFIFO寄存器中发射模式II101→0停留在发射模式,直到数据发送完待机模式I1-0无正在传输的数据待机模式II101TXFIFO为空掉电模式0---
4.工作原理(1)nRF24L01发送数据单片机将数据通过I/O口模拟SPI串口给无线模块nRF24L01,由nRF24L01发送,需要先将nRF24L01配置为发射模式,再按照SPI时序将发送地址和有效数据写进缓冲区,在片选CSN为0时,连续写入有效数据,在发射时写入接收节点地址,然后CE置1保持15μS并延迟130μS后发送数据。同时要开启自动应答,然后进入接收模式,等待接收应答信号。在此过程中,自动应答接收地址和接收节点地址要保持一致。如果接收到应答信号,则表明通信成功。TX_DS置1,同时清除有效数据。如果没有收到应答信号,则表明通信成功。TX_DS置1,同时清除有效数据。5050如果没有收到应答,就需要重新发送。同时设置最大重发次数,当达到最大重发次数时,MAX_RT置1,TX_FIFO保留数据重新发送。当MAX_RT或者TX_DS置1时,IRQ为1会产生中断。发射成功后,CE为0则无线模块进入空闲模式1,如果发送堆栈里有数据并且CE为1,则继续发送。如果没有数据而CE为1就进入待机模式II。
(2)nRF24L01接收数据在nRF24L01无线接收数据时,先将nRF24L01配置为接收模式,延时130μS后等待数据到来接收。接收方检测到有效地址和CRC时,就将数据包存在RXFIFO中,将RX_DR置1,IRQ置0进入中断,同时返回确认接收的应答信号,接收成功后CE变低,无线模块进入待机模式I,然后单片机通过SPI口读取数据。
5.nRF24L01接口应用下面通过一个案例,介绍如何实现单片机利用SPI接口实现射频通信。【例12-5】单片机甲采用温度传感器DS18B20采集温度,将温度值处理后,单片机甲用I/O口模拟SPI时序与SPI收发接口nRF24L01通信,实现对温度值的无线发送,单片机甲与nRF24L01接口发送电路如图12-11所示;单片机乙通过模拟SPI时序与nRF24L01通信,实现无线接收温度值,接收温度后显示在LCD12864上,单片机乙与nRF24L01接口芯片接收电路如图12-12所示。5151
其中,CE是模式控制线,CE为低和CONFIG共同决定nRF24L01的状态。CSN是nRF24L01片选线,CSN为0时芯片工作,MOSI是单片机输出数据控制线,MISO是单片机输入数据控制线。IRQ是中断信号,当FIFO发完数据并收到使能ACK时、RXFIFO收到数据和达到最大重发次数时,触发低电平,中断会得到响应。程序设计中,单片机甲首先将温度模块采集的温度数据通过模拟SPI串口给无线模块,由无线模块发送。需要先将nRF24L01配置为发射模式,再按照SPI时序将发送地址和有效数据写进缓冲区,在CSN为0时,连续写入有效数据,在发射时写入一次接收节点地址,然后CE置1保持15μS并延迟130μS后发送数据。同时要开启了自动应答然后进入接收模式,等待接收应答信号。在此过程中,自动应答接收地址和接收节点地址要保持一致。如果接收到应答信号,则表明通信成功。TX_DS置1,同时清除有效数据。如果没有收到应答,就需要重新发送。同时设置最大重发次数,当达到最大重发次数时,MAX_RT置1,TX_FIFO保留数据重新发送。当MAX_RT或者TX_DS置1时,IRQ为1会产生中断。发射成功后,CE为0则无线模块进入空闲模式1,如果发送堆栈里有数据并且CE为1,则继续发送。如果没有数据而CE为1就进入待机模式II。5252
在无线接收温度数据时,先将nRF24L01配置为接收模式,延时130μS后等待数据到来接收。接收方检测到有效地址和CRC时,就将数据包存在RXFIFO中,返回确认接收的应答信号,置位状态寄存器中的接收位RX_OK,并硬件置IRQ引脚为低电平等待单片机查询,同时接收成功后CE变低,无线模块进去待机模式1,然后单片机通过SPI口读取数据。图12-11单片机与nRF24L01组成发送数据接口5353图12-12nRF24L01与单片机组成接收数据接口
单片机甲通过DS18B20采集温度,并通过SPI射频收发芯片nRF24L01发送温度值的参考程序如下:#include"reg52.h"#include"intrins.h"#include"process.h" #defineucharunsignedchar#defineuintunsignedint /**********NRF24L01寄存器操作命令***********/5454#defineREAD_REG0x00//读配置寄存器,低5位为寄存器地址#defineWRITE_REG0x20//写配置寄存器,低5位为寄存器地址#defineRD_RX_PLOAD0x61//读RX有效数据,1~32字节#defineWR_TX_PLOAD0xA0//写TX有效数据,1~32字节#defineFLUSH_TX0xE1//清除TXFIFO寄存器.发射模式下用#defineFLUSH_RX0xE2//清除RXFIFO寄存器.接收模式下用#defineREUSE_TX_PL0xE3//重新使用上一包数据,CE为高,数据包被不断发送.#defineNOP0xFF//空操作,可以用来读状态寄存器 /**********NRF24L01寄存器地址*************/#defineCONFIG0x00//配置寄存器地址#defineEN_AA0x01//使能自动应答功能#defineEN_RXADDR0x02//接收地址允许#defineSETUP_AW0x03//设置地址宽度(所有数据通道)#defineSETUP_RETR0x04//建立自动重发#defineRF_CH0x05//RF通道#defineRF_SETUP0x06//RF寄存器#defineSTATUS0x07//状态寄存器#defineOBSERVE_TX0x08//发送检测寄存器5555#defineCD0x09//载波检测寄存器#defineRX_ADDR_P00x0A//数据通道0接收地址#defineRX_ADDR_P10x0B//数据通道1接收地址#defineRX_ADDR_P20x0C//数据通道2接收地址#defineRX_ADDR_P30x0D//数据通道3接收地址#defineRX_ADDR_P40x0E//数据通道4接收地址#defineRX_ADDR_P50x0F//数据通道5接收地址#defineTX_ADDR0x10//发送地址寄存器#defineRX_PW_P00x11//接收数据通道0有效数据宽度(1~32字节)#defineRX_PW_P10x12//接收数据通道1有效数据宽度(1~32字节)#defineRX_PW_P20x13//接收数据通道2有效数据宽度(1~32字节)#defineRX_PW_P30x14//接收数据通道3有效数据宽度(1~32字节)#defineRX_PW_P40x15//接收数据通道4有效数据宽度(1~32字节)#defineRX_PW_P50x16//接收数据通道5有效数据宽度(1~32字节)#defineFIFO_STATUS0x17//FIFO状态寄存器/******STATUS寄存器bit位定义*******/#defineMAX_TX 0x10 //达到最大发送次数中断#defineTX_OK 0x20 //TX发送完成中断#defineRX_OK 0x40 //接收到数据中断5656/*********24L01发送接收数据宽度定义 ***********/#defineTX_ADR_WIDTH5//5字节地址宽度#defineRX_ADR_WIDTH5//5字节地址宽度#defineTX_PLOAD_WIDTH32//32字节有效数据宽度#defineRX_PLOAD_WIDTH32//32字节有效数据宽度sbitNRF_CE=P2^5;sbitNRF_CSN=P2^4;sbitNRF_SCK=P2^3;sbitNRF_MOSI=P2^2;sbitNRF_MISO=P2^1;sbitNRF_IRQ=P2^0;externucharrece_buf[32];voiddelay_us(ucharnum);voiddelay_150us();voiddelay(uintt);ucharSPI_RW(ucharbyte);ucharNRF24L01_Write_Reg(ucharreg,ucharvalue);ucharNRF24L01_Read_Reg(ucharreg);ucharNRF24L01_Read_Buf(ucharreg,uchar*pBuf,ucharlen);ucharNRF24L01_Write_Buf(ucharreg,uchar*pBuf,ucharlen);5757ucharNRF24L01_RxPacket(uchar*rxbuf);ucharNRF24L01_TxPacket(uchar*txbuf);ucharNRF24L01_Check(void);voidNRF24L01_RT_Init(void);voidSEND_BUF(uchar*buf);#defineucharunsignedchar#defineuintunsignedint;sbitDQ=P1^5;//ds18b20端口intReadOneTemperature(void);intGetTpData(unsignedcharNum);bitInit_DS18B20(void);unsignedcharReadOneChar(void);voidWriteOneChar(unsignedchardat);voidReadNum(unsignedchar*Ptr);unsignedcharSysTime;unsignedcharrece_buf[32];unsignedintTempData;
5858voidInitTimer0(void) //定时器 T0方式1{ TMOD|=0x01; //定时1MS TH0=0xFC; //fbc2ec78 252 TL0=0x17; //23 EA=1; //65536-64535=1000微秒=1ms ET0=1; TR0=1;}voidet0()interrupt1using0 //中断服务程序{ TH0=0xFC; //fc17ec78 TL0=0x17;
SysTime++;}5959constucharTX_ADDRESS[TX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF};//发送地址constucharRX_ADDRESS[RX_ADR_WIDTH]={0xFf,0xFF,0xFF,0xFF,0xFF};//发送地址voiddelay_us(ucharnum){ uchari; for(i=0;i>num;i++) _nop_();}voiddelay_150us(){ uinti; for(i=0;i>150;i++);}
6060
voiddelay(uintt){ uchark; while(t--) for(k=0;k<200;k++);}ucharSPI_RW(ucharbyte){ ucharbit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++)//输出8位 { NRF_MOSI=(byte&0x80); //MSBTOMOSI byte=(byte<<1); //shiftnextbittoMSB NRF_SCK=1; //时钟控制线 byte|=NRF_MISO; //capturecurrentMISObit } returnbyte;}6161
/*********************************************//*函数功能:给24L01的寄存器写值(一个字节)*//*入口参数:reg要写的寄存器地址*//*value给寄存器写的值*//*出口参数:status状态值*//*********************************************/ucharNRF24L01_Write_Reg(ucharreg,ucharvalue){ ucharstatus; NRF_CSN=0;//CSN=0; status=SPI_RW(reg); //发送寄存器地址,并读取状态值 SPI_RW(value); NRF_CSN=1;//CSN=1; returnstatus;}/*************************************************//*函数功能:读24L01的寄存器值(一个字节)*//*入口参数:reg要读的寄存器地址*//*出口参数:value读出寄存器的值*//*************************************************/6262ucharNRF24L01_Read_Reg(ucharreg){ ucharvalue; NRF_CSN=0;//CSN=0; SPI_RW(reg); //发送寄存器值(位置),并读取状态值 value=SPI_RW(NOP); NRF_CSN=1; //CSN=1; returnvalue;}/*函数功能:读24L01的寄存器值(多个字节)*//*入口参数:reg寄存器地址*//**pBuf读出寄存器值的存放数组*//*len数组字节长度*//*出口参数:status状态值*/ucharNRF24L01_Read_Buf(ucharreg,uchar*pBuf,ucharlen){ ucharstatus,u8_ctr; NRF_CSN=0;//CSN=0 status=SPI_RW(reg); //发送寄存器地址,并读取状态值 for(u8_ctr=0;u8_ctr<len;u8_ctr++) pBuf[u8_ctr]=SPI_RW(0XFF); //读出数据
6363
NRF_CSN=1; //CSN=1 returnstatus; //返回读到的状态值}/*函数功能:给24L01的寄存器写值(多个字节)*//*入口参数:reg要写的寄存器地址*//**pBuf值的存放数组*//*len数组字节长度*/ucharNRF24L01_Write_Buf(ucharreg,uchar*pBuf,ucharlen){ ucharstatus,u8_ctr; NRF_CSN=0; status=SPI_RW(reg); //发送寄存器值(位置),并读取状态值 for(u8_ctr=0;u8_ctr<len;u8_ctr++) SPI_RW(*pBuf++); //写入数据 NRF_CSN=1; returnstatus; //返回读到的状态值} 6464/*********************************************//*函数功能:24L01接收数据*//*入口参数:rxbuf接收数据数组*//*返回值:0成功收到数据*//*1没有收到数据*//*********************************************/ucharNRF24L01_RxPacket(uchar*rxbuf){ ucharstate;state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG+STATUS,state);//清除TX_DS或MAX_RT中断标志 if(state&RX_OK) //接收到数据{ NRF_CE=0; NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RXFIFO寄存器 NRF_CE=1;
6565
delay_150us(); return0; } return1;//没收到任何数据}/*函数功能:设置24L01为发送模式*//*入口参数:txbuf发送数据数组*//*返回值;0x10达到最大重发次数,发送失败*//*0x20成功发送完成*//*0xff发送失败*/ucharNRF24L01_TxPacket(uchar*txbuf){ ucharstate; NRF_CE=0; //CE拉低,使能24L01配置NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写32B到TXBUF NRF_CE=1; //CE置高,使能发送 while(NRF_IRQ==1); //等待发送完成 state=NRF24L01_Read_Reg(STATUS);//读取状态寄存器的值 6666NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志 if(state&MAX_TX) //达到最大重发次数 { NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TXFIFO寄存器 returnMAX_TX; } if(state&TX_OK) //发送完成 { returnTX_OK; } return0xff; //发送失败}/*函数功能:检测24L01是否存在*//*返回值;0存在*//*1不存在*/ 6767ucharNRF24L01_Check(void) //检测无线是否存在{ ucharcheck_in_buf[5]={0x11,0x22,0x33,0x44,0x55}; ucharcheck_out_buf[5]={0x00}; NRF_SCK=0; NRF_CSN=1; NRF_CE=0; NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,check_in_buf,5); NRF24L01_Read_Buf(READ_REG+TX_ADDR,check_out_buf,5); if((check_out_buf[0]==0x11)&&\ (check_out_buf[1]==0x22)&&\ (check_out_buf[2]==0x33)&&\ (check_out_buf[3]==0x44)&&\ (check_out_buf[4]==0x55))return0; elsereturn1;} 6868voidNRF24L01_RT_Init(void){ NRF_CE=0; NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//通道0效数据宽度 NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RXFIFO寄存器 NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH);//设置TX节点地址,主要为了使能ACK NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);//使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us+86us;6969
最大自动重发次数:10次 NRF24L01_Write_Reg(WRITE_REG+RF_CH,0);//设RF2.400GHz=2.4+0GHz NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0F);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 NRF_CE=1; //CE置高,使能发送}voidSEND_BUF(uchar*buf){ NRF_CE=0; NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e); NRF_CE=1; delay_us(15); NRF24L01_TxPacket(buf); NRF_CE=0; NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f); NRF_CE=1; }7070unsignedcharcodeSensor0[8]={0x28,0x30,0xC5,0xB8,0x00,0x00,0x00,0x8E};unsignedcharcodeSensor1[8]={0x28,0x31,0xC5,0xB8,0x00,0x00,0x00,0xB9};unsignedcharcodeSensor2[8]={0x28,0x32,0xC5,0xB8,0x00,0x00,0x00,0xE0};/*------------------------------------------------uS延时函数,含有输入参数unsignedchart,无返回值unsignedchar是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5uS------------------------------------------------*/voidDelayUs2x(unsignedchart){while(--t);}/*mS延时函数,含有输入参数unsignedchart,无返回值unsignedchar是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编*/7171
voidDelayMs(unsignedchart){while(t--)//大致延时1mS{DelayUs2x(245); DelayUs2x(245);}}/*18b20初始化*/bitInit_DS18B20(void){bitdat=0;DQ=1;//DQ复位DelayUs2x(5);//稍做延时DQ=0;//单片机将DQ拉低DelayUs2x(200);//精确延时大于480us小于960usDelayUs2x(200);DQ=1;//拉高总线DelayUs2x(50);//15~60us后接收60-240us的存在脉冲7272dat=DQ;//如果x=0则初始化成功,x=1则初始化失败DelayUs2x(25);//稍作延时返回returndat;}unsignedcharReadOneChar(void){unsignedchari=0;unsignedchardat=0;for(i=8;i>0;i--){DQ=0;//给脉冲信号dat>>=1;DQ=1;//给脉冲信号DelayUs2x(25);}return(dat);}
7373voidWriteOneChar(unsignedchardat){unsignedchari=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;DelayUs2x(25);DQ=1;dat>>=1;}DelayUs2x(25);}/*读取温度*/intReadOneTemperature(void){ unsignedchara=0;unsignedintb=0; intt=0;7474Init_DS18B20(); WriteOneChar(0xCC);//跳过读序号列号的操作 WriteOneChar(0x44);//启动温度转换 DelayMs(10); Init_DS18B20(); WriteOneChar(0xCC);//跳过读序号列号的操作 WriteOneChar(0xBE);//读取温度寄存器等,前两个就是温度 a=ReadOneChar();//低位 b=ReadOneChar();//高位
b<<=8; t=a|b; return(t);}main(){ InitTimer0(); ReadTemperature(); while(NRF24L01_Check());//等待检测到NRF24L01,程序才会向下执行
7575NRF24L01_RT_Init(); for(;;) //死循环 { StartPro(0); TempData=ReadOneTemperature(); rece_buf[1]=TempData>>8; rece_buf[2]=TempData; // rece_buf[0]=2; // SEND_BUF(rece_buf); EndPro(100); }}单片机乙模拟SPI时序通过接收温度,并在LCD12868上显示温度,参考程序如下:#include"reg52.h"#include"intrins.h"7676#include"process.h"#defineLCD_DATA1#defineLCD_COMMAND0#defineLCD_PORTP1 //端口定义,数据口sbitLCD_RS=P3^7; //寄存器选择输入sbitLCD_RW=P3^6; //液晶读写控制sbitLCD_EN=P3^5; //液晶使能控制sbitLCD_PSB=P2^1; //串/并方式控制sbitLCD_RST=P2^0; //复位 voidLCD_Write(unsignedchardat,unsignedchartype);voidLcdDisData(unsignedcharRow,unsignedcharLine,unsignedchar*Ptr);voidLCD_INITIALIZE(void);voidSetPos(unsignedcharRow,unsignedcharLine); #defineucharunsignedchar#defineuintunsignedint/**********NRF24L01寄存器操作命令***********/#defineREAD_REG0x00//读配置寄存器,低5位为寄存器地址#defineWRITE_REG0x20//写配置寄存器,低5位为寄存器地址7777#defineRD_RX_PLOAD
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 体育与健康人教初中年级《快乐奔跑》教学设计
- Revision2(教学设计)-2024-2025学年人教精通版(2024)英语三年级上册
- 2025年金属复合材项目发展计划
- 小学信息技术第三册 第14课网上来信-收发电子邮件及附件3教学实录 河大版
- Unit 6 Colours(教学设计)-2024-2025学年人教精通版英语三年级下册
- 162号令新规全文
- 36岁,人生半熟散文
- 八年级物理上册 1.2运动的描述教学实录 (新版)新人教版
- mos表面钝化层成分
- 八年级生物上册 5.4.5 人类对细菌和真菌的利用教学实录 (新版)新人教版
- 2025年初级社会工作者综合能力全国考试题库(含答案)
- 2024年全国国家版图知识竞赛题库及答案(中小学组)
- 斯瓦希里语轻松入门
- 拼音田字格(A4 word 打印版)
- 教育部人文社科项目申请书范本-2-副本
- GA∕T 743-2016 闪光警告信号灯
- 珍爱生命预防溺水 安全教育主题班会PPT课件
- 呼吸内科实习生出科考试试题卷与答案
- 完整版专家信息登记表
- 比例的应用评课
- 5米以上深基础专项施工方案
评论
0/150
提交评论