马老师,请教一个问题
程序可以正常运行,但就是感觉写的不好,希望高手指点一下我用了两个定时器,一个是用来扫描按键,一个用来数码管计数用的.
下载以后程序可以运行(下载线还在下载端口上,没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();
}
}
建议你下载我电子书的前2篇学习一下,编程的思想方法要更新. 是不是你出的那本书的前两章呀,那本书我买了 用马老师新出的书,里面有个状态机的键盘设计,用状态机的思想可以只用一个定时器实现很多功能:比如键盘单按键/按键连_发,数码管的显示,定时,PWM等等,当然功能都是在主程序里实现的,呵呵,提个方法,具体的自己琢磨一下... 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,但建议你仔细读我的书,并体会里面的东西,会更上一层楼的. 马老师,非常感谢你给我的指导,这几天一直在看你的书,我想问一下,就是想学一下LCD的用法,是否可以先学你书中的那个LCD呀,那以后用到别的LCD是否会用,还是要看LCD的说明书呀
对了TIMSK=0X02; 我是想禁止定时器2产生中断,不知这样合不合适呀,我是想计数减到0时就停止,不让它继续下去了,不知还有没有好的方法呀,再次感谢!! 对了,还有一点,如果我只使用一个定时器的话,那我在数码管计数到0时,想不让计数了,那怎么办呀,如果把中断屏蔽掉的话,扫描程序不也就退出了,谢谢!! STEP BY STEP 是最好的学习方法和态度. 不错,保留
页:
[1]