怎样用C8051F单片机的定时器做准确的5MS的延时呢
答案:2 悬赏:50
解决时间 2021-04-22 12:54
- 提问者网友:她是我的お女人
- 2021-04-22 07:44
外部晶振11.059M 系统时钟不分频
最佳答案
- 二级知识专家网友:哥在撩妹请勿打扰
- 2021-04-22 08:06
你要多准确?
对应系统时间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
//-----------------------------------------------------------------------------
// 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; // 清除溢出标志
}
}
全部回答
- 1楼网友:气场征服一切
- 2021-04-22 08:12
你要多准确? 对应系统时间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; // 清除溢出标志 } }
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