程序就像玩积木,每编写一段代码编译通过了再写下一段代码,方便找bug。
杭州-小冯:
为什么出现这样的错啊?我检查了,没发现有错啊.鸿哥第5节内容。以下是我改写有bug的代码:
#include<reg52.h>
/* 注释一:
* 如何知道1秒钟需要多少个定时中断?
* 这个需要编写一段小程序测试,得到测试的结果后再按比例修正。
* 步骤:
* 第一步:在程序代码上先写入1秒钟大概需要200个定时中断。
* 第二步:基于以上1秒钟的基准,编写一个60秒的简单测试程序(如果编写超过
* 60秒的时间,这个精度还会更高)。比如,编写一个用蜂鸣器的声音来识别计时的
* 起始和终止的测试程序。
* 第三步:把程序烧录进单片机后,上电开始测试,手上同步打开手机里的秒表。
* 如果单片机仅仅跑了27秒。
* 第四步:那么最终得出1秒钟需要的定时中断次数是:const_time_1s=(200*60)/27=444
*/
#define const_time_05s 222 //0.5秒钟的时间需要的定时中断次数
#define const_time_1s 444 //1秒钟的时间需要的定时中断次数
#define const_time_3s 1332//3秒钟的时间需要的定时中断次数
#define const_time_6s 2664//6秒钟的时间需要的定时中断次数
#define const_voice_short 40 //蜂鸣器短叫的持续时间
#define const_voice_long200//蜂鸣器长叫的持续时间
void initial_myself();
void initial_peripheral();
void delay_long(unsigned int uidelaylong);
void led_flicker();
void alarm_run();
void T0_time();
sbit beep_dr=P2^7;
sbit led_dr=P3^5;
unsigned char ucledstep=0;
unsigned int uitimeledcnt=0;
unsigned char ucalarmstep=0;
unsigned int uitimealarmcnt=0;
unsigned int uitimevoicecnt=0;
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
led_flicker();
alarm_run();
}
}
void led_flicker()
{
switch(ucledstep)
{
case 0:
{
if(uitimeledcnt>=const_time_05s)
{
uitimeledcnt=0;
led_dr=1;
ucledstep=1;
}
break;
case 1:
{
if(uitimeledcnt>=const_time_05s)
{
uitimeledcnt=0;
led_dr=0;
ucledstep=0;
}
break;
}
}
void alarm_run()
{
switch(ucalarmstep)
{
case 0:
if(uitimealarmcnt>=const_time_3s)
{
uitimealarmcnt=0;
/* 注释二:
* 只要变量uiVoiceCnt不为0,蜂鸣器就会在定时中断函数里启动鸣叫,并且自减uiVoiceCnt
* 直到uiVoiceCnt为0时才停止鸣叫。因此控制uiVoiceCnt变量的大小就是控制声音的长短。
*/
uitimevoicecnt=const_voice_short;
ucalarmstep=1;
}
break;
case 1:
if(uitimealarmcnt>=const_time_6s)
{
uitimealarmcnt=0;
uitimevoicecnt=const_voice_long;
ucalarmstep=2;
}
break;
}
}
void T0_time() interrupt 1
{
TF0=0;
TR0=0;
if(uitimeledcnt<0xffff)
{
uitimeledcnt++;
}
if(uitimealarmcnt<0xffff)
{
uitimealarmcnt++;
}
/* 注释三:
* 为什么不把驱动蜂鸣器这段代码放到main函数的循环里去?
* 因为放在定时中断里,能保证蜂鸣器的声音长度是一致的,
* 如果放在main循环里,声音的长度就有可能受到某些必须
* 一气呵成的任务干扰,得不到及时响应,影响声音长度的一致性。
*/
if(uitimevoicecnt!=0)
{
uitimevoicecnt--;
beep_dr=0;
}
else
{
;
beep_dr=1;
}
TH0=OXf8;
TL0=0X2f;
TR0=1;
}
void delay_long(unsigned int uidelaylong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uidelaylong;i++)
{
for(j=0;j<500;j++)
{
;
}
}
}
void initial myself()
{
beer_dr=1;
led_dr=0
TMOD=0X01;
TH0=0xf8;
TL0=0x2f;
}
void initial peripheral()
{
EA=1;
ET0=1;
TR0=1;
}
鸿哥-深圳:
我帮你找了7处错误。以后类似的问题,我希望你自己解决,你不要一下子复制我的代码,一概一点一点来调试。程序就像玩积木,是一点点往上加的,每加一段程序,就要确保通过了,然后再添加下一段代码。以后这类问题,我抽不出时间帮你的。以后一点代码一点代码网上加。不要一气呵成,这样可以及时发现bug,不然bug累加多了不好找问题。以下是我帮你修改后并且加了注释错误标注的代码:
#include<reg52.h>
/* 注释一:
* 如何知道1秒钟需要多少个定时中断?
* 这个需要编写一段小程序测试,得到测试的结果后再按比例修正。
* 步骤:
* 第一步:在程序代码上先写入1秒钟大概需要200个定时中断。
* 第二步:基于以上1秒钟的基准,编写一个60秒的简单测试程序(如果编写超过
* 60秒的时间,这个精度还会更高)。比如,编写一个用蜂鸣器的声音来识别计时的
* 起始和终止的测试程序。
* 第三步:把程序烧录进单片机后,上电开始测试,手上同步打开手机里的秒表。
* 如果单片机仅仅跑了27秒。
* 第四步:那么最终得出1秒钟需要的定时中断次数是:const_time_1s=(200*60)/27=444
*/
#define const_time_05s 222 //0.5秒钟的时间需要的定时中断次数
#define const_time_1s 444 //1秒钟的时间需要的定时中断次数
#define const_time_3s 1332//3秒钟的时间需要的定时中断次数
#define const_time_6s 2664//6秒钟的时间需要的定时中断次数
#define const_voice_short 40 //蜂鸣器短叫的持续时间
#define const_voice_long200//蜂鸣器长叫的持续时间
void initial_myself();
void initial_peripheral();
void delay_long(unsigned int uidelaylong);
void led_flicker();
void alarm_run();
void T0_time();
sbit beep_dr=P2^7;
sbit led_dr=P3^5;
unsigned char ucledstep=0;
unsigned int uitimeledcnt=0;
unsigned char ucalarmstep=0;
unsigned int uitimealarmcnt=0;
unsigned int uitimevoicecnt=0;
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
led_flicker();
alarm_run();
}
}
void led_flicker()
{
switch(ucledstep)
{
case 0:
// { 第1处错误,把这个大括号删掉。
if(uitimeledcnt>=const_time_05s)
{
uitimeledcnt=0;
led_dr=1;
ucledstep=1;
}
break;
case 1:
// { 第2处错误,把这个大括号删掉。
if(uitimeledcnt>=const_time_05s)
{
uitimeledcnt=0;
led_dr=0;
ucledstep=0;
}
break;
}
}
void alarm_run()
{
switch(ucalarmstep)
{
case 0:
if(uitimealarmcnt>=const_time_3s)
{
uitimealarmcnt=0;
/* 注释二:
* 只要变量uiVoiceCnt不为0,蜂鸣器就会在定时中断函数里启动鸣叫,并且自减uiVoiceCnt
* 直到uiVoiceCnt为0时才停止鸣叫。因此控制uiVoiceCnt变量的大小就是控制声音的长短。
*/
uitimevoicecnt=const_voice_short;
ucalarmstep=1;
}
break;
case 1:
if(uitimealarmcnt>=const_time_6s)
{
uitimealarmcnt=0;
uitimevoicecnt=const_voice_long;
ucalarmstep=2;
}
break;
}
}
void T0_time() interrupt 1
{
TF0=0;
TR0=0;
if(uitimeledcnt<0xffff)
{
uitimeledcnt++;
}
if(uitimealarmcnt<0xffff)
{
uitimealarmcnt++;
}
/* 注释三:
* 为什么不把驱动蜂鸣器这段代码放到main函数的循环里去?
* 因为放在定时中断里,能保证蜂鸣器的声音长度是一致的,
* 如果放在main循环里,声音的长度就有可能受到某些必须
* 一气呵成的任务干扰,得不到及时响应,影响声音长度的一致性。
*/
if(uitimevoicecnt!=0)
{
uitimevoicecnt--;
beep_dr=0;
}
else
{
;
beep_dr=1;
}
//TH0=OXf8; //第3处错误,这个0x是数字0,而不是字母O。
TH0=0Xf8;
TL0=0X2f;
TR0=1;
}
void delay_long(unsigned int uidelaylong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uidelaylong;i++)
{
for(j=0;j<500;j++)
{
;
}
}
}
// void initial myself()第4处错误,这两个单词之间必须有下划线
void initial_myself()
{
//beer_dr=1; 第5处错误,拼写错误是beep_dr
beep_dr=1;
// led_dr=0 第6处错误,漏了分号;
led_dr=0;
TMOD=0X01;
TH0=0xf8;
TL0=0x2f;
}
//void initial peripheral() 第7处错误,这两个单词之间必须有下划线
void initial_peripheral()
{
EA=1;
ET0=1;
TR0=1;
}
关于鸿哥提到的一段段调试,是指写一个函数就调试一次吗?那么如何方便的在keil里面调试了? 本帖最后由 jianhong_wu 于 2014-11-16 12:53 编辑
海~~ 发表于 2014-11-16 09:29
关于鸿哥提到的一段段调试,是指写一个函数就调试一次吗?那么如何方便的在keil里面调试了?
不一定是一个函数一个函数来写,反正是一点点往上加。比如,你做一个项目,有显示,有按键,有数据采集,那么你可以先调通按键的,再加显示的,调通了按键与显示之后,再做数据采集的,这样就一步步把项目做出来了。我是直接把程序下载到单片机电路板上看现象的,这个没有什么技巧,做多了就自然领悟了。 恩,明白了,基本上是根据一个个相关功能模块调试的。
页:
[1]