stm32,js407 使用smsja1000 CAN独立控制器

国产化项目需要调试国产单片机 js407 和国产CAN独立控制器 smsja1000。

js407完全适配stm32f407,可直接下载stm32f407的代码。

smsja1000完全适配sja1000,可直接替换。

以下使用默认模式BasicCAN,不支持扩展帧模式。

 

 

 

 

         总体来说,和stm32的CAN控制器一样,需要配置一些寄存器,模式,中断,波特率,屏蔽码等。

        需要注意哪些寄存器是在复位模式或者工作模式中可用。

1.8080接口的写时序如下:    

void sja1000_write_cmd(uint8_t addr, uint8_t cmd) //can 写寄存器数据
{
	uint8_t i;
	
	adio_out_change(); //切换数据io为输出

	CAN_ALE_H;  //写命令地址
	for(i=0; i<8; i++)
	{
		if(addr & 0x80)
			GPIO_SetBits(CAN_AD_Port, adIOPin[i]);
		else
			GPIO_ResetBits(CAN_AD_Port, adIOPin[i]);
		
		addr <<= 1;
	}
	CAN_ALE_L;

	CAN_CS_L; //写命令
	CAN_WR_L;
	for(i=0; i<8; i++)
	{
		if(cmd & 0x80)
			GPIO_SetBits(CAN_AD_Port, adIOPin[i]);
		else
			GPIO_ResetBits(CAN_AD_Port, adIOPin[i]);
		
		cmd <<= 1;
	}
	CAN_WR_H;
	CAN_CS_H;
}

2.读时序如下: 

uint8_t sja1000_read_byte(uint8_t addr) //can 读寄存器数据
{
	uint8_t i,data=0;
	
	adio_out_change(); //切换数据io为输入

	CAN_ALE_H; //写命令地址
	for(i=0; i<8; i++)
	{
		if(addr & 0x80)
			GPIO_SetBits(CAN_AD_Port, adIOPin[i]);
		else
			GPIO_ResetBits(CAN_AD_Port, adIOPin[i]);
		
		addr <<= 1;
	}
	CAN_ALE_L;
		
	adio_in_change();
	
	CAN_CS_L; //读8位数据
	CAN_RD_L;
	for(i=0; i<8; i++)
	{
		data <<= 1;
		
		if(GPIO_ReadInputDataBit(CAN_AD_Port,adIOPin[i]))
			data++;	
	}
	CAN_RD_H;
	CAN_CS_H;
	
	return data;
}

 3.初始化寄存器配置如下:

uint8_t can_filter[8] = {0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff};
void sja1000_reg_Init(void) 
{
	uint8_t i,test=0;

	CAN_RESET_L; 
	CAN_ALE_L;
	CAN_WR_H;
	CAN_RD_H;
	CAN_CS_H;
	delay_ms(1);
	CAN_RESET_H;  
	
	sja1000_write_cmd(0x00, 0x01); // 复位模式
	sja1000_write_cmd(0x06, 0x00); // 配置总线定时器 0
	sja1000_write_cmd(0x07, 0x1C); // 配置总线定时器 1
	sja1000_write_cmd(0x08, 0xFA); // 配置输出管脚为 TX0 与 RX0,推挽输出
	sja1000_write_cmd(0x04, 0x00); // 验收
	sja1000_write_cmd(0x05, 0xFF); // 屏蔽
	sja1000_write_cmd(0x00, 0x02); // 工作模式+接收中断
	
}

 4.发送帧数据如下:

/*	CMR 命令 addr 0x01
		CMR.4 自接收 1/0 
*/
uint8_t msg[10] = {0x00,0xE8,0x01,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
void sja1000_send_frame(void)
{
	uint8_t i;
	msg[2]++;
	for(i=0;i<10;i++)
	{
		sja1000_write_cmd(0x0A+i,msg[i]); //发送缓冲区
	}
	sja1000_write_cmd(0x01,0x01);  //发送请求
}

5.利用sja1000的中断线配置中断接受数据:

uint8_t msgbuf[8]={0};
void EXTI2_IRQHandler(void) //外部中断2服务程序
{
	uint8_t data=0,i;
	
	data = sja1000_read_byte(0x03);
	
	if(data & 0x01)
	{
		for(i=0;i<8;i++)
		{
			msgbuf[i] = sja1000_read_byte(22+i);
		}
		
		sja1000_write_cmd(0x01,0x04); //清除接收husn
		
		sja1000_send_frame();
	}
	
	EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE2上的中断标志位 
}

 

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值