找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8834|回复: 0
收起左侧

单片机定时器毫秒级精确定时程序与分析

[复制链接]
ID:423556 发表于 2018-11-29 11:34 | 显示全部楼层 |阅读模式
一,T0使用8位自动重装模式(最大256us)
定时周期计算:
定时器计数器自加1时间:1us=机器周期(1/12M=1/12us) 乘 12(AUXR&=0x7f; //B7=0,T0设置为12倍速,其它设置不变)
当计数器(设置为8位时)计数到255再加1溢出(TMOD&=0xf0; //xxxx 0000,T0设置置零    TMOD|=0x02; //xxxx 0010,T0设置为8位自动重装)
溢出时间=256-初装值(TH0=0x38; //自动初装值)(从初装值开始计数,到256溢出完成一次。)


1.自动重装方式
程序如下:
/*


P1.3为PWM输出端

5.SID 串行数据输入端 接单片机P3.7
6.SCLK 串行时钟输入端 接单片机P3.6


*/


#include<stc12c5a60s2.h>//头文件

//全局变量声明
sbit lcd_sid=P3^7; //定义12864数据端口
sbit lcd_sclk=P3^6; //定义12864时钟脉冲端口
sbit pwm=P1^3;//

unsigned char t0_1ms; //T0计数器

//子函数声明
void init(); //初始化子函数
void lcd(); //lcd子函数

//主函数开始/////////////////////////////////////////////////////////////////////
void main()
{
        init(); //初始化
        while(1) //循环下面的程序
        {
                if(t0_1ms==5) //如果计数5次,5*0.2ms=1ms,执行下面的程序
                {
                        t0_1ms=0; //计数器复位
                        lcd(); //lcd显示
                }
        }
}

//主函数结束/////////////////////////////////////////////////////////////////////

//子函数程序
void t0_200us()interrupt 1 //T0中断函数
{
        t0_1ms++; //每0.2ms加一次
        pwm=~pwm; //
}

void init() //初始化子函数
{
        //T0初始化
        AUXR&=0x7f; //B7=0,T0设置为12倍速,其它设置不变
        TMOD&=0xf0; //xxxx 0000,T0设置置零
        TMOD|=0x02; //xxxx 0010,T0设置为8位自动重装
        TL0=0x38; //初装值
        TH0=0x38; //自动初装值
        TR0=1; //T0运行
        EA=1; //
        ET0=1; //
}

void lcd(); //lcd子函数

IMG_20181129_104323R.jpg IMG_20181129_101720R.jpg


从示波器可以看出时间的时间比计算的时间要多。

把与定时器不相关的程序全部删除:

#include<stc12c5a60s2.h>//头文件

//全局变量声明
sbit lcd_sid=P3^7; //定义12864数据端口
sbit lcd_sclk=P3^6; //定义12864时钟脉冲端口
sbit pwm=P1^3;//

unsigned char t0_1ms; //T0计数器

//子函数声明
void init(); //初始化子函数

//主函数开始/////////////////////////////////////////////////////////////////////
void main()
{
        init(); //初始化
        while(1) //循环下面的程序
        {
                if(t0_1ms==5) //如果计数5次,5*0.2ms=1ms,执行下面的程序
                {
                        t0_1ms=0; //计数器复位
                }
        }
}

//主函数结束/////////////////////////////////////////////////////////////////////

//子函数程序
void t0_200us()interrupt 1 //T0中断函数
{
        t0_1ms++; //每0.2ms加一次
        pwm=~pwm; //
}

void init() //初始化子函数
{
        //T0初始化
        AUXR&=0x7f; //B7=0,T0设置为12倍速,其它设置不变
        TMOD&=0xf0; //xxxx 0000,T0设置置零
        TMOD|=0x02; //xxxx 0010,T0设置为8位自动重装
        TL0=0x38; //初装值
        TH0=0x38; //自动初装值
        TR0=1; //T0运行
        EA=1; //
        ET0=1; //
}





IMG_20181129_103814R.jpg

200us输出变换一次。符合计算。
由此可知,中断发生是由于需要保护原来正在运行的程序,处理中断前需要先保护现场,这样就增加了运行时间,每毫秒需要5次中断,当需要运行的程序越多时,中断的时间越不稳定。

下面尝试增加中断时间,减少中断处理时间,看看程序对中断时间的影响。


IMG_20181129_103814R.jpg
IMG_20181129_104249R.jpg
IMG_20181129_105844R.jpg
IMG_20181129_105946R.jpg
IMG_20181129_105950R.jpg
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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