无敌小青年 发表于 2012-4-19 21:55:19

真诚询问马老师一个AVR程序问题,谢谢

马老师 我用的Atmega128 定时计数的输入捕获功能测量一个方波(例如50Hz)的周期然后通过串口助手将处理计算后的周期值显示在电脑上 以下是我编的程序 希望您能看一下,我用示波器发送50HZ方波 但是我在串口助手里怎么都不能接收数据,但是切换成十六进制形式能接收一串乱码   
#include<iom128v.h>
#include<macros.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define BAUD 9600
#define F_CPU 8000000

//全局变量定义
uint WAN=0,QIAN=0,BAI=0,SHI=0,GE=0;//万,千,白,十,个位
uchar flow_flag=0;//溢出次数
uint icpnum=0;
uchar timerover_error=0;
uint last_icrvalue=0;
uint value;

void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
    for(j=0;j<1141;j++);
}

//USART寄存器配置
void usart_init(void)
{
UCSR0A=0x00;//bit1为0对波特率加倍无作用
UCSR0C=(1 << UCSZ01) | (1 << UCSZ00);//奇偶模式无,8位数据位,1位停止位,异步模式
UBRR0L = (F_CPU / BAUD / 16 - 1) % 256;
UBRR0H = (F_CPU / BAUD / 16 - 1) / 256;
UCSR0B|=(1<< RXEN0)|(1<< TXEN0)|(1<<RXCIE0);//发送接收使能,接收结束使能
}

//字节发送函数
void usart_putchar(uchar y)
{
while(!(UCSR0A&(1<<UDRE0)));//只有数据寄存器为空才能发送数据
UDR0=y;
}
/*
void usart_puts(char *s)
{
while(*s)
    {
          usart_putchar(*s);
          s++;
        }
        usart_putchar(0x0a);//回车换行
        usart_putchar(0x0d);
}
*/
//T/C1初始化
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
TCCR1A = 0x00;
TCCR1B = 0xC2; //start Timer上升沿触发,选择8分频
}

#pragma interrupt_handler timer1_capt_isr:12
//定时计数器1输入捕捉中断使能
void timer1_capt_isr(void)
{
CLI();
value=ICR1L;         //Read low byte first (important)
value|=(uint)ICR1H << 8; //Read high byte and shift into top byte

//根据 flow_flag 的不同,计算真实的ICR差值
if(flow_flag==0)
{
icpnum=value-last_icrvalue;
}
else
{
if(flow_flag==1)
{
//说明TCNT越过一次TOP
flow_flag=0;
icpnum=0xFFFF-last_icrvalue+value;
}
else
{
//超时(越界两次以上)未检查到信号,错误处理
timerover_error=1;
flow_flag=0;
}
}
last_icrvalue=value;
SEI();
}

#pragma interrupt_handler timer1_ovf_isr:15
//定时计数器1溢出中断使能
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
flow_flag ++ ;
}

//器件初始化
void init_devices(void)
{
CLI();
DDRD&=~(1<<PD4);;
PORTD = (1<<PD4); //ICP1引脚为输入并带上拉电阻
usart_init();
timer1_init();
TIMSK = 0x24; //timer interrupt sources输入捕获中断使能,溢出中断使能
SEI(); //re-enable interrupts
}

//16进制转10进制函数
void conver16_to10(uint num)
{
for(WAN=0;num>=10000;)
    {
   num=num-10000;
       WAN=WAN+1;
        }
for(QIAN=0;num>=1000;)
    {
   num=num-1000;
       QIAN=QIAN+1;
        }
for(BAI=0;num>=100;)
    {
   num=num-100;
       BAI=BAI+1;
        }
for(SHI=0;num>=10;)
    {
   num=num-10;
       SHI=SHI+1;
        }               
GE=num;
}


void shuchu(uint abc)
{
uchar ten_0,ten_1,ten_2,ten_3,ten_4;
conver16_to10(abc);
ten_0=WAN;
ten_1=QIAN;
ten_2=BAI;
ten_3=SHI;
ten_4=GE;
usart_putchar(ten_0);
usart_putchar(ten_1);
usart_putchar(ten_2);
usart_putchar(ten_3);
usart_putchar(ten_3);
}

void main(void)
{
   uint Freque=0,t=0;
   uint temp=0;
   init_devices();
while(1)
{
if(timerover_error==1){}
temp=icpnum; //读出再处理,防止中断中在对icpnum改写,造成影响
Freque=(uint)((float)1000000/temp); //频率Hz
t=temp;       //周期 us
shuchu(temp);
}
}
页: [1]
查看完整版本: 真诚询问马老师一个AVR程序问题,谢谢