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

📄 sz2.c

📁 本程序为CAN总线开发程序,通过串口显示,多台计算机远程数据适时传递,用于工业控制
💻 C
字号:
#include <iom16.h> //和单片机类型相对应的头文件,选择Atmega16做实验;
#include <macros.h>
#include <spi.h>

void delay_1ms(void); //函数声明,本实验中会用到这两个函数
void delay_nms(unsigned int n);
void InitADC( void);
 unsigned int mm;
 int EEPROMwrite_256( int location, unsigned char byte);
 unsigned char EEPROMread_256( int location);
 
 void SpiWriteByte(unsigned char byte);
 unsigned char SpiReadByte(void);
 void InitUART( unsigned char baudrate );
unsigned char ReceiveByte( void );
void TransmitByte( unsigned char data );
unsigned char iRx=0;
void timer1_init(void);
void uart0_init(void);
void led( unsigned char ed );
//ICC-AVR application builder : 05-3-12 16:15:07
// Target : M16
// Crystal: 1.0000Mhz

#pragma interrupt_handler UART_RX_interrupt:12 UART_TX_interrupt:14
/* UART Buffer Defines */
#define UART_RX_BUFFER_SIZE 64 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_RX_BUFFER_MASK 63
#define UART_TX_BUFFER_SIZE 64 /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_MASK 63


static unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
static volatile unsigned char UART_RxHead;
static volatile unsigned char UART_RxTail;
static unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
static volatile unsigned char UART_TxHead;
static volatile unsigned char UART_TxTail;
unsigned char data=0;
unsigned char RxHead=0;
unsigned int zhongci=0;
unsigned char BUTE1=0xd8;
unsigned char BUTE2=0x34;
unsigned char keyba=0;
unsigned char keyd=0;
unsigned char keyba1=0;
int count=0;
int  ci=0;
static unsigned char xianshi[11]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0};
static unsigned char dxianshi[24];
static unsigned char pxianshi[24];
static unsigned char a[60];
static unsigned char b[60];
static unsigned char c[60];


#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void) 
{ 
  
  ci++;
	c[ci]=SPDR;		// 数据暂存a[]中 
		ci++;
	count=count-1;;
	if(count>0)  SPDR=a[ci];// 未发送完,继续 
	else  
	{PORTA=PORTA  | 0B10000000;//2510片选// 片选位置低电平 ;	
			// 否则,片选信号置高电平 
	PORTB = 0;
	}
	return;

} 



void port_init(void)
{
 unsigned char   temp ;
 DDRA  = 0B10000000;
 PORTA = 0B10000000;
 DDRA  = 0B10000000;
 
 
 PORTB=0;
  DDRB  = 0B10110000;  // Set SCK, MOSI & SS as outputs
    PORTB =0;  // clear bits MOSI, & SCK
	SPCR=0B11010001;
	 SPSR = 0x00; 
  temp = SPSR; 
  temp = SPDR; 
	
 PORTB = 0;
 
 PORTC = 0b00000100;
 DDRC  = 0xff;
 PORTC = 0b00000100;
  
 DDRD  = 0b11111000;
 PORTD = 0b00011000;
 
}



/* initialize UART */
void InitUART( unsigned char baudrate )
	{
	
	UCSRB = 0x00; //disable while setting baud rate
	UBRR = baudrate; /* set the baud rate */
	/* enable UART receiver and transmitter, and
	receive interrupt */
	UCR = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
	
	UART_RxTail = 0;
	UART_RxHead = 0;
	UART_TxTail = 0;
	UART_TxHead = 0;
	UCSRA = 0x00;
	//UCSRC = BIT(URSEL) | 0x06;
 	//UCSRB = 0xD8;
	
	}

/* interrupt handlers */
void UART_RX_interrupt( void )
{
	
	//unsigned char tmphead;
	//data ++; /* read the received data */
	/* calculate buffer index */
	
	if ( UART_RxHead > UART_RX_BUFFER_MASK )
		{
		UART_RxHead=0;/* ERROR! Receive buffer overflow */
		}
	UART_RxBuf[UART_RxHead] = UDR; /* store received data in buffer */
	data=UART_RxBuf[UART_RxHead];
	//tmphead = ( UART_RxHead + 1 ) ;
	//UART_RxHead = tmphead; /* store new index */
	UART_RxHead++;
}

void UART_TX_interrupt( void )
{
	unsigned char tmptail;

	/* check if all data is transmitted */
	if ( UART_TxHead != UART_TxTail )
		{
		/* calculate buffer index */
		tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
		UART_TxTail = tmptail; /* store new index */
		UDR = UART_TxBuf[tmptail]; // start transmition 
		}
	else
		{
		UCR &= ~(1<<UDRIE); /* disable UDRE interrupt */
		}
	}

