⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can18b20.c

📁 基于CAN总线的 温度采集方法。选用DS18B20温度传感器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <iom8v.h>
#include <macros.h>
#include "mcp2515.h"

#define fosc 7372800  //晶振7.3728MHZ

#define DQ (1<<5)  //DQ接PC5

#define S_CS PORTC|=0x02   //PC1片选线
#define C_CS PORTC&=(~0x02)

#define S_CLK PORTC|=0x01  //PC0时钟线
#define C_CLK PORTC&=(~0x01)

#define S_DATA PORTC|=0x04  //PC2数据
#define C_DATA PORTC&=(~0x04)
/**************************** Definitionen ***********************************/
void init_SPI (void);
void reset_MCP (void);
void write_MCP (unsigned char adress, unsigned char value);
unsigned char read_MCP(unsigned char adress);
void fill_msg_box_0(void);
void send_box_0 (void);
void wait(unsigned int n);
void init_can(void);
void bit_modify(unsigned char adress,unsigned char cc, unsigned char value);
void delay_1ms(void);
void HC595_SENDDAT(char dat);
void delay(unsigned int n);
unsigned char crccheck(unsigned char *p,unsigned char len);
void	delay_us(unsigned int time);
unsigned char ds1820_ack(void);
unsigned char	read_byte(void);
void	write_byte(unsigned char value);
//unsigned char	Read_Temperature(unsigned int *temperature);
//unsigned char	Read_RomCode(unsigned char *temp);
//void ds1820_match(unsigned char *p);
unsigned int	count; //CAN发送间隔
unsigned char	wendu,shi,ge;  
unsigned char	dot1; 
unsigned char	minus_flag;
unsigned char	flag=0; //初始化,个位显示    
//0-9
unsigned char table[10]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
/**************************** Hauptprogramm **********************************/
/*SPI初始化*/
void init_SPI (void)
{
	//HW_SPI=0x00;		//	PortB ist HW_SPI
	DDR_SPI|=0x2D;		//	CS\MOSI\SCK output MISO input
	SPCR=0x51;		//	SPI Controll Register set,Fosc/16
}
/*MCP2515复位*/
void reset_MCP (void)
{   unsigned char i;
	PORTB&=~(1<<CS_CAN);					//	CS  Low -> MCP enable
	SPDR=RESET_MCP;				       //	sende Reset Kommando
	while(!(SPSR & (1<<SPIF))); 	//	warten bis das Byte gesendet wurde
	PORTB|=(1<<CS_CAN);				//	CS  High -> MCP disable
	wait(1000);		//	waiting?
}
/*CAN发送请求*/
void send_box_0 (void)
{
	write_MCP (TXB0CTRL, 0x0B);			//	sende Telegramm mit h鯿hster Priorit鋞
	PORTB&=~(1<<CS_CAN);				//	CS  Low -> MCP enable
	SPDR=(RTS | 0x01);			//	sende Mailbox Nummer 0
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	PORTB|=(1<<CS_CAN);					//	CS  High -> MCP disable
}
/*MCP2515写操作*/
void write_MCP (unsigned char adress, unsigned char value)
{
	PORTB&=~(1<<CS_CAN);				//	CS  Low -> MCP enable
	SPDR=0x02;					//	sende Write Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=adress;					//	Addresse senden
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=value;					//	Wert senden
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	PORTB|=(1<<CS_CAN);					//	CS  High -> MCP disable
}
/*MCP2515读操作*/
unsigned char read_MCP(unsigned char adress)
{
	unsigned char spidata;

	PORTB&=~(1<<CS_CAN);				//	CS  Low -> MCP enable
	SPDR=0x03;					//	sende Read Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=adress;					//	Adresse von der gelesen werden soll
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=0xAA;					//	Dummy-Byte senden
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	spidata = SPDR;				//	Daten aus SPI abholen
	PORTB|=(1<<CS_CAN);				//	CS  High -> MCP disable
	return (spidata);
}
/*位修改*/
void bit_modify(unsigned char adress,unsigned char cc, unsigned char value)
{ PORTB&=~(1<<CS_CAN);				//	CS  Low -> MCP enable

    SPDR=0x05;					//	bit modify Write Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=adress;					//	sende Write Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=cc;					//	sende Write Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde
	SPDR=value;					//	sende Write Kommando
	while(!(SPSR & (1<<SPIF)));	//	warten bis das Byte gesendet wurde

  PORTB|=(1<<CS_CAN);					//	CS  High -> MCP disable
}
/*填充CAN信息*/
void fill_msg_box_0(void)
{
	write_MCP(TXB0SIDH, (unsigned char) (0x261 >> 3));	//	ID = 0x26a
	write_MCP(TXB0SIDL, (unsigned char) (0x261 << 5));  ////需要修改
	write_MCP (TXB0DLC, 0x02);		//	1 Bytes
	write_MCP (TXB0D0, wendu);		
	write_MCP (TXB0D1, dot1);
  
}
/*CAN初始化*/
void init_can(void)
{   write_MCP (CANCTRL, 0x80);  //0x80, set mode
	//TX
	write_MCP (CNF1, 0x03);		//	Set CAN-Baudrate  125 kBaud
	write_MCP (CNF2, 0xB8);		//	 16MHz
	write_MCP (CNF3, 0x05);		//	des MCP2510 bzw. MCP2515
	
	//RX
	write_MCP (RXB0CTRL, 0x20); // receive stand message
	write_MCP (RXM0SIDH, 0xFF); // 屏蔽寄存器高8位,11位都要校验
	write_MCP (RXM0SIDL, 0xE0); // 屏蔽寄存器低3位
	write_MCP (RXF0SIDH, 0x4C); //接收报文ID为:0x260的报文(上位机 cansap)
	write_MCP (RXF0SIDL, 0x00);
	
	write_MCP (CANINTE, 0x25);   //enable interrupt
	write_MCP (CANCTRL, 0x00);	//	Set CLK-Out disable,0x80 set mode,0x40 shou fa ,0x00 normal mode,
     asm("nop");     
}
/*CAN中断*/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{   unsigned char i,err; 
    //unsigned int canid; 
      i = read_MCP (CANINTF);
	      if((i&0x04)==0x04)  //TX0 空
			   { minus_flag=0;  //负温度标志清0 
			     
			     bit_modify(CANINTF, 0x04,0x00); //清除TX0IF标志
				}
	      if((i&0x20)==0x20) // 出错
			   {//err = read_MCP (EFLG);
			    reset_MCP();
				init_can();
				//fill_msg_box_0();
				bit_modify(CANINTF, 0x20,0x00); //清除ERRIF标志
				}
	      if((i&0x01)==0x01) //RX0接收满
			   {//str[0] = read_MCP (0x61);
	            //str[1] = read_MCP (0x62);
		        //str[2] = read_MCP (0x65);
		        //str[3] = read_MCP (0x66);
		         bit_modify(CANINTF, 0x01,0x00); //清除RX0IF标志
				 		
	           }
      
}

