打印

各位大侠,请教一个单片机定时器的C程序

[复制链接]
2017|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
acone|  楼主 | 2013-1-23 21:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天是第一次写单片机的C程序,单片机开发板是STC12C5A60S2的,参照STC的datasheet,编写了一个定时器的参数设置通用函数,全部源代码如下,烧录到单片机以后,两个定时器都能工作,两个定时器之间的比例也正常,但是每个定时器的时长好像比预期的都长了10倍左右,不知道什么原因,望各位大侠能给予指导和帮助。
#include "reg51.h"

unsigned   uCount0 = 100, uCount1 = 200;
sbit        P1_0 = P1^0;
sbit        P1_3 = P1^3;
unsigned char ucTimer0InitHigh = 0, ucTimer0InitLow = 0;
unsigned char ucTimer1InitHigh = 0, ucTimer1InitLow = 0;

float EnableAndSetTimer( unsigned char ucWhichTimer, float fTimer_us, float fClockFreq_MHz,
                                                 unsigned char * pucTimerInitHigh, unsigned char * pucTimerInitLow )
{
        float fTimerNum = 0, fRealTimer_us = 0;
        unsigned int uTimerNum = 0;
        unsigned char * pucAUXR = 0x8e; //address of auxiliary register
        unsigned char bIs1TMode = fTimer_us < 65536.0/fClockFreq_MHz ? 1 : 0;
        if( bIs1TMode )       
        {
                if( 0 == ucWhichTimer ) * pucAUXR |= 0x80;
                else * pucAUXR |= 0x40;
        }
        else
        {
                if( 0 == ucWhichTimer ) * pucAUXR &= 0x7f;
                else * pucAUXR &= 0xbf;
        }
        fTimerNum = bIs1TMode? fTimer_us*fClockFreq_MHz : fTimer_us*fClockFreq_MHz/12;
        uTimerNum = fTimerNum >= 65536.0? 1 : 65536l-(unsigned)fTimerNum;
        fRealTimer_us = fTimerNum >= 65536.0? 65536.0*12/fClockFreq_MHz : fTimer_us;
        if( pucTimerInitLow ) * pucTimerInitLow = uTimerNum;
        if( pucTimerInitHigh ) * pucTimerInitHigh = uTimerNum >> 8;
        if( 0 == ucWhichTimer )
        {
                TMOD |= 0x01;        //set timer0 as mode1 (16-bit)
                TL0        = uTimerNum;        //initial timer0 low byte
                TH0        = uTimerNum >> 8;        //initial timer0 high byte
                TR0        = 1;        //timer0 start running
                ET0        = 1;        //enable timer0 interrupt
        }
        else
        {
                TMOD |= 0x10;        //set timer1 as mode1 (16-bit)
                TL1        = uTimerNum;        //initial timer1 low byte
                TH1        = uTimerNum >> 8;        //initial timer1 high byte
                TR1        = 1;        //timer1 start running
                ET1        = 1;        //enable timer1 interrupt
        }
        EA        = 1;        //open global interrupt switch
        return fRealTimer_us;       
}

void OnTimer0() interrupt 1 using 1
{
        TL0 = ucTimer0InitLow;        //reload timer0 low byte
        TH0 = ucTimer0InitHigh;        //reload timer0 high byte
        uCount0 --;
        if( 0 == uCount0 )        //1ms * 100 -> 0.1s
        {
                uCount0 = 100;        //reset counter
                P1_0 = ! P1_0;        //work LED flash
        }
}       

void OnTimer1() interrupt 3 using 1
{
        TL1 = ucTimer1InitLow;        //reload timer1 low byte
        TH1 = ucTimer1InitHigh;        //reload timer1 high byte
        uCount1 --;
        if( 0 == uCount1 )
        {
                uCount1 = 200;        //reset counter
                P1_3 = ! P1_3;        //work LED flash
        }
}       

void main()
{
        EnableAndSetTimer( 0, 1000, 12.0, & ucTimer0InitHigh, & ucTimer0InitLow );
        EnableAndSetTimer( 1, 200, 12.0, & ucTimer1InitHigh, & ucTimer1InitLow );
        while (1);        //loop
}

相关帖子

沙发
ayb_ice| | 2013-1-24 08:20 | 只看该作者
本帖最后由 ayb_ice 于 2013-1-24 08:23 编辑

这种问题,仔细看手册就搞定了

另外注意51的定时器初值是目标值的负值

比如想定时1000个周期,初始其实是-1000,
即65536-1000

TH0 = -1000/256, TL0 = -1000%256

使用特权

评论回复
板凳
NE5532| | 2013-1-24 08:30 | 只看该作者
如果两个的比例是对的,那就看主时钟设置问题了,或者自己算法有没有问题。

使用特权

评论回复
地板
mzq2wym| | 2013-1-24 09:07 | 只看该作者
这个单片机比普通的要快一些用STC89C52时间就对了

使用特权

评论回复
5
acone|  楼主 | 2013-1-24 11:00 | 只看该作者
问题找到了,是特殊功能寄存器AUXR的问题,如果在函数外声明成
sfr pucAUXR = 0x8e;
然后在函数中赋值
pucAUXR |= 0x80;
就没有问题。
如果像我上面的那样在函数内声明
unsigned char * pucAUXR = 0x8e;
赋值时写成:* pucAUXR |= 0x80;
就有问题。为什么呀?我不想在函数外声明,好像从窗户钻进函数内一样,我该怎样在函数内声明?

使用特权

评论回复
6
ayb_ice| | 2013-1-24 11:13 | 只看该作者
acone 发表于 2013-1-24 11:00
问题找到了,是特殊功能寄存器AUXR的问题,如果在函数外声明成
sfr pucAUXR = 0x8e;
然后在函数中赋值

SFR只能直接寻址,不能通过指针访问的

使用特权

评论回复
7
acone|  楼主 | 2013-1-24 12:55 | 只看该作者
谢谢ayb_ice。
有什么变通的办法可在函数内声明?用嵌入汇编行不行?怎么写?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

45

帖子

1

粉丝