OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6735|回复: 10

不到50行代码的51单片机的定时器0溢出速度有问题,大神求解,谢了啊!

[复制链接]

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
发表于 2013-5-4 20:52:54 | 显示全部楼层 |阅读模式

//晶振是11.0592Mhz 
#include <reg52.h>

#define s8 signed char
#define u8 unsigned char
#define u16  unsigned int


sbit D1 = P0^0;//位定义LED0


u8 tmr0_value = 1000;//定时器0的初值

void init_tmr0(void); 


int main(void)

{
 init_tmr0();//初始化定时器0
 
 while (1);
 
 return 0;
}

void init_tmr0(void)
{
 TMOD = 0x01;//设置tmr0为工作方式1
 EA = 1;//开总中断
 ET0 = 1;//开定时器0中断
 TH1 = (65536 - tmr0_value) / 16;//得到高8位
 TH0 = (65536 - tmr0_value) % 16;//得到低8位
 TR0 = 1;//启动定时器0

 return;
}

//注:定时器溢出后若没重装初值就重新从0开始计数(0—65535)
//计数到65536就溢出!
void tmr0(void) interrupt 1//定时器0中断
{    
    TR0 = 0;//关闭定时器0
 //重新给定时器0赋初值
 TH1 = (65536 - tmr0_value) / 16;
 TH0 = (65536 - tmr0_value) % 16;
   
    D1 = !D1;//D1的闪烁速度和tmr0_value的值不匹配
 
    TR0 = 1;//启动定时器0
 
    return;
}
        现象:人眼可以明显地看见D1的闪烁!
        困惑:大家看红色代码tmr0_value = 1000,说明定时器0是大约1ms中断一次,对吧?
那么即D1的亮灭状态是1ms变化一次,以这个速度人眼肯定不能看到灯的闪烁的,但我的灯的闪烁状态就很明显。
这是为什么呢?大神解释,小弟很痛苦!!!

 

乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165353
金钱
165353
注册时间
2010-12-1
在线时间
2108 小时
发表于 2013-5-4 22:54:45 | 显示全部楼层
//重新给定时器0赋初值
 TH1 = (65536 - tmr0_value) / 16;
 TH0 = (65536 - tmr0_value) % 16;
是不是该改为:
//重新给定时器0赋初值
 TH1 = (65536 - tmr0_value) / 256;
 TH0 = (65536 - tmr0_value) % 256;
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

153

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2013-4-4
在线时间
0 小时
发表于 2013-5-4 22:59:56 | 显示全部楼层
u8 真的可以保存1000吗?
~~~~ 欢迎讨论,拒绝谩骂 ~~~~
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2013-5-5 01:44:58 | 显示全部楼层
问题多多,按照前面两位说的改一下,再仿真看一下吧。我都没装keil 51好多年了。
开中断前最好先清除一下中断标志。
业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-5-5 16:45:57 | 显示全部楼层

谢谢楼上各位的意见,我已更正了错误之处,不过还是有个很奇怪的问题,希望大家继续帮看看!
//晶振是11.0592Mhz
#include <reg52.h>
#define s8 signed char
#define u8 unsigned char
#define u16  unsigned int


sbit D1 = P0^0;//位定义LED0

u16 tmr0_value = 1000;//定时器0的初值

void init_tmr0(void);


int main(void)
{
 init_tmr0();//初始化定时器0
 
 while (1);
 
 return 0;
}

void init_tmr0(void)
{
 TMOD = 0x01;//设置tmr0为工作方式1
 EA = 1;//开总中断
 ET0 = 1;//开定时器0中断
 TH1 = (65536 - tmr0_value)  >> 8;//得到高8位
 TH0 = (65536 - tmr0_value)  & 0x00ff;//得到低8位
 TR0 = 1;//启动定时器0

 return;
}

//注:定时器溢出后若没重装初值就重新从0开始计数(0—65535)
//计数到65536就溢出!
void tmr0(void) interrupt 1//定时器0中断
{   
    TR0 = 0;//关闭定时器0
 //重新给定时器0赋初值
 TH1 = (65536 - tmr0_value) >> 8;
 TH0 = (65536 - tmr0_value)  & 0x00ff;
   
    D1 = !D1;//D1的闪烁速度和tmr0_value的值不匹配
 
    TR0 = 1;//启动定时器0
 
    return;
}
        现象:tmr0_value 取值为25000时,人眼可以明显地看见D1的闪烁!
        困惑:大家看红色代码tmr0_value = 20000时,人眼是看不到D1闪烁的;当tmr0_value = 30000时,人眼能略见D1闪烁,这当然是符合情理的,但当tmr0_value = 25000时,D1的闪烁变的非常明显,这真是好奇怪呃!

乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2013-5-5 18:21:51 | 显示全部楼层
65536改成65536ul试试看。

其实改成65535ul不是更好?2个字节空间就够了,运算还更快。

定时器中断可以设置成一个1ms或是10ms的tick,然后在主循环中查询tick的值,根据需要就可以得到你需要的频率了。
业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-5-5 18:40:32 | 显示全部楼层
回复【6楼】ofourme:
---------------------------------
   请问 65535ul和65536到底是啥区别呀?真心不懂啊   还看到有人用类似65536u了的。u和ul都是什么意思呢?
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-5-5 18:47:57 | 显示全部楼层
回复【6楼】ofourme:
---------------------------------
哦   明白了数字后面加u表示无符号型吧,ul表示无符号长型吧?但不懂的是u是unsigned char  还是unsigned int呢?还有在stm32里的uchar、uint和51里的uchar、uint的长度一样吗?
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2013-5-5 20:24:40 | 显示全部楼层
u是unsigned int。所以还是用65535u吧。

uchar和uint是自定义的。stm32里int是32位,51里int是16位。char都是8位。
业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-5-5 20:32:12 | 显示全部楼层
回复【9楼】ofourme:
---------------------------------
嗯嗯  好的 是不是以后只要是写程序 遇到正的常数时 都可以在常数后加u或者ul啊?
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

6

主题

153

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2013-4-4
在线时间
0 小时
发表于 2013-5-6 23:40:27 | 显示全部楼层
尽量用大一点的数据类型
没必要这么扣空间的
一般应用
~~~~ 欢迎讨论,拒绝谩骂 ~~~~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 11:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表