📄 cc25001.txt
字号:
//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 <iom8v.h>
#include <macros.h>
#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<<WDCE)|(1<<WDE);WDTCR =0x00
uint sleeptime;
uchar tt,gotosleep;
uchar sample_rate,resolution,command;
uchar frommouse[6];
void delay(uint tt)
{while(tt--);}
void timer0_init(void) //定义睡眠定时器
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00; //set count
TIMSK |= 0x01; //interrupt sourse
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{TCNT0 = 0x00;
sleeptime++;
if(sleeptime==5000)gotosleep=1; //about 327 seconds
}
#pragma interrupt_handler int0_isr:2 //定义掉电睡眠的外中断唤醒服务程序
void int0_isr(void)
{delay(500);
TCCR0 = 0x05;disable_int0;disable_powerdown;
PORTD=0xec;PORTB=0xff;PORTC=0xff;
DDRB=0x81;DDRD=0xb0;DDRC=0x00;
mouse_on;cc2500_on;WDTCR = 0x0D; //使用看门狗
}
#pragma interrupt_handler int1_isr:3 //定义待机睡眠的外中断唤醒服务程序
void int1_isr(void)
{
disable_int1;disable_idle;WDTCR = 0x0D;
}
uchar read_from_mouse(void) //定义从鼠标读字节子程
{uchar i,temp;
uchar receive=0;
m_clk_high;m_data_high;
m_clk_read;m_data_read;//NOP();NOP();
WDR();
while(PIND&0x08); //wait start bit
if(PINC&0x01)while(9); //if start bit is faulty,wait for watchdog to reset
while(!(PIND&0x08));
NOP();
for(i=0;i!=8;i++)
{while(PIND&0x08);
temp=PINC&0x01;receive|=temp<<i;
NOP();
while(!(PIND&0x08));WDR();
NOP();
}
while(PIND&0x08); //wait parity bit
NOP();
while(!(PIND&0x08));
NOP();
while(PIND&0x08);NOP(); //wait stop bit
while(!(PIND&0x08));NOP();
WDR();
return receive;
}
void send_a_command(uchar command) //定义发命令到鼠标子程
{uchar i,temp,parity;
parity=0;
WDR();
m_clk_ctrl;m_data_ctrl;NOP();NOP();m_clk_low;//pull clock low
delay(20);
m_data_low;delay(20); //pull data low
m_clk_high;m_clk_read; //release clock
for(i=0;i!=8;i++)
{while(PIND&0x08);NOP();
temp=command>>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();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -