2 bra hancock Bra_Hancock 于 2016.04.24 14:21 提问

ATmega16A 定时器0 不明原因程序不运行

想用定时器实现按毫秒定时(输入多少毫秒就定多少)
配置了MCUCR GICR TIMSK SREG TCCR0 TCNT0 中断函数 以及输出电平
熔丝位设置:CKOPT:0 CKSEL:1111 SUT:10 外部12M晶振
功能就是让数码管亮 锁存控制具体哪个数码管
for循环延时正常 通电瞬间会全亮一下然后循环
现在用定时器 不知道什么原因 通电之后全亮了 应该是卡在程序开头 然而开头只是个io口电平设置啊

环境 CodeBlocks13.12 编译器 WinAVR

刚才测了输出的电平 用1个单片机测的是3.66V 另1个是3.11V 都不是高电平


#include <avr/io.h>
//#include <avr/iom16a.h>
//#include <avr/iom16.h>


unsigned int digits[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //0-10和无数字
unsigned int count0 = 0;
unsigned int ms = 0;

void portInit(void)
{
    //A输出到数码管,B输出到锁存LE
    //先规定电平后规定方向防止默认电平
    PORTA = 0x00;
    DDRA = 0xff;
    PORTB = 0x00;
    DDRB = 0xff;
    PORTC = 0x00;
    DDRC = 0xff;
    PORTD = 0x00;
    DDRD = 0xff;
}


//#define _TC0_
#ifndef _TC0_
void timer0Init(void)
{
    SREG = 0x80;   //全局中断  Page7
    TIMSK = 0x01;   //T/C0  Page 80
    TCNT0 = 209;
    TCCR0 = 0x04;  //256分频  Page79
}

void timer0Off(void)
{
    SREG = 0x00;   //全局中断  Page7
    TIMSK = 0x00;   //T/C0  Page 80
    TCCR0 = 0x00;
}

/*
//针对晶振12M
void delayMs(unsigned int ms)
{
    unsigned int count0 = 0;
    TCNT0 = 209;
    while(1)
    {
        TCCR0 = 0x04;  //256分频  Page79
        if(++count0 >= ms)
        {
            TCCR0 = 0x00;
            //count0 = 0;
            break;
        }
        else
        {
        }
    }
}
*/
void delayMs(unsigned int mss)
{
    timer0Init();
    ms = mss;
}

#pragma interrupt_handler timer0Ovf: 10  //中断向量  Page43
void timer0Ovf(void)
{
    TCNT0 = 209;             //重装计数初值
    if(++count0 >= ms)
    {
        timer0Off();
        count0 = 0;
        ms = 0;
    }
}

void main(void)
{
    unsigned int i;
    portInit();
    timer0Off();
    GICR = 0x00;
    MCUCR = 0x00;         //Page30
    PORTB = 0x3f;
    PORTA = digits[10];
    while(1)
    {
        for(i=0;i<11;i++)
        {
            delayMs(300);
            PORTA = digits[i];
        }
    }
}

#else   //for循环延时
void main(void)
{
    unsigned int i,j;
    portInit();
    PORTB = 0x3f;
    PORTA = digits[10];
    while(1)
    {
        for(j=0;j<11;j++)
        {
            for(i=0;i<20000;i++)
            {
            }
            PORTA = digits[j];
        }
    }
}
#endif

1个回答

Bra_Hancock
Bra_Hancock   2016.04.24 15:53

刚才有些行顺序错了 但是不是本质错误 通过逐行注释 发现错误在TCCR0上 不知道为什么 程序卡住
改后代码


#include <avr/io.h>
//#include <avr/iom16a.h>
//#include <avr/iom16.h>


unsigned int digits[11] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //0-10和无数字
unsigned int count0 = 0;
unsigned int ms = 0;

void portInit(void)
{
    //A输出到数码管,B输出到锁存LE
    //先规定电平后规定方向防止默认电平
    PORTA = 0x00;
    DDRA = 0xff;
    PORTB = 0x00;
    DDRB = 0xff;
    PORTC = 0x00;
    DDRC = 0xff;
    PORTD = 0x00;
    DDRD = 0xff;
}


void timer0Init(void)
{
    SREG |= 0x80;   //全局中断  Page7
    TIMSK |= 0x01;   //T/C0  Page 80
    TCNT0 = 209;
    TCCR0 |= 0x04;  //256分频  Page79
}

void timer0Off(void)
{
    SREG = 0x00;   //全局中断  Page7
    TIMSK = 0x00;   //T/C0  Page 80
    TCCR0 = 0x00;
}

/*
//针对晶振12M
void delayMs(unsigned int ms)
{
    unsigned int count0 = 0;
    TCNT0 = 209;
    while(1)
    {
        TCCR0 = 0x04;  //256分频  Page79
        if(++count0 >= ms)
        {
            TCCR0 = 0x00;
            //count0 = 0;
            break;
        }
        else
        {
        }
    }
}
*/
void delayMs(unsigned int mss)
{
    ms = mss;
    timer0Init();
}

#pragma interrupt_handler timer0Ovf: 10       //中断向量  Page43
void timer0Ovf(void)
{
    if(++count0 >= ms)
    {
        timer0Off();
        count0 = 0;
        ms = 0;
    }
    else
    {
        TCNT0 = 209;             //重装计数初值
    }
}

//#define _TC0_
#ifndef _TC0_

void main(void)
{
    unsigned int i,k;
    portInit();
    timer0Off();
    GICR = 0x00;
    MCUCR = 0x00;         //Page30
    PORTB = 0x3f;
    PORTA = digits[10];
    while(1)
    {
        for(i=0;i<11;i++)
        {
            delayMs(100);

            for(k=0;k<10000;k++)
            {
            }
            PORTA = digits[i];
        }
    }
}

#else   //for循环延时
void main(void)
{
    unsigned int i,j;
    portInit();
    PORTB = 0x3f;
    PORTA = digits[10];
    while(1)
    {
        for(j=0;j<11;j++)
        {
            for(i=0;i<10000;i++)
            {
            }
            PORTA = digits[j];
        }
    }
}
#endif

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!