📄 cymometer.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 + -