/* Read and write functions */
unsigned char ReceiveByte( void )
	{
	unsigned char tmptail;
	//if (UART_RxHead==UART_RxTail) return 0;
	//while ( UART_RxHead == UART_RxTail ) /* wait for incomming data */
		;
	tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;/* calculate buffer index */
	UART_RxTail = tmptail; /* store new index */
	return UART_RxBuf[tmptail]; /* return data */
	}

void TransmitByte( unsigned char data )
	{
	unsigned char tmphead;
	/* calculate buffer index */
	tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK; 
		/* wait for free space in buffer */

	while ( tmphead == UART_TxTail )
		;
	UART_TxBuf[tmphead] = data; /* store data in buffer */
	UART_TxHead = tmphead; // store new index 
	UCR |= (1<<UDRIE); // enable UDRE interrupt 
	}

unsigned char DataInReceiveBuffer( void )
	{
	return ( UART_RxHead != UART_RxTail ); 
		/* return 0 (FALSE) if the receive buffer is empty */
	}









void main(void) //主函数
{
unsigned int k=0;
unsigned int i=0;
	unsigned char kk=0;
	int uuu=4;
	int uuj=0;
	unsigned char uk=180;
	unsigned char jia=0;
	unsigned char mi=1;
	unsigned char san=0;
	

 InitUART(71);     
 timer1_init();
        
    
	
 MCUCR = 0x02; //TIN0 FALL

 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 
 WDR(); //this prevents a timout on enabling
 	WDTCR = 0x0C; //WATCHDOG ENABLED - dont forget to issue WDRs
		 
	;
	  port_init();
	
	   PORTA = 0B10000000;
	 
	  PORTC=PORTC & 0B11111011;
	  
	   delay_nms(40);
	   PORTA = 0B10000000;
	   PORTC=PORTC | 0B00000100;
	  WDR();
	  
	
	  RESET2510();// 使芯片复位 
	   delay_nms(600);
	   WDR();
	   b[0]=0b10010110;
	   WR2510(0x0f,1);
	
	 
	 //////////////10M晶振 缓冲1:4TQ  缓冲2:4TQ,同步1TQ,传播1TQ,TQ=(2*5/16)*10-6E=625ns
	 b[0]=0x03;
	 b[1]=0b10011000; 
	 b[2]=0x04; 
	 WR2510(0x28,3);// 波特率为 160 kbps 
	 
	 /////////////////
b[0]=0x00; 
b[1]=0x00; 
WR2510(0x20,2); 
b[0]=0x00; 
b[1]=0x00; 
WR2510(0,2);// RX0接收,屏蔽位为0,过滤器为0 
b[0]=0x00; 
b[1]=0x00; 
WR2510(0X20,2);// RX0接收,屏蔽位为0,过滤器为0 
b[0]=0x01; 
WR2510(0x2b,1);// CAN中断rxb0使能 
	b[0]=0b00000110;// 设置为正常操作模式 
	   WR2510(0x0f,1);
	   delay_nms(60);
	 RD2510(0x0e,1); 
	
	

	
b[0]=8; 
WR2510(0x35,1); 
	b[0]=0x03; 
b[1]=0X06; 
b[2]=0; 
WR2510(0x30,3);

b[0]=0; 
b[1]=0; 
WR2510(0x61,2);

	b[0]=0b01100000;  
	WR2510(0x60,1);  
	b[0]=8;  
	WR2510(0x65,1);  
	b[0]=8;  
	WR2510(0x75,1); 
	
 WDR();


	
  while(1) //程序一直执行该循环 
  {
  WDR( );
     
	
	if (data!=0)
	{
	 
	
	
	delay_nms(100);
	k=UART_RxHead;
	
	
	 
	
	 
	 b[0]=0x03; 
	b[1]=0; 
	b[2]=0; 
	WR2510(0x30,3);  
	 for(kk=0;kk<k;kk++)
	  TransmitByte(UART_RxBuf[kk]);
	 
		
		  
		  
		
		 
		
	
	
	UART_RxHead=0;
	RxHead=0;
	
	
	}
	
	
	
	
	RD2510(0x2c,1);
	if ((c[2] & 0b00000001)>0)
	{
	
	 RD2510(0x66,8); 
	for(i=0;i<8;i++)
	TransmitByte(c[2+i]);
	/b[0]=0b11000110;
	b[1]=0;
	 for(kk=0;kk<8;kk++)
	  for(i=2;i<8;i++)
	 b[i]=UART_RxBuf[i]+c[2+i];
		
		for(i=0;i<8;i++)
	
		 
		  WR2510(0x36,8);
		  RTS2510();// 发送
	
	
	b[0]=0x00; 
	WR2510(0x2c,1);// CAN中断清除
	
	}
	

	
	
	
	
	}
	
	
  WDR(); //this prevents a timout on enabling
 	//WDTCR = 0x0C; //WATCHDOG ENABLED - dont forget to issue WDRs
}
void delay_1ms(void)//1ms延时函数
{
  unsigned int i;
  for (i=0;i<2;i++)
  {
  
  } 
}
void delay_nms(unsigned int n)//延时n毫秒
{
  unsigned int i;
   
  
  for (i=0;i<n;i++)//执行n次1毫秒延时
  
  
  delay_1ms();
  
  
}
    

	
	

 
 ///////////////////////
 // 启动SPI传送 
