//transmitter //crystal = 4.0Mhz //NO movement in 327s then M8 turns off mouse&CC2500 & goes to power-down mode,resulting in 0.2ma consumption //every time CC2500 finishes transmitting,it will be forced to goto SLEEP mode //NO movement in 2s, M8 goes to IDLE state,consumption decreases from 7.23ma down to 4.48ma //watch dog timer:WDTCR = 0x0D,512K pulses,about 0.52s #include #include #define uint unsigned int #define uchar unsigned char #define m_clk_read DDRD&=~0x08 #define m_clk_ctrl DDRD|= 0x08 #define m_data_read DDRC&=~0x01 #define m_data_ctrl DDRC|= 0x01 #define m_clk_high PORTD|=0x08 #define m_clk_low PORTD&=~0x08 #define m_data_high PORTC|=0x01 #define m_data_low PORTC&=~0x01 #define mouse_on PORTD&=~0x10 #define mouse_off PORTD|=0x10 //以上定义PS2鼠标的CLK,DATA针脚的输入输出,高低电平和开,关鼠标电源 #define CSn_on PORTD|=0x20 #define CSn_off PORTD&=~0x20 #define sclk_on PORTD|=0x80 #define sclk_off PORTD&=~0x80 #define si_on PORTB|=0x01 #define si_off PORTB&=~0x01 #define so_read DDRD&=~0x40 //以上定义cc2500有关的spi协议的针脚 #define burst 0x40 #define read_reg 0x80 #define write_reg 0x00 #define scal 0x33 #define srx 0x34 #define stx 0x35 #define sftx 0x3b #define spwd 0x39 #define sxoff 0x32 #define snop 0x3d //以上定义cc2500有关的指令 #define cc2500_on PORTB&=~0x80 #define cc2500_off PORTB|=0x80 //以上定义cc2500的电源开关 #define enable_int0 GICR |=0x40 #define disable_int0 GICR &=~0x40 #define enable_int1 GICR |=0x80 #define disable_int1 GICR &=~0x80 #define enable_powerdown MCUCR |=0xa0 #define disable_powerdown MCUCR &=~0xa0 #define enable_idle MCUCR |=0x80 #define disable_idle MCUCR &=~0x80 #define wdt_off WDTCR = (1<>i; if(temp&0x01)parity++; PORTC|=temp&0x01; PORTC&=temp|0xfe; while(!(PIND&0x08));NOP();WDR(); } while((PIND&0x08));NOP(); if(parity%2==0) m_data_high; else m_data_low; //send parity bit while(!(PIND&0x08));NOP(); while((PIND&0x08));NOP(); m_data_high; //send stop bit while(!(PIND&0x08));WDR(); m_data_read;NOP();NOP(); while(PIND&0x08);NOP(); //wait ack while(!(PIND&0x08)); WDR(); } void connectmouse_init(void) //定义鼠标初始化 {uchar i,buffer,counter; WDR(); send_a_command(0xff);buffer=read_from_mouse(); //reset buffer=read_from_mouse();buffer=read_from_mouse();WDR(); send_a_command(0xf2);buffer=read_from_mouse();buffer=read_from_mouse();//get ID send_a_command(0xf3);buffer=read_from_mouse(); //set sample send_a_command(200); buffer=read_from_mouse(); //sample rate =200 send_a_command(0xf3);buffer=read_from_mouse(); //set sample rate send_a_command(0x64);buffer=read_from_mouse(); //sample rate =100 send_a_command(0xf3);buffer=read_from_mouse(); //set sample send_a_command(0x50);buffer=read_from_mouse(); //sample rate =80 send_a_command(0xf2);buffer=read_from_mouse();buffer=read_from_mouse();//get ID send_a_command(0xf3);buffer=read_from_mouse(); //set sample rate send_a_command(100); buffer=read_from_mouse(); //sample rate =100 send_a_command(0xe8);buffer=read_from_mouse(); //set resolution send_a_command(0x02);buffer=read_from_mouse(); //resolution = 4 counts/mm send_a_command(0xe6);buffer=read_from_mouse(); //set scaling 1:1 send_a_command(0xf4);buffer=read_from_mouse(); //enable data reporting } uchar SPI_command(unsigned char bitpointer) //发指令到CC2500 {uchar i,temp_SI,temp_SO,return_SO; i=temp_SI=temp_SO=return_SO=0; WDR(); sclk_off;NOP(); CSn_off;NOP(); //CSn low while(PIND&0x40); // wait until SO low for(i=0;i!=8;i++) { NOP(); temp_SI=(bitpointer>>(7-i)); PORTB|=temp_SI&0x01; PORTB&=temp_SI|0xfe; PORTD|=0x80;NOP(); temp_SO=PIND&0x40; return_SO|=((temp_SO<<1)>>i); NOP(); sclk_off; } if(!(bitpointer&0x40)) // bitpointer is a cmmd,set CSn & SCLK high {CSn_on;NOP(); sclk_on;NOP(); } WDR(); return return_SO; } void SPI_host_send(unsigned char bitpointer) //写字节到CC2500,功能兼容SPI_command {uchar i,temp_SI; i=temp_SI=0; WDR(); sclk_off;NOP(); CSn_off;NOP(); //CSn low while(PIND&0x40);NOP(); // wait until SO low for(i=0;i!=8;i++) {NOP(); temp_SI=(bitpointer>>(7-i)); PORTB|=temp_SI&0x01; PORTB&=temp_SI|0xfe; sclk_on; NOP(); sclk_off; } WDR(); } uchar SPI_host_read(void) //读字节从CC2500 {uchar i,temp_SO,return_SO; i=temp_SO=return_SO=0; WDR(); for(i=0;i!=8;i++) { sclk_on;NOP(); temp_SO=PIND&0x40; return_SO|=((temp_SO<<1)>>i); NOP(); sclk_off; NOP(); } WDR(); return return_SO; } void cc2500_TX_initialization(void) //初始化cc2500 {uchar read; SPI_host_send(scal);delay(130); SPI_host_send(0x01);SPI_host_send(0x07); SPI_host_send(0x06);SPI_host_send(0x06); //fixed packet length =6 SPI_host_send(0x08);SPI_host_send(0x0c); SPI_host_send(0x0b);SPI_host_send(0x09); SPI_host_send(0x0d+burst+write_reg); SPI_host_send(0x5d); SPI_host_send(0xb1); SPI_host_send(0x38); SPI_host_send(0x2d); SPI_host_send(0x3b); SPI_host_send(0x73); SPI_host_send(0xd2); SPI_host_send(0xf8); SPI_host_send(0x01); SPI_host_send(0x07); SPI_host_send(0x30); SPI_host_send(0x18); SPI_host_send(0x1d); SPI_host_send(0x1c); SPI_host_send(0xc7); SPI_host_send(0x00); SPI_host_send(0xb2); CSn_on;NOP(); SPI_host_send(0x21);SPI_host_send(0xb6); SPI_host_send(0x23);SPI_host_send(0xca); SPI_host_send(0x26);SPI_host_send(0x11); SPI_command(sftx); SPI_host_send(scal);delay(85); SPI_host_send(0x25+read_reg);read=SPI_host_read(); while(read==0x3f){SPI_host_send(0x25+read_reg);read=SPI_host_read();} SPI_command(spwd); } void main(void) {uchar readcc2500,i,j; OSCCAL=0x9f; PORTD=0xec;PORTB=0x7f;PORTC=0xff; DDRB=0x81;DDRD=0xb0;DDRC=0x00; CLI(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x00; delay(25);frommouse[0]=0xbb;frommouse[1]=0xaa; timer0_init();//for(i=2;i!=6;i++)frommouse[i]=0x00; cc2500_TX_initialization(); sample_rate=100;resolution=0x03; sleeptime=0x00;gotosleep=0x00; for(i=0;i!=21;i++){delay(33000);} connectmouse_init(); WDR();SEI();WDTCR = 0x0D; //开看门狗 while(9) {startloop: m_clk_high;m_clk_read;NOP();NOP(); if(!(PIND&0x08)) { for(tt=2;tt!=6;tt++) {frommouse[tt]=read_from_mouse();} //从鼠标读字节 if((!(frommouse[2]&0x08))||(frommouse[2]&0xc0))//check bit3,6,7 of 1st byte {while(9);} m_clk_ctrl;m_clk_low; //inhibit mouse transmit sleeptime=0;WDR(); SPI_host_send(0x7f); //burst write TXfifo for(tt=0;tt!=6;tt++) {SPI_host_send(frommouse[tt]);} //写字节到CC2500 CSn_on;NOP(); //end burst write SPI_command(stx);delay(100); //go to TXmode SPI_host_send(0xf5);readcc2500=SPI_host_read();//check whether TX finished while(readcc2500!=0x01){SPI_host_send(0xf5);readcc2500=SPI_host_read();} SPI_command(spwd); //go into SLEEP mode,TXfifo lose value WDR();delay(300); m_clk_high;m_clk_read;NOP(); //release mouse tansmit } WDR(); if((gotosleep)&&(sleeptime>=5000)) //掉电睡眠定时器满足,进入掉电睡眠 {gotosleep=0;sleeptime=0;TCCR0 = 0x00;TCNT0 = 0x00; enable_int0; DDRD=0x10;DDRC=DDRB=0x00;PORTD=PORTB=PORTC=0xff;mouse_off;cc2500_off; enable_powerdown;CLI();wdt_off;SEI();SLEEP(); } if(sleeptime>30)//1.96seconds //待机睡眠定时满足,进入待机睡眠 {m_clk_high;m_clk_read;NOP(); enable_int1;enable_idle;CLI();wdt_off;SEI();SLEEP(); } } }