1普通IO口控制硬件连接如图1-1所示[P1_0]-[LED1],[P1_1]-[LED2],[P1_4/CSN]-[LED3],其中P1_4/CSN引脚与调试器的引脚复用,若使其正常工作,需拔下调试器,使用串口供电。图1-1LED硬件连接在进行IO口操作时,首先需要设置IO口的工作方式,常用到PxSEL,PxDIR,PxINP,其中x为0,1,2,表示0,1,2组IO口。如图1-2所示,PxSEL设置IO口功能,默认为0,即通用IO;值1表示外设功能。PxDIR设置输入输出,默认为0,即输入;值1表示输出。PxINP设置IO输入时,是否使用芯片内部的上下拉电阻,详细设置可以查询CC2530芯片手册。图1-2设置IO口寄存器1.1输出/*程序功能:三个LED灯顺序闪烁*/#includeioCC2530.h/*无符号八位数据类型*/#defineuintunsignedint#defineucharunsignedchar/*IO端口映射*/#defineLED1P1_0#defineLED2P1_1#defineLED3P1_4/*函数声明*/voiddelay(uint);//延时voidinitIO();//初始化IO口//入口voidmain(){initIO();while(1){LED1=!LED1;delay(20000);LED2=!LED2;delay(20000);LED3=!LED3;delay(20000);}}//延时voiddelay(uintx){uniti;for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);}//初始化IO口voidinitIO(){P1DIR|=0x13;LED1=1;LED2=1;LED3=1;}1.2输入开关S1的硬件连接如图1-3所示,芯片外部另接有上拉电阻,所以P0_1口的输入模式应设置为三态模式,当开关S1断开时,由于上拉电阻的存在,P0_1值为1,当开关S2闭合时,高电压直接到地,所以此时P0_1值为0。图1-3开关硬件连接(1)首先设置P0_1为普通IO,其实不用设置也是可行的,因为芯片默认为普通IO。P0SEL&=~0x02;//置0,且不更改其它位的值(~0x02==11111101)(2)然后设置P0_1为输入模式,其实不用设置也可以,默认为输入模式。P0DIR&=~0x02;(3)设置P0_1为三态,即不使用芯片内部上下拉电阻。P0INP|=0x02;//置1,且不更改其它位的值(0x02==00000010)当设置相关寄存器后,可以进行输入检测了,可以使用ucharkeyScan()函数来检测S1是否按下,如下程序所示,当按键按下并抬起时,函数返回1,若无按键按下,则函数返回0。ucharkeyScan(){if(S1==0){delay(100);if(S1==0)//再次检测消除瞬时低电平的干扰{while(S1==0);//等待按键S1抬起return1;}}return0;}1.3中断在CC2530中,有18个中断源,每个中断源都有各自的控制位、标志位和使能位。图1-4给出了18个中断源的中断向量,图1-5给出了P0组IO口作为中断源时的触发流程。图1-4中断向量图1-5P0组IO口中断触发流程若使用按键S1(P0_1)中断,需要进行以下工作:(1)设置P0SEL寄存器,使P0_1作为普通IO口;(2)设置P0DIR寄存器,使P0_1作为输入;(3)设置P0INP寄存器,上下拉或三态模式,若外部接有上下拉电阻,则应选择三态模式;(4)清零P0IFG寄存器中的第1位,避免程序误入中断;(5)设置PICTL寄存器中的第0位(P0组IO口),默认为0,上升沿触发,1为下降沿触发;(6)设置P0IEN寄存器,使能P0_1口(第1位)中断;(7)设置IEN0寄存器中的EA位(第7位),开启中断总开关;(8)设置IEN1寄存器中的P0IE位(第5位),开启P0组IO口中断开关;(9)设置中断向量函数。在程序进入中断向量函数时,中断函数需要完成以下工作:(1)判断是否为P0_1促发的中断,方法为判断P0IFG寄存器中的第1位;(2)清零P0IFG寄存器中的第1位(P0_1)。(3)处理中断任务;(4)清零P0IF寄存器中的第1位(P0_1)。/*按下BTN1时LED1和LED2状态切换*/#includeioCC2530.h#defineuintunsignedint#defineucharunsignedchar#defineLED1P1_0#defineLED2P1_1#defineBTN1P0_1voiddelay(uintx);voidinitLED();voidinitBTNandInterrupt();uintInterruptCount=0;voidmain(){initLED();initBTNandInterrupt();while(1){if(InterruptCount==1){LED1=!LED1;LED2=!LED2;InterruptCount=0;}}}voiddelay(uintx){uinti;for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);for(i=0;ix;i++);}voidinitLED(){P1SEL&=~0x03;//bit0,1cls0fornormalioP1DIR|=0x03;//bit0,1set1foroutputP1INP|=0x03;//bit0,1set1fornores}voidinitBTNandInterrupt(){P0SEL&=~0x02;//bit1cls0P0DIR&=~0x02;//bit1cls0P0INP|=0x02;//bit1set1P0IFG&=~0x02;//bit1cls0PICTL|=0x01;//bit0set1fordowntriggerP0IEN|=0x02;//bit1set1EA=1;P0IE=1;}#pragmavector=P0INT_VECTOR__interruptvoidinterrupt_p0_down_trigger(){if(P0IFG&0x02){P0IFG&=~0x02;delay(200);if(!(P0IFG&0x02)){delay(200);InterruptCount+=1;}}P0IF&=~0x02;}2定时器2.1查询方式通过查询的方式使用定时器T1(16位)时,需要用到2个寄存器,如图2-1和图2-2所示的T1CTL寄存器和IRCON寄存器。图2-1T1CTL寄存器图2-2IRCON寄存器外部晶振32MHz,默认情况下,CC2530的频率为外部晶振的2分频,即16MHz。对于T1CTL寄存器来说,128分频的意思是16MHz的128分频。若将T1CTL设置为0x0D,即128分频的自由运行模式,那么16MHz/128=125000,即1秒能执行125000条单周期指令,那么0000到FFFF则需要计数65536次,65536/125000=0.524288,即计数溢出一次的时间约为0.5秒,溢出两次的时间就为1秒。每次溢出时,IRCON.T1IF(第1位)都会被置1,通过查询的方式查询IRCON.T1IF位,可以判断是否计数溢出,接着手动清零IRCON.T1IF位即可。/*切换LED1状态,周期为1秒*/#includeioCC2530.h#defineuintunsignedint#defineucharunsignedchar#defineLED1P1_0voidmain(){uintFlowCount=0;P1DIR|=0x01;LED1=0;T1CTL=0x0D;//freqdiv128andfree-runningmodelwhile(1){if(IRCON&0x02){IRCON&=~0x02;FlowCount++;if(FlowCount=2){FlowCount=0;LED1=!LED1;}}}}2.2中断方式通过中断的方式使用定时器T3(8位)时,首先需要配置T3的工作方式:(1)设置T3CTL寄存器,具体内容如图2-3所示;(2)设置IEN1.T3IE位(第1位)为1,使能T3中断;(3)设置EA位1,开启中断总开关。图2-3T3CTL寄存器/*LED1灯暗1秒,亮1秒*/#includeioCC2530.h#defineuintunsignedint#defineucharunsignedchar#defineLED1P1_0uintFlowCount1=0;uintFlowCount2=0;voidmain(){P1DIR|=0x01;LED1=0;T3CTL|=0x08;//bit3set1,enableinterruptT3IE=1;//enableinterruptT3CTL|=0xE0;//freqdiv128T3CTL&=~0x03;//freerunning0x00to0xFFT3CTL|=0x10;//startT3EA=1;//enableEAwhile(1){}}#pragmavector=T3_VECTOR__interruptvoidT3_ISR(){//N/(16000000/128)=1getN=125000(freqdiv128)//FlowCount=N/256=488(freerunning0x00to0xFF)//488=00000001(FlowCount2)11101000(FlowCount1)IRCON&=~0x08;FlowCount1++;if(FlowCount1==255){FlowCount1=0;FlowCount2++;}if(FlowCount2=0x01){if(FlowCount1=0xE8){FlowCount1=0;FlowCount2=0;LED1=!LED1;}}}3串口UART0通信3.1发送(CC2530-COM)CC2530默认的时钟是芯片内部16MHz的震荡电路,但典型波特率是以32MHz设置的,如图3-1所示,所以需要设置CC2530的时钟频率为32MHz:(1)设置CLKCONCMD.OSC位(第6位)为0,即使用32MHz外部晶振晶振源;(2)等待晶振稳定,方法是判断CLKCONSTA.OSC位(第6位)的值;(3)设置CLKCONCMD.CLKSPD为000,即系统频率为32MHz,串口波特率基于此值;要使用UART0,首先要确定RT,CT,TX,RX在IO口的映射,可以通过设置PERCFG寄存器来实现,如图3-1为PERCFG寄存器,图3-2为UART0在IO口的映射。图3-1PERCFG寄存器图3-2UART0在IO口的映射默认情况下,PERCFG.U0CFG位为0,即RT,CT,TX,RX分别对应P0_5,P0_4,P0_3,P0_2。确定了UART0的映射之后,需要将相应的IO口(P0_5,P0_4,P0_3,P0_2)设置为外设模式,即设置P0SEL的第5,4,3,2位为1。然后设置P2DIR的第7,6位为00,即优先执行UART0响应,这是为了解决当其他外设也复用同一个IO口时导致响应顺序的问题。对应的IO设置完成后,就需要设置UART0有关的寄存器了:(1)设置U0CSR.MODE位(第7位)为1,即UART模式(默认为0,SPI模式);(2)设置波特率,根据图3-3设置典型波特率,如115200,则U0GCR.BAUD_E(4:0)为01011,即十进制11,U0BAUD.BAUD_M(7:0)为11011000,即十进制216;(3)发送中断标志位UTX0IF位初始化清零。图3-3典型波特率(32MHz晶振)(4)通过给U0DBUF寄存器赋