找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2683|回复: 7
打印 上一主题 下一主题
收起左侧

这个单片机函数功能是16位自动重载模式中给定时器设定初值的,赋值给8位寄存器TL0

[复制链接]
跳转到指定楼层
楼主
废话不多说,先上代码

/************************* 定时器设定计数(16位) *************************
        
                变量名                |                        取值范围                |                        变量含义
                NUM                        |                        0 ~ 4                        |                        定时器编号
                COUNT                |                0 ~ 65535                |                        定时器计数值
        
*/


void _TIMER_COUNT_16_(uint8_t NUM, uint16_t COUNT){
        
        uint16_t Temp;
        Temp = 65536 - COUNT;
        
        switch (NUM){
                case 0 :
                        TL0 = Temp;
                        TH0 = _crol_(Temp,8);
                        break;
                case 1 :
                        TH1 = Temp;
                        TH1 = _crol_(Temp,8);
                        break;
                case 2 :
                        T2L = Temp;
                        T2H = _crol_(Temp,8);
                        break;
                case 3 :
                        T3L = Temp;
                        T3H = _crol_(Temp,8);
                        break;
                case 4 :
                        T4L = Temp;
                        T4H = _crol_(Temp,8);
                        break;
        }
        
}


我本来想写一个库函数,做一个长期的积累,结果就出怪事了。


这段代码里的两个变量在上面注释里有,编译之后单步运行,发现变量监视器里发生“灵异事件”。


这个函数功能是16位自动重载模式中给定时器设定初值的。假定 NUM = 0(给定时器0设定初值)。Temp是一个16位无符号变量,用来存放定时器初始值(65536 - 计数值COUNT)。赋值给8位寄存器TL0,直接将低8位送进去,没有任何问题。然后Temp右移8位,幅值给TH0,但这中间发生了几个奇怪的问题。


1、测试,Temp(定时器初值) = 65536 - COUNT(计数值)。但这条语句执行完之后,COUNT的值也发生了变化,虽说运算结果是正确的,而且COUNT是局部变量不影响主函数,但哪有把操作数改变的道理?万一我下面再需要用到COUNT呢?那不全乱套了?




2、一开始我用的是 “>>” 右移运算符,但无论怎么改都没有效果,Temp变量并没有右移8位。后来改用 intrins.h 的库函数 _cror_(),不用不要紧,一用更邪门了。_cror_(Temp,8)操作之后连NUM这个数都改变了,但这可是NUM啊!这是定时器编号啊,函数里没有修改,也根本不需要修改,怎么莫名其妙地就被改了呢?而且说好的移位呢?也没实现啊……




希望前辈答疑解惑,多谢啦!



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:47286 发表于 2020-9-25 20:13 | 只看该作者
用宏定义写不好么 你这么写是挺方便 但编译后文件大 运行速度也有影响 毕竟要走一个switch

#define FOC 1 //1=11.0592 2=22.1148

#if FOC==1 //如果 频率设置=1 编译以下内容
THV=0x??; //高8位
THL=0x??; //低8位
#elif FOC==2 //如果 频率设置=2 编译以下内容
THV=0x??; //高8位
THL=0x??; //低8位
#endif 结束编译

TL0 = THV;
TH0 = TLV;

这样写编译的时候实际上只编译实际值 没有额外运算 而且 也可以实现灵活配置
回复

使用道具 举报

板凳
ID:224104 发表于 2020-9-26 15:33 | 只看该作者
dzbj 发表于 2020-9-25 20:13
用宏定义写不好么 你这么写是挺方便 但编译后文件大 运行速度也有影响 毕竟要走一个switch

#define FOC  ...

只是单纯想写个库,而且初始化只有一次,不是循环调用,应该不影响运行效率
回复

使用道具 举报

地板
ID:311846 发表于 2020-9-27 16:46 | 只看该作者
本帖最后由 权威人物 于 2020-9-27 16:51 编辑

亲,移位操作这边建议加括号哦!对于一些符号类型不匹配的也建议手动加强制转换,对于_cror_建议仔细看看的函数说明,以后对函数有异议麻烦请自行找度娘,一般不会重现偏差。
回复

使用道具 举报

5#
ID:311846 发表于 2020-9-27 16:49 | 只看该作者
对于NUM验证直接,固定NUM的值,在其他所有地方的NUM使用屏蔽掉
回复

使用道具 举报

6#
ID:224104 发表于 2020-9-28 10:45 | 只看该作者
权威人物 发表于 2020-9-27 16:46
亲,移位操作这边建议加括号哦!对于一些符号类型不匹配的也建议手动加强制转换,对于_cror_建议仔细看看的 ...

刚刚查了一下才知道,_cror_ 是字节变量右移,谢谢啦
回复

使用道具 举报

7#
ID:224104 发表于 2020-9-28 10:48 | 只看该作者
权威人物 发表于 2020-9-27 16:49
对于NUM验证直接,固定NUM的值,在其他所有地方的NUM使用屏蔽掉

请问具体代码怎么实现呢?
回复

使用道具 举报

8#
ID:224104 发表于 2020-9-28 11:37 | 只看该作者
问题已经完全解决了,经测试是编译器的锅。

选择8(默认)就会出现各种各样莫名其妙的问题。改成3之后所有的错误都没了。

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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