harng 发表于 2008-4-23 09:06:40

马老师,请教一个问题

程序可以正常运行,但就是感觉写的不好,希望高手指点一下
我用了两个定时器,一个是用来扫描按键,一个用来数码管计数用的.
下载以后程序可以运行(下载线还在下载端口上,没BA出来)然后关了电源,重启一下,那个PINC4接的按键就不行了,还有如果把下载线BA了,数码管就会自动计数,不知什么原因,还请马老师指点一下哦,还有就是我的数码管是1秒自动计数的,感觉要小于一秒,不知是怎么回事呀
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.7a Evaluation
Automatic Program Generator
?Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 2008-3-30
Author: Freeware, for evaluation and non-commercial use only
Company :
Comments:
PC4为按键计数键,按键时数码管自动加1,PC6为开始作减法自动计数键(按一下,开始减法计数,在按一下暂停,在按一下复位)

Chip type         : ATmega16
Program type      : Application
Clock frequency   : 4.000000 MHz
Memory model      : Small
External SRAM size: 0
Data Stack size   : 256
*****************************************************/

#include <mega16.h>
flash unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//定义字符表
flash unsigned char position={0x01,0x02,0x4,0x08};
unsigned chartime;//显示时,分
unsigned char      led;      //                        
unsigned char keycnt;    //按键计数变量
unsigned int time_counter; // 中断次数计数单元
unsigned char      posit,n;
bit      point_on, time_1s_ok;   




void time_to_disbuffer(void)//显示缓冲区
{   led=time%10;
    led=time/10;
    led=time%10;
    led=time/10;
   
}
void display(void)//数码管显示程序
{       PORTC =0X70;
      PORTD = table];
      PORTC= position;
      if (++posit >=4 ) posit = 0;
         
}
void delay(unsigned int a)
{
      while(a--)
         {
         
         }
}

void key_in(void)//按键扫描程序
{
if((PINC&(1<<4))==0)//按键是否按下,
   {
      delay(35000);//延时消抖?
      if((PINC&(1<<4))==0)//确认按键按下
       { time++;
             if(time==100)
                  {time=0;}
                time_to_disbuffer();
               
                }
          }
   
   

}
interrupt void timer2_comp_isr(void)   //Timer 2比较匹配中断服务
{                     // 调用LED扫描显示
      if (++time_counter>=500) //1秒
      {       time_1s_ok=1;
                time_counter = 0;
                if(time_1s_ok)
                {time_1s_ok=0;
                  time--;
                  n=time;
                  if(time==0)
                  {time=0;
                  
                  TIMSK=0X02;}
                  time_to_disbuffer();
                  }
               
      }
}
// Timer 0 比较匹配中断服务
interrupt void timer0_comp_isr(void)
{      
      display();
                                        // 调用LED扫描显示
         
}


void main(void)
{      
      PORTD=0XFF;
      DDRD=0XFF;
      PORTC=0X70;
      DDRC=0X8F;
      // T/C0 初始化
      TCCR0=0x0B;                              // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
      OCR0=0x7C;                         // OCR0 = 0x7C(124),(124+1)/62.5=2ms
      TCNT0=0x00;
      TIMSK=0x02;                              // 允许T/C0比较匹配中断   
         
         
         
       time = 00; time = 00;                // 设初值
      posit = 0;
         
          time_to_disbuffer();
          #asm("sei");
          while(1){
                  if((PINC&(1<<6))==0)
                   {delay(30000);
                      if((PINC&(1<<6))==0)
                     {   keycnt++;
                           switch(keycnt)
                           {
                               case 1:
                              
                              if(time==0)
                                  {keycnt=0;
                                  break;}
                              TCCR2=0x0B;                              // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
                              OCR2=0x7C;                         // OCR0 = 0x7C(124),(124+1)/62.5=2ms
                              TCNT2=0x00;
                              TIMSK=0x82;                              // 允许T/C2比较匹配中断
                              
                               break;
                                 
                                 
                              
                               case 2:
                               TIMSK=0X02;//不允许T/C2比较匹配中断
                              
                               time_to_disbuffer();
                              
                               break;
                               case 3:
                               keycnt=0;
                                 
                               time = 0;
                               time_to_disbuffer();
                               break;   
                              }
                              while((PINC&(1<<6))==0);
                           }
                            } key_in();
                         }
                        }
                        
 

machao 发表于 2008-4-23 09:36:08

建议你下载我电子书的前2篇学习一下,编程的思想方法要更新.

harng 发表于 2008-4-23 11:58:42

是不是你出的那本书的前两章呀,那本书我买了

eagle_1 发表于 2008-4-23 13:45:08

用马老师新出的书,里面有个状态机的键盘设计,用状态机的思想可以只用一个定时器实现很多功能:比如键盘单按键/按键连_发,数码管的显示,定时,PWM等等,当然功能都是在主程序里实现的,呵呵,提个方法,具体的自己琢磨一下...

machao 发表于 2008-4-23 17:45:54

1.首先在你的程序中使用delay()函数,这是我不提倡的(几个us的除外),我书中在第8章后就不使用软件延时了.
2."我用了两个定时器,一个是用来扫描按键,一个用来数码管计数用的".实际使用一个就可以了,看我书中例子.
3."数码管是1秒自动计数的,感觉要小于一秒",要准的话,最好采用外部晶体.CTC方式(这个你用对了)
4.程序冗余,乱.比如:
interrupt void timer2_comp_isr(void)   //Timer 2比较匹配中断服务
{                     // 调用LED扫描显示
   if (++time_counter>=500) //1秒
   {
       time_1s_ok=1;
       time_counter = 0;   
       if(time_1s_ok)                  //这个判断明显多余的!!
       {
         time_1s_ok=0;
         time--;
         n=time;
         if(time==0)
         {
               time=0;
               TIMSK=0X02;            // 这句的作用是什么?有必要吗?
         }
         time_to_disbuffer();   
       }
   }
}

5.不知道你使用哪片AVR.如果是M16,并使用ISP通过SPI下载的话,是不会影响PORTC口工作的.

===============================
你可能学过或使用过51,但建议你仔细读我的书,并体会里面的东西,会更上一层楼的.

harng 发表于 2008-4-24 09:18:16

马老师,非常感谢你给我的指导,这几天一直在看你的书,我想问一下,就是想学一下LCD的用法,是否可以先学你书中的那个LCD呀,那以后用到别的LCD是否会用,还是要看LCD的说明书呀
对了TIMSK=0X02; 我是想禁止定时器2产生中断,不知这样合不合适呀,我是想计数减到0时就停止,不让它继续下去了,不知还有没有好的方法呀,再次感谢!!

harng 发表于 2008-4-24 09:21:24

对了,还有一点,如果我只使用一个定时器的话,那我在数码管计数到0时,想不让计数了,那怎么办呀,如果把中断屏蔽掉的话,扫描程序不也就退出了,谢谢!!

machao 发表于 2008-4-24 11:17:02

STEP BY STEP 是最好的学习方法和态度.

alice5208 发表于 2011-1-6 19:54:18

不错,保留
页: [1]
查看完整版本: 马老师,请教一个问题