标题: 这个单片机函数功能是16位自动重载模式中给定时器设定初值的,赋值给8位寄存器TL0 [打印本页]

作者: guysxpf    时间: 2020-9-25 08:45
标题: 这个单片机函数功能是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啊!这是定时器编号啊,函数里没有修改,也根本不需要修改,怎么莫名其妙地就被改了呢?而且说好的移位呢?也没实现啊……




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




作者: dzbj    时间: 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;

这样写编译的时候实际上只编译实际值 没有额外运算 而且 也可以实现灵活配置
作者: guysxpf    时间: 2020-9-26 15:33
dzbj 发表于 2020-9-25 20:13
用宏定义写不好么 你这么写是挺方便 但编译后文件大 运行速度也有影响 毕竟要走一个switch

#define FOC  ...

只是单纯想写个库,而且初始化只有一次,不是循环调用,应该不影响运行效率
作者: 权威人物    时间: 2020-9-27 16:46
本帖最后由 权威人物 于 2020-9-27 16:51 编辑

亲,移位操作这边建议加括号哦!对于一些符号类型不匹配的也建议手动加强制转换,对于_cror_建议仔细看看的函数说明,以后对函数有异议麻烦请自行找度娘,一般不会重现偏差。
作者: 权威人物    时间: 2020-9-27 16:49
对于NUM验证直接,固定NUM的值,在其他所有地方的NUM使用屏蔽掉
作者: guysxpf    时间: 2020-9-28 10:45
权威人物 发表于 2020-9-27 16:46
亲,移位操作这边建议加括号哦!对于一些符号类型不匹配的也建议手动加强制转换,对于_cror_建议仔细看看的 ...

刚刚查了一下才知道,_cror_ 是字节变量右移,谢谢啦
作者: guysxpf    时间: 2020-9-28 10:48
权威人物 发表于 2020-9-27 16:49
对于NUM验证直接,固定NUM的值,在其他所有地方的NUM使用屏蔽掉

请问具体代码怎么实现呢?
作者: guysxpf    时间: 2020-9-28 11:37
问题已经完全解决了,经测试是编译器的锅。

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





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1