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

📄 cymometer.c

📁 关于学习avr单片机的资料
💻 C
字号:
/* 
    Title:    AVR-GCC Cymometer program for the Cymometer board
    Author:   yfzhang
    Date:     3/2005
    Purpose:  
    needed
    Software: AVR-GCC to compile
    needed
    Hardware: ATmega8 on Cymometer board
    Note:     To contact me, mail to
                  yfzhang@ele.pku.edu.cn
*/

#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <avr/iom8.h>
#include <avr/sleep.h>
#include <math.h>

#include "global.h"		// include our global settings
#include "Cymometer.h"		// include main include

SIGNAL(SIG_OVERFLOW0)     /* signal handler for Time0 interrupt */
{
	T_5ms_num++;		//5ms 执行一次(200Hz)
	if(T_5ms_num==25){
		T_5ms_num=0;	//125ms 执行一次
		
//		if(T_125ms_num&1)Display_on=1;
		
		T_125ms_num++;
		if(T_125ms_num>15){	//per 2 second exec one time
			T_125ms_num=0;
			Two_Second=1;
//			Count_start_F=1;
		}
		else if((T_125ms_num==1)||(T_125ms_num==3)) LED_ON;
		else if((T_125ms_num==2)||(T_125ms_num==4)) LED_OFF;
		else if((T_125ms_num==5)||(T_125ms_num==13)){
			T_Second_num++;
			}
		else if((T_125ms_num&1)==0) pc_update=1;
		else
			;
		}
	TCNT0 = 6;      /* Set TIMER0 50kHz/250=200Hz         */
}
SIGNAL(SIG_OVERFLOW1)     /* signal handler for Time1 interrupt */
{
	Count3++;
}
SIGNAL(SIG_INPUT_CAPTURE1)
{
	u16 value;
	Count1 ++;
	value=ICR1;
	if(Count1==3)            //第一个上升沿到来,记录时间印记到COUNT3
  	{     
		Count2 = value; 
		Count3 = 0;
  	}  
	else if((Count1>=3)&&(Count3>100))     //计时大于512ms,记录时间印记到COUNT4
  	{
  		T__allnum=Count1;
		Count4 = value;
		Cont3_end=Count3;
		Count_end_F = 1;
  	}  
	
}
void AvrInit (void)
{
	PORTD = 0;     /* bit 7..0 input  no pull-up */
	DDRD =  0;	 /* PortD bit 7..1 input */
	PORTB = 1;     /* bit 0 input   pull-up */
	DDRB =  _BV(DDB1);	 /* PortB bit 0 output */
	PORTC = _BV(DDB0)|_BV(DDB1);     /* bit 0,1 input   pull-up */
	DDRC = _BV(DDB0)|_BV(DDB1)|_BV(DDB2);	 /* PortC bit 0,1,2 output */
	
	TCCR0 = _BV(CS02);      /* Set TIMER0 prescaler to CLK/256   50kHz           */
	TCNT0 = 6;      /* Set TIMER0 50kHz/250=200Hz         */
	TCCR1B = _BV(CS10);      /* Set TIMER1 prescaler to CLK/1  and mode =normal           */
	
	TIMSK =_BV(TOIE0)|_BV(TOIE1);      /* Enable TIMER0 & TIMER1 overflow interrupt            */
	
	Count_start_F = 1;
	Count_end_F = 0;

}
void Delay_t(u16 t)
{
	u16 i;
	for(i=0;i<t;i++){
		;
	}
}
void delay(u08 ms){
	u08 i;
	for(i=0;i<ms;i++){
		Delay_t(924);
	}
}
void hex_to_ascii(u08 *p,u08 num){
	u08 c[16];
	u08 i,ch,cl;
	for(i=0;i<num;i++){
		c[i]=p[i];
		}
	for(i=0;i<num;i++){
		ch=cl=c[i];
		cl&=0x0f;ch>>=4;cl|=0x30;ch|=0x30;
		if(cl>0x39)cl+=7;
		if(ch>0x39)ch+=7;
		p[2*i]=ch;p[2*i+1]=cl;
	}
	p[2*num]=0;
	}
void ascii_to_hex(u08 *p,u08 num){
	u08 i,ch,cl;
	for(i=0;i<num;i++){
		ch=p[2*i];cl=p[2*i+1];
		ch-=0x30;cl-=0x30;
		if(cl>9)cl-=7;
		if(ch>9)ch-=7;
		cl&=0x0f;ch&=0x0f;ch<<=4;
		p[i]=cl|ch;
		}
	}

