📄 slave_spi.c
字号:
/* Mega8 Slave_SPI.c */
unsigned char rev_buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //接收数据缓存数组
unsigned char send_buf[10] = {1, 2, 3, 4, 5, 6, 7, 9, 0, 0}; //反馈回主机数据缓存数组
//SPI initialisation
// clock rate: 62500hz
void spi_init(void)
{
PORTB |= 0X3C; //SPI初始化
DDRB &= 0xC3; //MOSI,SCK,SS为输入,
DDRB |= (1 << 4); //MISO 输出
/* 使能SPI 主机模式,设置时钟速率为fck/128 */
SPCR = ((1<<SPIE) | (1<<SPE) |(1<<SPR1) | (1<<SPR0));
SPSR = 0x00; //setup SPI
}
/* ******************************************************************
/**********************************************************************/
#define CMD_START 0X40 //发送数据之前先发送起动命令字
#define RISEGO 0x88
#define RISEBACK 0x89
#define PUSH2GO 0x8A
#define PUSH2BACK 0x8B
#define PUSH1GO 0x87
#define PID_RESET 0XA4 //复位指令(0数据指令)
#define FREE_STOP 0X81 //自由停机指令(0数据指令)
#define SPEED_SET 0X80 //速度设定(双数据指令)
#define DISTANCE_SET 0X90 //位置设定(四数据指令)
/**********************************************************************/
/**********************************************************************/
//被传输数据前加的命令字
/**********************************************************************/
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{
static unsigned char i = 0;
static unsigned char start_trans_flag = 0; //接收开始标志
static unsigned char com_flag = 0; //命令类型标志,
static unsigned char data_long = 0; //数据传送长度
unsigned char temp_char = 0x00; //传送数据
signed int temp_int = 0x00;
signed long temp_long = 0x00;
temp_char = SPDR;
if (start_trans_flag == 0) //
{ /*主机向从机传送的第一个字节数据为启动字节数据,包含三部分信息,1:启动命令字0x40。2:命令类型信息,第四位为1时,表从机向主机传送数据,否则为主机向从机传送数据。3:被传送,数据流长度信息,为低四位所表之数值.*/
if ((temp_char & 0xE0) == CMD_START) //判断是否启动传送 1111 0000
{
data_long = (temp_char & 0x0f); //0000 1111
com_flag = (temp_char & 0x10); //0x00->主机向从机传送,0x10->从机向主机传送
start_trans_flag = 1;//从机开始送(标志位)
if (com_flag) //将需返回给主机的第一个字节放入SPDR,等待主机接收
{
SPDR = send_buf[0];
i = i+1; //传送数据指针指向下一数据
}
}
}
else
{
if (com_flag == 0x00) //从机接收数据
{
rev_buf[i] = temp_char;
i++;
if (i >= data_long)
{
i = 0;
start_trans_flag = 0;
data_long = 0;
com_flag = 0x00;
switch (rev_buf[0])//首位设为标志位
{
case RISEGO :
{
risemotor('g');
delay_ms(2300);
risemotor('s');
/* pushmotor1('g'); //推块电机上
delay_ms(1500);
pushmotor1('s');*/
}break;
case RISEBACK:
{
risemotor('b');
delay_ms(1200);
risemotor('s');
}break;
case PUSH2GO:
{
pushmotor2('g'); //推块电机下
delay_ms(2000);
pushmotor2('s');
}break;
case PUSH2BACK:
{
pushmotor2('b'); //推块电机下
delay_ms(2000);
pushmotor2('s');
}break;
case PUSH1GO:
{
pushmotor1('g'); //推块电机上
delay_ms(1500);
pushmotor1('s');
}break;
case PID_RESET : // 系统复位(RESET)
{
L_PIDInit ();
TCNT0 = 0;
num_H = 0;
Num_Speed = 0;
//write7279(DECODE1+0,5);
}break;
case FREE_STOP:
{
TCCR2 = 0x00; //start计数器2不工作
PID_choice = 0xff;
//write7279(DECODE1+7,1);
free_stop ( );
}break;
case SPEED_SET :
{
temp_int = rev_buf[1];
temp_int <<= 8;
temp_int += rev_buf[2];
L_sPID.vi_Ref = temp_int;
//dis_data(0, 7,L_sPID.vi_Ref);
PID_choice = SPEED_SET;
TCCR2 = 0x07; //start选择分频源1024
}break;
case DISTANCE_SET :
{
temp_long = rev_buf[1];
temp_long <<= 8;
temp_long += rev_buf[2];
temp_long <<= 8;
temp_long += rev_buf[3];
temp_long <<= 8;
temp_long += rev_buf[4];
L_sPID.si_Ref = temp_long;
//dis_data(0, 7, temp_long);
//dis_data(0, 7,L_sPID.si_Ref);
PID_choice = DISTANCE_SET;
TCCR2 = 0x07; //start选择分频源1024
}break;
default:break;
}//end switch
}//end if
}
else //从机发送数据
{
if (i < data_long)
{
SPDR = send_buf[i];
i++;
}
else
{
i = 0;
start_trans_flag = 0;
data_long = 0;
com_flag = 0x00;
/*send_buf[0] = 8;
send_buf[1] = 7;
send_buf[2] = 6;
send_buf[3] = 5;
send_buf[4] = 4;
send_buf[5] = 3;
send_buf[6] = 2;
send_buf[7] = 1;*/
}//end if
}
}
}
void risemotor(unsigned char m)
{
switch(m)
{case 'g':PORTD&=~0x40;PORTD|=0x80;break;
case 'b':PORTD|=0x40;PORTD|=0x80;break;
case 's': PORTD&=~0x40;PORTD&=~0x80;break;
default:break;
}
}
void pushmotor2(unsigned char m)
{
switch(m)
{case 'g':PORTD|=0x40;PORTD|=0x80;break;
case 'b':PORTD&=~0x40;PORTD|=0x80;break;
case 's': PORTD&=~0x40;PORTD&=~0x80;break;
default:break;
}
}
void pushmotor1(unsigned char m)
{
switch(m)
{case 'g':PORTC|=0x20;break;
case 's': PORTC&=~0x20;break;
default:break;
}
}
/*void disp(signed int num1)//
{
if (num1 < 0)
num1 = -num1;
send_buf[0] = num1%10;
send_buf[1] = (num1/10) %10;
send_buf[2] = (num1/100) %10;
send_buf[3] = (num1/1000) % 10;
send_buf[4] = (num1/10000);
send_buf[5] = 0;
send_buf[6] = 0;
send_buf[7] = 0;
}*/
/*void disp(signed int num1, signed int num2) //
{
if (num1 < 0)
num1 = -num1;
if (num2 < 0 )
num2 = -num2;
send_buf[0] = num1%10;
send_buf[1] = (num1/10) %10;
send_buf[2] = (num1/100) %10;
send_buf[3] = (num1/1000) % 10;
send_buf[4] = num2% 10;
send_buf[5] = (num2/10) %10;
send_buf[6] = (num2/100) %10;
send_buf[7] = (num2/1000) % 10;
}*/
/*void send_counter (signed int num_counter )
{
unsigned char buf[3];
buf[0] = Counter_SET;
buf[1] = (unsigned char)num_counter;
num_counter >>= 8;
buf[2] = (unsigned char)num_counter;
MasterTransmit(buf, 3);
}
void send_control (signed int num_control )
{
unsigned char buf[3];
buf[0] = Control_SET;
buf[1] = (unsigned char) num_control;
num_control >>= 8;
buf[2] = (unsigned char) num_control;
MasterTransmit(buf, 3);
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -