中易网

怎样用C8051F单片机的定时器做准确的5MS的延时呢

答案:2  悬赏:50  
解决时间 2021-04-22 12:54
外部晶振11.059M 系统时钟不分频
最佳答案
你要多准确?
对应系统时间T=0.0904uS,5mS=55309.7<65536,可以用定时器0工作在16位定时模式。CKCON=0x04;
TMOD=0x01;
//------------------
void Timer0_Delay (void)interrupt 1 using 1{
TH0=(65536-55310)/256;
TL0=(65536-55310)%256;
}
55309为4999.9336(少664ns),55310为5000.0240(多240ns)。定时器时钟选系统时钟,
或者:
//-----------------------------------------------------------------------------
// Timer0_Poll1.c
//-----------------------------------------------------------------------------
// 此程序是一个使用定时器T0在查询模式的例子实现一个延时计数器精度1ms
//
// 假设在XTAL1和XTAL2之间接22.1184MHz晶体
//
// 系统时钟频率存储在全局常量SYSCLK.
//
// 目标器件: C8051F02x
// 链接工具: KEIL C51 6.03 / KEIL EVAL C51
//
//-----------------------------------------------------------------------------
// 包含文件
//-----------------------------------------------------------------------------
#include // SFR声明
//-----------------------------------------------------------------------------
// C8051FF02x的16位SFR定义
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // 数据指针
sfr16 TMR3RL = 0x92; // 定时器T3重装值
sfr16 TMR3 = 0x94; // 定时齐器T3计数器
sfr16 ADC0 = 0xbe; // ADC0数据
sfr16 ADC0GT = 0xc4; // ADC0大于窗口
sfr16 ADC0LT = 0xc6; // ADC0小于窗口
sfr16 RCAP2 = 0xca; // 定时器T2捕捉/重装
sfr16 T2 = 0xcc; // 定时器T2
sfr16 RCAP4 = 0xe4; // 定时器T4 捕捉/重装
sfr16 T4 = 0xf4; // 定时器T4
sfr16 DAC0 = 0xd2; // DAC0数据
sfr16 DAC1 = 0xd5; // DAC1数据
//-----------------------------------------------------------------------------
// 全局常量
//-----------------------------------------------------------------------------
#define SYSCLK 11059200 // 系统时钟频率Hz
sbit LED = P1^6; // LED=’1’ 意为ON
sbit SW1 = P3^7; // SW1=’0’ 意为按下开关
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void Timer0_Delay (int ms);
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
void main (void) {
WDTCN = 0xde; // 禁止看门狗定时器
WDTCN = 0xad;
SYSCLK_Init (); // 初始化振荡器
PORT_Init (); // 初始化数据交叉开关和通用IO口
while (1) {
Timer0_Delay (5); // 延时5ms
LED = ~LED; //改变LED状态
}
}
//-----------------------------------------------------------------------------
// 初始化子程序
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------
//
// 此程序初始化系统时钟使用11.0592MHz晶体作为时钟源
//
void SYSCLK_Init (void)
{
int i; // 延时计数器
OSCXCN = 0x67; // 启动外部振荡器晶振
for (i=0; i < 256; i++) ; // 等待振荡器启动
while (!(OSCXCN & 0x80)) ; // 等待振荡器稳定
OSCICN = 0x88; // 选择内部振荡器为时钟源并使能丢失时钟检测器
}
//-----------------------------------------------------------------------------
// IO口初始化
//-----------------------------------------------------------------------------
//
// 配置数据交叉开关和通用IO口
//
void PORT_Init (void)
{
XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x40; // 使能数据交叉开关和弱上拉
P1MDOUT |= 0x40; // 使能P1.6(LED)为推挽输出
}
//-----------------------------------------------------------------------------
// Timer0_Delay
//-----------------------------------------------------------------------------
//
// 配置定时器T0延时.
//
void Timer0_Delay (int ms)
{
int i; // 毫秒计数器
TCON &= ~0x30; // 停止定时器T0并清除溢出标志
TMOD &= ~0x0f; // 配置定时器T0为16位模式
TMOD |= 0x01;
CKCON |= 0x08; // 定时器T0计数系统时钟
for (i = 0; i < ms; i++) { // 数毫秒
TR0 = 0; // 停定时器T0
TH0 = (-SYSCLK/1000) >> 8; // 设置定时器T0 1ms溢出
TL0 = -SYSCLK/1000;
TR0 = 1; // 启动定时器T0
while (TF0 == 0); // 等待溢出
TF0 = 0; // 清除溢出标志
}
}
全部回答
你要多准确?
对应系统时间t=0.0904us,5ms=55309.7<65536,可以用定时器0工作在16位定时模式。ckcon=0x04;
tmod=0x01;
//------------------
void timer0_delay (void)interrupt 1 using 1{
th0=(65536-55310)/256;
tl0=(65536-55310)%256;
}
55309为4999.9336(少664ns),55310为5000.0240(多240ns)。定时器时钟选系统时钟,
或者:
//-----------------------------------------------------------------------------
// timer0_poll1.c
//-----------------------------------------------------------------------------
// 此程序是一个使用定时器t0在查询模式的例子实现一个延时计数器精度1ms
//
// 假设在xtal1和xtal2之间接22.1184mhz晶体
//
// 系统时钟频率存储在全局常量sysclk.
//
// 目标器件: c8051f02x
// 链接工具: keil c51 6.03 / keil eval c51
//
//-----------------------------------------------------------------------------
// 包含文件
//-----------------------------------------------------------------------------
#include <c8051f020.h> // sfr声明
//-----------------------------------------------------------------------------
// c8051ff02x的16位sfr定义
//-----------------------------------------------------------------------------
sfr16 dp = 0x82; // 数据指针
sfr16 tmr3rl = 0x92; // 定时器t3重装值
sfr16 tmr3 = 0x94; // 定时齐器t3计数器
sfr16 adc0 = 0xbe; // adc0数据
sfr16 adc0gt = 0xc4; // adc0大于窗口
sfr16 adc0lt = 0xc6; // adc0小于窗口
sfr16 rcap2 = 0xca; // 定时器t2捕捉/重装
sfr16 t2 = 0xcc; // 定时器t2
sfr16 rcap4 = 0xe4; // 定时器t4 捕捉/重装
sfr16 t4 = 0xf4; // 定时器t4
sfr16 dac0 = 0xd2; // dac0数据
sfr16 dac1 = 0xd5; // dac1数据
//-----------------------------------------------------------------------------
// 全局常量
//-----------------------------------------------------------------------------
#define sysclk 11059200 // 系统时钟频率hz
sbit led = p1^6; // led=’1’ 意为on
sbit sw1 = p3^7; // sw1=’0’ 意为按下开关
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void sysclk_init (void);
void port_init (void);
void timer0_delay (int ms);
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------------------
void main (void) {
wdtcn = 0xde; // 禁止看门狗定时器
wdtcn = 0xad;
sysclk_init (); // 初始化振荡器
port_init (); // 初始化数据交叉开关和通用io口
while (1) {
timer0_delay (5); // 延时5ms
led = ~led; //改变led状态
}
}
//-----------------------------------------------------------------------------
// 初始化子程序
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------
//
// 此程序初始化系统时钟使用11.0592mhz晶体作为时钟源
//
void sysclk_init (void)
{
int i; // 延时计数器
oscxcn = 0x67; // 启动外部振荡器晶振
for (i=0; i < 256; i++) ; // 等待振荡器启动
while (!(oscxcn & 0x80)) ; // 等待振荡器稳定
oscicn = 0x88; // 选择内部振荡器为时钟源并使能丢失时钟检测器
}
//-----------------------------------------------------------------------------
// io口初始化
//-----------------------------------------------------------------------------
//
// 配置数据交叉开关和通用io口
//
void port_init (void)
{
xbr0 = 0x00;
xbr1 = 0x00;
xbr2 = 0x40; // 使能数据交叉开关和弱上拉
p1mdout |= 0x40; // 使能p1.6(led)为推挽输出
}
//-----------------------------------------------------------------------------
// timer0_delay
//-----------------------------------------------------------------------------
//
// 配置定时器t0延时.
//
void timer0_delay (int ms)
{
int i; // 毫秒计数器
tcon &= ~0x30; // 停止定时器t0并清除溢出标志
tmod &= ~0x0f; // 配置定时器t0为16位模式
tmod |= 0x01;
ckcon |= 0x08; // 定时器t0计数系统时钟
for (i = 0; i < ms; i++) { // 数毫秒
tr0 = 0; // 停定时器t0
th0 = (-sysclk/1000) >> 8; // 设置定时器t0 1ms溢出
tl0 = -sysclk/1000;
tr0 = 1; // 启动定时器t0
while (tf0 == 0); // 等待溢出
tf0 = 0; // 清除溢出标志
}
}
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
英语表示:至少10个国家国籍的名称
银行职员建议我买定投保险,每年3000元,存15
水货现在多少钱?
win7上的star-nx600不打印
“同心圆"打三个字,必须是数学术语!
十七岁女生乳房大而垂,算乳房下垂吗?
电热油汀取暖器在哪里加油?加哪种油?
中国人均素质排第世界第几位?
大便出血怎么办
内蒙古大学新生是否可以在入学时转专业
As often as you like life什么意思?
从广州市到台山斗山市怎样去
QQ农场打不开‘初始化错误,点击重试’?
为什么要过情人节?
为什么我下完真三国无双5是记事本啊?
推荐资讯
回迁房是什么意思啊
长安悦翔怎么样?好开吗 ?
微友圈发广告挣钱收加盟费合法吗
鑫都商务宾馆在什么地方啊,我要过去处理事情
信用卡我今天刷了是下个月的今天还吗?
胃疼,应该在饮食和休息上注意些什么呢?
苹果手机怎么取消微信朋友圈不看他(她)消息
苹果手机打字跑到格子上面怎么办?
这个选啥子?详细说明
有什么工作能经常出差的
蔡甸区侏儒街胜洪中心卫生室地址在什么地方,
早教公用袜套怎么做才不会丢?
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?