Bra_Hancock 2016-04-24 06:21 采纳率: 0%
浏览 1727

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 2016-04-24 07: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
    
    
    评论

报告相同问题?

悬赏问题

  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)