void SPIEXCHANGE() 
 
{ 
unsigned char k;
unsigned char kk;
ci=0;
if(count>0) {// 有数据可送? 
PORTA=PORTA  & 0B01111111;//2510片选// 片选位置低电平 
 

 SPDR=a[0];;// 送数 

  //while (!(SPSR & 0x80));
 // kk=SPSR;
 
	//kk = SPDR;
  ;
} 
else 
 ;// 否则,空操作,并返回 
return; 
} 
// 等待SPI传送完成 
void WAIT_SPI() 
{ 
do{ 
 ; 
}while(count>0);// 当count!=0时,等待 to add "CLRWDT" 
return; 
} 
// 对MCP2510芯片进行复位 
void RESET2510() 
{ 
a[0]=0B1100000; 
count=1; 
	
SPIEXCHANGE();// 送复位指令 

WAIT_SPI(); 
return; 
} 
// 读取从地址"adress"开始的寄存器中的数据,共n个,存放在数组b[n]中 
int RD2510(adress,n) 
int adress; 
int n; 
{ 
int j; 
a[0]=3; 
a[1]=adress; 
for(j=0;j<n;j++)  c[j+2]=0; 
count=n+2;// 指令、地址和要得到的数据量n 
SPIEXCHANGE(); 
WAIT_SPI(); 
for(j=0;j<n;j++)  b[j]=c[j+2];// 数据存到数组b[]中 
return; 
} 
// 向从地址"adress"开始的寄存器写入数据,共n个,数据存放数组b[n]中 
void WR2510(int adress,int n) 
 
{ 
int j; 
a[0]=2; 
a[1]=adress; 
for(j=0;j<n;j++) a[j+2]=b[j]; 
count=n+2;// 指令、地址和要写入的数据量n 
SPIEXCHANGE(); 
WAIT_SPI(); 
return; 
} 
// MCP2510芯片请求发送程序 
void RTS2510() 

{ 
a[0]=0b10000001; 
count=1; 
SPIEXCHANGE();// 发送MCP2510芯片,请求发送指令 
WAIT_SPI(); 
return; 
} 
// 读取MCP2510芯片的状态 
int GETS2510() 
{ 
a[0]=0b10100000; 
c[1]=0; 
c[2]=0;
count=2; 
SPIEXCHANGE();// 读取MCP2510芯片状态 
WAIT_SPI(); 
b[0]=c[1];// 状态存到数组b[]中
b[1]=c[2]; 
return; 
} 
// 对MCP2510芯片进行位修改子程序 
void BM2510(adress,mask,data) 
int  adress; 
int  mask; 
int  data; 
{ 
a[0]=00000101;// 位修改指令 
a[1]=adress;// 位修改寄存器地址 
a[2]=mask;// 位修改屏蔽位 
a[3]=data;// 位修改数据 
count=4; 
SPIEXCHANGE(); 
WAIT_SPI(); 
return; 
} 
// 设置MCP2510芯片为正常操作模式 
void  SETNORMAL() 
{ 
int  k=1; 
BM2510(0xf,0xe0,0b10000000);// 设置为正常操作模式 //////改为回环
do{ 
 RD2510(0x0e,1); 
 k=c[2]&0xe0; 
 TransmitByte(c[2]);
}while(k);// 确认已进入正常操作模式 

return; 
} 
// 对MCP2510进行初始化 
void INIT2510() 
{ 
//RESET2510();// 使芯片复位 
 
delay_nms(4000);
RD2510(0x0e,1); 

TransmitByte(c[2]);
b[0]=0x02; 
b[1]=0x90; 
b[2]=0x07; 
WR2510(0x28,3);// 波特率为 125 kbps 
b[0]=0x00; 
b[1]=0x00; 
WR2510(0x20,2); 
b[0]=0x00; 
b[1]=0x00; 
WR2510(0,2);// RX0接收,屏蔽位为0,过滤器为0 
b[0]=0x00; 
WR2510(0x2b,1);// CAN中断不使能 
SETNORMAL();// 设置为正常操作模式 
//b[0]=0x00; 
//WR2510(0xe,1);
return; 
} 
// MCP2510芯片发送完成与否判断,邮箱号为adress 
void TXCOMPLETE(adress) 
int adress; 
{ 
int k=1; 
do{ 
 RD2510(adress,1); 
 k=b[0]&0x08; 
}while(k);// 确认是否已发送完毕 to add CLRWDT 
return; 
} 

⌨️ 快捷键说明

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