sja1000是一款独立的can控制器芯片,对它的操作很像操作外部存储器,8位地址数据复用线AD0~AD7,WR,RD,ALE,CS。
原本是使用stm32的fsmc来操作sja1000的,发现总有一两个寄存器数据读出来和写入的不一样,所以才改用io口模拟方式操作sja1000(别问我为什么不直接使用stm32的can控制器,因为项目需要没办法,不然stm32自带的can控制器这么好用为什么不用呢!!!)。
进入正题,贴上操作部分的源码!
void WriteSja1000(u8 addr,u8 data)
{
CLR_SJA1000_CS;
SET_DATA(addr);
SET_SJA1000_RS;
delay(10);
CLR_SJA1000_RS;
SET_DATA(data);
CLR_SJA1000_WR;
delay(10);
SET_SJA1000_WR;
SET_SJA1000_CS;
}
u8 ReadSja1000(u8 addr)
{
u8 DATA = 0;
SET_DATA(addr);
CLR_SJA1000_CS;
SET_SJA1000_RS;
delay(10);
CLR_SJA1000_RS;
CLR_SJA1000_RD;
delay(10);
DATA = GET_DATA();
SET_SJA1000_RD;
SET_SJA1000_CS;
return DATA;
}
void SET_DATA(u8 data)
{
DATALINE_OUT();//设置AD0~AD7对应的io为输出
(data & (1 << 7)) ? (GPIOE->BSRR = (1 << 10)): (GPIOE->BRR = (1 << 10));
(data & (1 << 6)) ? (GPIOE->BSRR = (1 << 9)): (GPIOE->BRR = (1 << 9));
(data & (1 << 5)) ? (GPIOE->BSRR = (1 << 8)): (GPIOE->BRR = (1 << 8));
(data & (1 << 4)) ? (GPIOE->BSRR = (1 << 7)): (GPIOE->BRR = (1 << 7));
(data & (1 << 3)) ? (GPIOD->BSRR = (1 << 1)): (GPIOD->BRR = (1 << 1));
(data & (1 << 2)) ? (GPIOD->BSRR = (1 << 0)): (GPIOD->BRR = (1 << 0));
(data & (1 << 1)) ? (GPIOD->BSRR = (1 << 15 )): (GPIOD->BRR = (1 << 15 ));
(data & (1 << 0)) ? (GPIOD->BSRR = (1 << 14 )): (GPIOD->BRR = (1 << 14 ));
}
u8 GET_DATA()
{
u8 data = 0;
DATALINE_IN();//设置AD0~AD7对应的io为输入
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_14) == 1)
{
data |= 0x01;
}
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_15) == 1)
{
data |= 0x02;
}
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_0) == 1)
{
data |= 0x04;
}
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1) == 1)
{
data |= 0x08;
}
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_7) == 1)
{
data |= 0x10;
}
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_8) == 1)
{
data |= 0x20;
}
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9) == 1)
{
data |= 0x40;
}
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_10) == 1)
{
data |= 0x80;
}
return data;
}