void initLCD(void){
	u08 i;
	delay(15);
	LCD_CW_ADD(0x30);
	delay(5);
	LCD_CW_ADD(0x30);
	delay(5);
	LCD_CW_ADD(0x30);
	delay(5);
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x38);
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x08);	//显示关闭
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x01);	//清屏
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x0c);	//显示开及光标设置
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x06);	//输入方式  数据读写后AC++,画面不动
	while(chackLCDbusy()){;}
	LCD_CW_ADD(0x48);	//设置CGRAM地址
	writeLCD_cgtab();
	pc_LCDstatus=0;
	pc_LCDsetup_start=0;
	for(i=0;i<80;i++)buffer_LCD.LCD_buffer[i]=pgm_read_byte(&LCD_init[i]);
	pc_LCDsetup_start=1;
}
u08 LCD_CR_ADD(void){
	u08 temp;
	PORTC|=_BV(DDB1);	//for Read
	PORTC&=~_BV(DDB0);	//for Ctrl
	PORTC|=_BV(DDB2);	//LCD E is high
	Delay_t(1);
	temp=PIND;
	PORTC&=~_BV(DDB2);	//LCD E is low
	return temp;
	}
void LCD_CW_ADD(u08 cw){
	PORTC&=~_BV(DDB1);	//for Write
	PORTC&=~_BV(DDB0);	//for Ctrl
//	PORTD = 0;     /* bit 7..0 input  no pull-up */
//	DDRD =  0;	 /* PortD bit 7..1 input */
	PORTD = cw;
	DDRD =  0xff;
	PORTC|=_BV(DDB2);	//LCD E is high
	Delay_t(1);
	PORTC&=~_BV(DDB2);	//LCD E is low
	DDRD=0;
	PORTC|=_BV(DDB1);	//for Read
	PORTD=0;
	}
void LCD_DW_ADD(u08 dw){
	PORTC&=~_BV(DDB1);	//for Write
	PORTC|=_BV(DDB0);	//for data
//	PORTD = 0;     /* bit 7..0 input  no pull-up */
//	DDRD =  0;	 /* PortD bit 7..1 input */
	PORTD = dw;
	DDRD =  0xff;
	PORTC|=_BV(DDB2);	//LCD E is high
	Delay_t(1);
	PORTC&=~_BV(DDB2);	//LCD E is low
	DDRD=0;
	PORTC|=_BV(DDB1);	//for Read
	PORTD=0;
	}
void  PutString_LCD(u08 xpos,u08 ypos,u08 *s){ /* Write a null-terminated string to the  LCD buffer  */
u08 *p;
	switch(ypos){
		case 0: p=&buffer_LCD.L_line.line0[xpos];
			break;
		case 1: p=&buffer_LCD.L_line.line1[xpos];
			break;
		case 2: p=&buffer_LCD.L_line.line2[xpos];
			break;
		case 3: p=&buffer_LCD.L_line.line3[xpos];
			break;
		default: p=&buffer_LCD.L_line.line3[xpos];
			break;
		
	}
	while (*s != '\0') {
		*p=*s;
      		s++;p++;
    	}
}
void  PutString_LCD_P(u08 point,u08 *s){ /* Write a null-terminated string to the  LCD buffer  */
u08 *p;
	p=&buffer_LCD.LCD_buffer[point];
	while (*s != '\0') {
		*p=*s;
      		s++;p++;
    	}
}
u08 chackLCDbusy(void){
	u08 temp;
	temp=LCD_CR_ADD();
	temp&=0x80;
	return temp;
	}
void writeLCD_cgtab(void){
	u08 i;
	for(i=0;i<32;i++){
		do{;}while(writeLCD_data(pgm_read_byte(&LCD_cgtab[i])));
		}	
	}
