logo资料库

Zigbee入门教程-手把手的教你.pdf

第1页 / 共197页
第2页 / 共197页
第3页 / 共197页
第4页 / 共197页
第5页 / 共197页
第6页 / 共197页
第7页 / 共197页
第8页 / 共197页
资料共197页,剩余部分请下载后查看
【原创】ZigBee 学习之 1——点灯 我用的编译环境是 IARfor51 7.30B,再介绍一下我的开发板的情况,ZigBee 模 块用的是 CC2430.这块芯片是一款 Soc 的芯片,集成了 8051 内核和 ZigBee 射 频部分,只要很少的外部电路就可以搭建一个射频模块。 因为其中的是 8051 的内核,所有对于熟悉 8051 系列的同学们来说,基本的一 些操作就很简单了,这里我们在温习一下,顺便对 CC2430 芯片进行一下熟悉。 嵌入式的一大特点是其底层的软件和硬件紧密相关,如果没有数字电路的知识, 那么作起来是很困难的。我们先介绍一下基本的管脚分配情况: P0 的 2 和 3 接到了一个 232 电压转换芯片上,可以用来和 PC 进行通信,LCD _RST,LCD_CS,接的是 LCD 的复位和片选端,这里我用到的 LCD 是兼容 PCD 8544 的 NOkia5110 的 LCD,为 SPI 总线 LCD,84X48 点阵。CC2430_MOSI, CC2430_CLK 都接到 LCD 上了。P1_0 接到一个调试 LED 上面,为高电平点亮。 下面的第一个实验就很简单了,我们只要把 P1_0 配置为通用 IO,输出方式, 然后从这里输出高电平,那么就可以点亮这个 LED 了。用到的寄存器为: P1 配置寄存器 P1SEL, P1 方向寄存器 P1DIR 程序如下: #include #define DEBUG_LED P1_0 void delay(unsigned int n){ //26 cycles delay while(--n)asm("NOP"); } void LEDInit(){ P1SEL &= 0XFE; P1DIR |= 0X01; } main(){ LEDInit(); while(1){ DEBUG_LED = 1; delay(50000); DEBUG_LED = 0; delay(50000); //P1_0 defined General purpose I/O //P1_0 defined Output //Led light
} } 编译通过以后就用 TI 的官方工具 SmartRF Flash Programmer 将生成的 HEX 文件,烧录到 CC2430 吧,激动的时刻,呵呵如果点亮了这个小小的 LED 那么 恭喜你,你的硬件因该是没有问的了,一个小小的胜利后我们就有更多的勇气和 信心前进咯! 源程序,以及编译设置 http://space.ednchina.com/upload/2010/1/15/e19724a5 -d9ec-4481-8aef-bc0b4fb1e122.rar 【原创】ZigBee 学习之 2——SPI&LCD 今天的任务是用 SPI 总线方式点亮 LCD 屏幕,呵呵这里要涉及到两个内容,一 个是 SPI 总线,一个 LCD。 CC2430 的话已经集成了 SPI 总线,只要将 IO 口配置为外设,然后将 USART 配置成 SPI 方式就可以了。 关于 LCD 其实也很简单,很多没有接触过的同学可能将其想象的太过复杂了, 就是将字或者图像转换为一个一个的点,如果要这点显示东西呢,就把这点点亮, 否则则不点亮。其实 PCD8544 已经将很多细节的东西做好了,我们要做的呢, 就是发送一串命令序列,然后发送要显示的数据就可以了。看看 PCD8544 的芯 片资料,我们还会发现在最后它竟然给出了操作实例,呵呵相信大家都能看懂的 吧,如果有看不懂的可以给我留言或者是 QQ 联系我哦,我如果知道的话一定给 大家详细的答复! CC2430 的 SPI 的是放在 USART 外设里面的,和 UART 放在一起,同一个 US ART 即可以配置成 UART 也可以配置成 SPI,SPI 的主从模式通过相关的寄存 器来选择。关于管脚的分配也不难,这里就不多说了,其实这里还算是 8051 的 基础实验,对于 8051 很熟悉的同学肯定觉得我是在说废话了,哈哈! 这里只提一下关于 SPI 应该注意的一点问题: 1、PCD8544 的 SPI 是高电平采样,所以,主机端必须是高电平之前要把数据 准备好。所以主机端的发送(MOSI)因该设为下降沿采样。 当用 SPI 和 PCD8544 通信时,速率不能太低,否则点不亮 LCD,或者是出来乱 码 下面是引用网友的 SPI 总线心得,我觉得看看很有益处: SPI 接口时钟配置心得: 在主设备这边配置 SPI 接口时钟的时候一定要弄清楚从设备的时钟要求, 因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配 置上一定要
搞清楚从设备是在时钟的上升沿还是下降沿接收数据,是在时钟的下降沿还是上 升沿输出数据。 但要注意的是,由于主设备的 SDO 连接从设备的 SDI,从设备的 SDO 连接主 设备的 SDI, 从设备 SDI 接收的数据是主设备的 SDO 发送过来的,主设备 SDI 接收的数据是 从设备 SDO 发送过来的, 所以主设备这边 SPI 时钟极性的配置(即 SDO 的配置)跟从设备的 SDI 接收数 据的极性是相反的, 跟从设备 SDO 发送数据的极性是相同的。下面这段话是 Sychip Wlan8100 Mo dule Spec 上说的, 充分说明了时钟极性是如何配置的: The 81xx module will always input data bits at the rising edge of the clo ck, and the host will always output data bits on the falling edge of the clock. 意思是:主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。 因此主设备这边 SPI 时钟极性应该配置为下降沿有效。 又如,下面这段话是摘自 LCD Driver IC SSD1289: SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0. 意思是:从设备 SSD1289 在时钟的上升沿接收数据,而且是按照从高位到地位 的顺序接收数据的。 因此主设备的 SPI 时钟极性同样应该配置为下降沿有效。 时钟极性和相位配置正确后,数据才能够被准确的发送和接收。 因此应该对照从设备的 SPI 接口时序或者 Spec 文档说明来正确配置主设备的时 钟。 老规矩,上程序: 先来一个不用 SPI 方式控制 LCD 显示的实例: #include "periodef.h" #include void delay(uint n){ //26 cycles delay while(--n)asm("NOP"); } void LCD_IOInit(){ P0SEL &=~ 0X03; P0DIR |= 0X03; P1SEL &=~ 0XF0;
P1DIR |= 0XF0; } void LCD_WriteOneByte(uchar data){ uchar i = 0; for(i=0;i<8;i++){ LCD_SCK = 0; if((data<
0x00,0x7E,0x10,0x10,0x7E,0x00,/*"H",0*/ /* (6 X 8 , 楷体_GB2312 )*/ 0x00,0x7E,0x52,0x52,0x42,0x00,/*"E",1*/ /* (6 X 8 , 楷体_GB2312 )*/ 0x42,0x7E,0x42,0x40,0x40,0x00,/*"L",2*/ /* (6 X 8 , 楷体_GB2312 )*/ 0x42,0x7E,0x42,0x40,0x40,0x00,/*"L",3*/ /* (6 X 8 , 楷体_GB2312 )*/ 0x00,0x3C,0x42,0x42,0x3C,0x00,/*"O",4*/ /* (6 X 8 , 楷体_GB2312 )*/}; LCD_IOInit(); LCD_Init(); //for(i=0;i<30;i++){ //LCD_WriteOneByte(Hello[i]); //} LCD_WriteMByte(Hello,30); LCD_nCS = 1; : : } 下面是采用 SPI 总线方式控制 LCD 显示的例子: //======================== //This file is applicable to Eshine EXBEE-DK V1 //Function:LCD test,the LCD use SPI BUS.The SPI BUS occupation P1-U SART1-ALT.2 //InPut //OutPut //Created :longfan,2010.1.10 //Modify : //======================== #include "periodef.h" #include "font.h" #include "TestBMP.h" #include void delay(uint n){ //26 cycles delay while(--n)asm("NOP"); } void LEDInit(){ P1SEL &= 0XFE; //P1_0 defined General purpose I/O
P1DIR |= 0X01; DEBUG_LED = 1; //P1_0 defined Output //LED light up } //======================== //Initial P1-USART1-SPI void SPIInit_U1_P1(void){ PERCFG |= 0X02; P1SEL |= 0XE0; P2SEL |= 0X40; U1GCR |= 0x20; //USART1.alt.2,P1 //P1,ISP,P1_4(LCD_DnC) defined general IO //USART1 has priority //MSB first,Negative clock polarity,Data is output on MOSI on the falling edge of CLK U1GCR |= 19; U1BAUD = 0; UTX1IF = 0; //MAX Baud rate(17),falling edge //Clear interrupt } //======================== //P1-USART1-SPI Send One Byte void SPI_SendOne_U1_P1(uchar data){ U1DBUF = data; while(!UTX1IF); UTX1IF = 0; } //======================== //P1-USART1-SPI Send Multily Byte void SPI_Send_U1_P1(uchar *data,uint length){ while(length){ SPI_SendOne_U1_P1(*data); data++; length -= 1; } } //======================== //LCD Use SPI BUS,Set the first display piex. //When after call this function can direct call SPI data output function //0
SPI_SendOne_U1_P1(0x40 | Y); LCD_DnC = 1; } //======================== //LCD Use SPI BUS,Clear the LCD Display and its RAM. void SPI_ClearLCD(){ uint i; SPI_LCDSetPos(0,0); for (i=0; i<504; i++){ SPI_SendOne_U1_P1(0); } } //======================== //LCD Use SPI BUS,Send one LCD Command void SPI_LCDWriteOneComm(uchar command){ LCD_DnC = 0; SPI_SendOne_U1_P1(command); } //======================== //LCD Use SPI BUS,Send More than one LCD Command void SPI_LCDWriteMulComm(uchar *command,uchar num){ LCD_DnC = 0; SPI_Send_U1_P1(command,num); } //======================== //LCD Use SPI BUS,Send More than one data void SPI_LCDWriteData(uchar *data,uchar length){ LCD_DnC = 1; SPI_Send_U1_P1(data,length); } //======================== //LCD Use SPI BUS,Display a english character Without set position,The inverse argument control //the inverse video mode.When use font library call this function to displa y. //InPut // //OutPut :character:The character want to display inverse :Inverse video mode(1) or not(0) :
//Created :longfan,2010.1.10 //Modify : //======================== void SPI_LCDWriteChar(uchar character,uchar inverse){ uchar line; LCD_DnC = 1; if(inverse){ for(line=0;line<6;line++){ SPI_SendOne_U1_P1(~font6x8[character-32][line]); } }else{ SPI_Send_U1_P1((uchar *)font6x8[character-32],6); } } //======================== //LCD Use SPI BUS,Display a english character at (X,Y),The inverse arg ument control //the inverse video mode.When use font library call this function to displa y. //InPut // // //OutPut //Created :longfan,2010.1.10 //Modify : //======================== void SPI_LCDDISPChar(uchar character,uchar X,uchar Y,uchar inverse){ :character:The character want to display X,Y inverse :Inverse video mode(1) or not(0) :The position want to display : uchar line; SPI_LCDSetPos(X,Y); if(inverse){ for(line=0;line<6;line++){ SPI_SendOne_U1_P1(~font6x8[character-32][line]); } }else{ SPI_Send_U1_P1((uchar *)font6x8[character-32],6); } } //========================
分享到:
收藏