/*===================================================================
//	函数功能:	DS18B20数据校验函数
//	形参:		void
//	返回:		unsigned char	校验结果
//	编写:		2004/8/25
//	备注:		CRC公式为:CRC = X^8 + X^5 + X^4 + 1
===================================================================*/
unsigned char crccheck(unsigned char *p,unsigned char len)
{
	unsigned char bit0,cbit,r,temp,i,j,byte;
	temp = 0;
	for(j = 0; j < len; j++)
	{
		byte = p[j];
		for(i = 0; i < 8; i++)
		{
        		cbit = temp & 0x01;
        		bit0 = byte&0x01;
        		temp >>=   1;
        		r = cbit ^ bit0;
        		if(r == 1)
        			temp ^= 0x8c;
        		byte >>= 1;
        	}
    	}
	return	temp;	
}

/*===================================================================
//	函数功能:	us延时函数
//	形参:		void
//	返回:		void
//	编写:		2004/8/25
===================================================================*/
void	delay_us(unsigned int time)
{     
	do
	{ //delay_1us();
		time--;
	}	
	while (time>1);
}

/*===================================================================
//	函数功能:	判断总线应答
//	形参:		void
//	返回:		unsigned char	true为应答
//	编写:		2004/8/25
===================================================================*/
unsigned char ds1820_ack(void)
{
	unsigned char ack;
	DDRC |= DQ;
	PORTC &= ~DQ;
	delay_us(450);							//	reset
	PORTC |= DQ;
	DDRC &= ~DQ;
	delay_us(45);
	ack = DQ & PIND;
	delay_us(450);							//	host receive
	if(ack)
		return 1;
	else
		return 0;
}

/*===================================================================
//	函数功能:	从 1-wire 总线上读取一个字节
//	形参:		void
//	返回:		unsigned char	读到的值
//	编写:		2004/8/25
===================================================================*/
unsigned char	read_byte(void)
{
	unsigned char	i;
	unsigned char	value = 0;
	for(i = 8; i > 0; i--)
	{
		value >>= 1;						//	low bit first
		DDRC |= DQ;
		PORTC &= ~DQ;						//	pull DQ low to start timeslot
		delay_us(3);
		PORTC |= DQ;
		DDRC &= ~DQ;						//	release bus
		delay_us(10);
		if(DQ & PINC)
		value|=0x80;
		delay_us(100);
		DDRC |= DQ;
		delay_us(5);						//	time interval
	}
	return(value);
}

/*===================================================================
//	函数功能:	向 1-WIRE 总线上写一个字节
//	形参:		value		写到总线上的值
//	返回:		void
//	编写:		2004/8/25
===================================================================*/
void	write_byte(unsigned char value)
{
	unsigned char	i;
	DDRC |= DQ;
	for(i = 8; i > 0; i--)
	{
		if(value & 0x01)
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -