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

📄 sudu.c

📁 用AVR单片机实现脉冲采集源代码
💻 C
字号:
/**********************************/
/*        汽车转速测量程序
/*           8.24,2004
/*        Writed by Wuxw
/*    Automation Depart. of WHUT
/*          芯片:ATMEGA8L
/*          晶振:2MHz
/*        
/*
/***********************************/
/*    脉冲输入接在INT0端口
/*    
/*    输出n,单位r/50ms,可用来计算车轮转速
/*
/*    num----脉冲计数,可用来计算里程    
/*
/*    485输出格式:FB-86-n-numLL-numLH-numHL-numHH
/*    
/*    numLL-numLH-numHL-numHH分别为num的四个字节(L为低字节,H为高字节)
/*
/*    串口485通讯波特率baud = 9600
/*    
/*    在受到正确地址(0x32)和命令(0xc5)后,发送数据
/*
/***********************************/



#include "iom8v.h"  
#include "macros.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

#define E2ADDRLL 0x000         //脉冲计数存放地址
#define E2ADDRLH 0x001    
#define E2ADDRHL 0x002      
#define E2ADDRHH 0x003     
//#define osccal 0x9d//内部RC 校正常数

//#define osccal 0xa4       //内部RC校正常数
#define fosc 8000000      //晶振8MHZ
#define baud 9600         //串口通讯波特率
#define TIME50ms 0xae     //定时50ms的初装值

#define osccal_addr 0x1ff

uint m,n,k;
ulong num;      //脉冲计数
uchar numLL,numLH,numHL,numHH,K,nLL,nLH;
uchar flag_receive,ndata[8]={0xFB,0x86,0x55,0x00,0x00,0x00,0x00,0x00};
uchar i,cx,xxx[3];
uchar data_receive[3];


//最小延时单位,约16微秒
void delay(uchar x)   
{   uchar j;
    while(x-->0)
	{
       for(j=0;j<5;j++)
	   {;}
    }
}

void decompose(void)
{
    numLL = num;
	num=(num>>8);
	numLH= num;
	num= (num>>8);
	numHL=num;
	num=(num>>8);
	numHH=num;
	
	//nLL = n;
	//n=(n>>8);
	//nLH= n;
}

void combination(void)
{
    num = 0;
    num = numHH;
	num = num<<8;
	num += numHL;
	num = num<<8;
	num += numLH;
	num = num<<8;
	num += numLL;
	
	//n = 0;
    //n= nLH;
	//n = n<<8;
	//n += nLL;
	
}

void e2rom_write(uint e2addr,uchar e2data)  //EEROM写数据
{
	 while(EECR & (1<<EEWE));
	 EEAR = e2addr;
	 EEDR = e2data;
	 
	 EECR |= (1<<EEMWE);
	 EECR |= (1<<EEWE);
}

uchar e2rom_read(uint e2addr)   //EEROM读数据
{
    while(EECR & (1<<EEWE));
	EEAR = e2addr;
	EECR |= (1<<EERE);
	return EEDR;
}

void num_read(void)     //从EEROM读出num
{
    numLL = e2rom_read(E2ADDRLL);
	numLH = e2rom_read(E2ADDRLH);
	numHL = e2rom_read(E2ADDRHL);
	numHH = e2rom_read(E2ADDRHH);
	combination();
	
}

void num_write(void)    //将num写入EEROM
{
    decompose();
	e2rom_write(E2ADDRLL,numLL);
	e2rom_write(E2ADDRLH,numLH);
	e2rom_write(E2ADDRHL,numHL);
	e2rom_write(E2ADDRHH,numHH);
}
	
void DataTransmit(void)   //串行485数据发送
{
    //ndata[2] = nLL;
	 ndata[3] = n;
	ndata[4] = numLL;
	ndata[5] = numLH;
	ndata[6] = numHL;
	ndata[7] = numHH;
	UCSRB|=(1<<TXCIE);
	UDR = ndata[0];
    
	}


#pragma interrupt_handler uart0_tx_isr:iv_USART_TXC
void uart0_tx_isr(void)
{
          
if(K<7)
     {K=K+1;
	 UDR=ndata[K];
	 }  
       
     else
    {
	K=0;   
	UCSRB&=~(1<<TXCIE);  //1?UART ?¤?é?¨a?D??
	} 
     
     
}

void USART_Init(void)    //串行初始化
{
    UCSRB|=(1<<TXEN);//允许发送
  UBRRL=(fosc/16/(baud+1))%256; //波特率的设置
  UBRRH=(fosc/16/(baud+1))/256;
  UCSRC=0x86;//8 位数据+1 位STOP 位
	 
}


//定时器0溢出中断
#pragma interrupt_handler tim0Ovf:10		// vector #
//测量时间定时
void tim0Ovf(void)
{
    TCCR0 = 0x00;   //停止TC0
	//INT0中断关
	GICR = 0x00;
	
	m += 1;
	TCNT0 = TIME50ms; 
	TCCR0 = 0x05;      // Timer on //1024分频
	
	//PORTB |= (1<<PORTB1);
	//PORTB &= ~(1<<PORTB1);
	
	if(GIFR& 0x40)
      GIFR = 0x40;    //清除INT0中断标志
	SEI();
	//INT0中断开
	GICR = 0x40;
	
}
//INT0中断服务子程序
#pragma interrupt_handler INT_0:2	// vector #

void INT_0(void)
{
    n = m;
	/*
	while(1)
	{
	PORTD |= (1<<PORTD3);
	PORTD &= ~(1<<PORTD3);
	delay(500);
	}
	*/
	num_read();      //从EEROM读出num
	num += m ;  
	num_write();     //将num写入EEROM
	DataTransmit();  //串行485数据发送
	m = 0;
	TCNT0 = TIME50ms;
	TCCR0 = 0x05;    //Timer on //1024分频
	
  
}


void main(void)
{
    delay(200);
    OSCCAL=e2rom_read(osccal_addr); 
	 //OSCCAL=osccal;
	 
	PORTD|=(1<<PORTD3);
	
	MCUCR = 0x02;        //INT0下降沿				 
	TIMSK = 0x01;        //TC0溢出中断允许
	
	//定时器0中断设置
	TCCR0 = 0x00;        //停止TC0
	TCNT0 = TIME50ms;    //初装值
	
	USART_Init();
	
	DDRD=0xfb;
	
	SEI();
	
	GICR = 0x40;         //INT0中断开
	m = 0;
	TCCR0 = 0x05;        //Timer on //1024分频
	//主循环...
	
	while(1)
	{
	   /*测试程序段,已屏蔽*/
	   /*PORTB &= ~(1<<PORTB2);
	   delay(1);
	   PORTB |= (1<<PORTB2);
	   */
	 DataTransmit();
	for(k=1;k<100;k++)
	     delay(200);  
    
	    
	}
   

}

⌨️ 快捷键说明

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