u08 setLCD_pos(u08 xpos,u08 ypos){
	u08 ddram;
	if(chackLCDbusy()!=0){
		return 0xff;	//LCD is busy
		}
	ddram=xpos;
	while(ddram>=20){
		ddram-=20;
		}
	if(ypos&0x01)ddram+=0x40;
	if(ypos&0x02)ddram+=0x14;
	LCD_CW_ADD(0x80|ddram);
	return 0;
}
u08 setLCD_posadd(u08 posadd){
	if(chackLCDbusy()!=0){
		return 0xff;	//LCD is busy
		}
	LCD_CW_ADD(0x80|posadd);
	return 0;
}
u08 writeLCD_data(u08 d){
	if(chackLCDbusy()!=0)return 0xff;	//LCD is busy
	LCD_DW_ADD(d);
	return 0;
}
void communicate_with_LCD(void){
	u08 data_temp;
	switch(pc_LCDstatus){
		case 0:	{
			if(pc_LCDsetup_start){	//LCD开始更新数据
				pc_LCDsetup_start=0;
				pc_LCDaddress=0;
				pc_LCDstatus=1;
				LCD_work_is_busy=1;
			}
			else LCD_work_is_busy=0;
				}
			break;
		case 1:{
			if(setLCD_posadd(pc_LCDaddress)==0){
				pc_LCDstatus=2;
				}
			}
			break;
		case 2:{
			data_temp=buffer_LCD.LCD_buffer[pc_LCDaddress];
			if(writeLCD_data(data_temp)==0){
				pc_LCDaddress++;
				if(pc_LCDaddress==40){
					pc_LCDstatus=3;
				}
				else pc_LCDstatus=1;
			}
			}
			break;
		case 3:{
			if(setLCD_posadd((pc_LCDaddress+0x18))==0){
				pc_LCDstatus=4;
				}
			}
			break;
		case 4:{
			data_temp=buffer_LCD.LCD_buffer[pc_LCDaddress];
			if(writeLCD_data(data_temp)==0){
				pc_LCDaddress++;
				if(pc_LCDaddress==80){
					pc_LCDstatus=0;
				}
				else pc_LCDstatus=3;
			}
			}
			break;
		default:
				{
				pc_LCDstatus=0;
				pc_LCDsetup_start=0;	
				pc_LCDaddress=0;
				}
			break;
		
		}
	}

int main(void)
{
	double t1,t2,t3;
	u08 dp_i;
	char act[]="-\004|/";
	
   cli();                 /* disable interrupts */
   AvrInit();             /* Initialize the AVR UART and Timer  */
   Two_Second=0; 
//	wdt_enable(7);		
	T_Second_num=0;
	T_Second_num=0;
   initLCD();
   delay(250);
 //  PutString_LCD(15,3,"GOOD");
   sei();
   for (;;) 
	{	
  		if(Display_on!=0){
   			Display_on=0;
     			display_frequency(3, 2, t2);
     			dp_i++;if(dp_i>3)dp_i=0;
     			buffer_LCD.L_line.line3[1]=act[dp_i];
     			pc_LCDsetup_start=1;
   		}
    		Count_start_F=Count_start_F;
   		if(Count_start_F!=0){
			Count_start_F=0;
			Count1=0;
			TIMSK |=_BV(TICIE1);	/*Enable  INPUT_CAPTURE1 interrupt*/
			}
   		Count_end_F=Count_end_F;
   		if(Count_end_F!=0){
    			Count_end_F=0;
			TIMSK &=~_BV(TICIE1);	/*disable  INPUT_CAPTURE1 interrupt*/
			
    			m_sync_errnum=Cont3_end;
    			m_sync_errnum<<=16;
    			m_sync_errnum+=Count4;
    			m_sync_errnum-=Count2;
    			t1=12800000.0*((double)(T__allnum-3));
    			t2=(double)m_sync_errnum;
    			t3=inverse(t2);
    			t2=t1*t3*128.0;	//74HC4060 Q7 128 times f
    			Display_on=1;
    			Count_start_F=1;
   			}
 		communicate_with_LCD();
/*		if(pc_update!=0){
			pc_update=0;
			pc_LCDsetup_start=1;
			}*/
	}            /* loop forever */
}
void display_frequency(u08 xpos,u08 ypos,double m)//(1, 1, m_sync_errnum);
{
	char msg[10],msg1[]="(MHz)";
	u32 f;
	u08 i,s;
	s=1;
	while(m<10000000.0){
		m*=10.0;
		s++;
	}
	f=(u32)m;
	i=0;
	while(f>9999999){
		f-=10000000;i++;
	}
	msg[0]=i|0x30;
	i=0;
	while(f>999999){
		f-=1000000;i++;
	}
	msg[1]=i|0x30;
	i=0;
	while(f>99999){
		f-=100000;i++;
	}
	msg[2]=i|0x30;
	i=0;
	while(f>9999){
		f-=10000;i++;
	}
	msg[3]=i|0x30;
	i=0;
	while(f>999){
		f-=1000;i++;
	}
	msg[4]=i|0x30;
	i=0;
	while(f>99){
		f-=100;i++;
	}
	msg[5]=i|0x30;
	i=0;
	while(f>9){
		f-=10;i++;
	}
	msg[6]=i|0x30;
	msg[7]=f|0x30;
	msg[9]=msg[8]=0;
	if(s<3){
		msg1[1]='M';
		i=s;
		}
	else if(s<6){
		msg1[1]='k';
		i=s-3;
		}
	else if(s<9){
		msg1[1]=' ';
		i=s-6;
	}
	else
		;
	for(s=0;s<5+i;s++){
		msg[8-s]=msg[7-s];
	}
	msg[3-i]='.';
	PutString_LCD(xpos,ypos,msg);
	PutString_LCD((xpos+10),ypos,msg1);
}

⌨️ 快捷键说明

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