请教:STC32G定时器T2-T4问题
用STC32G的DIP封装芯片,使用STC公司的范例程序测试T0-T4定时器用C251编译下载后发现只有T0.T1能进入中断程序入口,其余T2-T4不能进入中断程序,软件仿真中T2-T4也进入不了,现将STC,公司程序贴上请教是那里问题/*************功能说明 **************
本例程基于STC32G为主控芯片的实验箱进行编写测试。
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
本程序演示5个定时器的使用, 本例程均使用16位自动重装.
定时器0做16位自动重装, 中断频率为1000HZ,中断函数从P6.7取反输出500HZ方波信号.
定时器1做16位自动重装, 中断频率为2000HZ,中断函数从P6.6取反输出1000HZ方波信号.
定时器2做16位自动重装, 中断频率为3000HZ,中断函数从P6.5取反输出1500HZ方波信号.
定时器3做16位自动重装, 中断频率为4000HZ,中断函数从P6.4取反输出2000HZ方波信号.
定时器4做16位自动重装, 中断频率为5000HZ,中断函数从P6.3取反输出2500HZ方波信号.
下载时, 选择时钟 24MHZ (用户可自行修改频率).
******************************************/
#include "STC32G.h"
#include "stdio.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#define MAIN_Fosc 24000000UL
//==========================================================================
#define Timer0_Reload (MAIN_Fosc / 1000) //Timer 0 中断频率, 1000次/秒
#define Timer1_Reload (MAIN_Fosc / 2000) //Timer 1 中断频率, 2000次/秒
#define Timer2_Reload (MAIN_Fosc / 3000) //Timer 2 中断频率, 3000次/秒
#define Timer3_Reload (MAIN_Fosc / 4000) //Timer 3 中断频率, 4000次/秒
#define Timer4_Reload (MAIN_Fosc / 5000) //Timer 4 中断频率, 5000次/秒
void Timer0_init(void);
void Timer1_init(void);
void Timer2_init(void);
void Timer3_init(void);
void Timer4_init(void);
/******************** 主函数 **************************/
void main(void)
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
Timer0_init();
Timer1_init();
Timer2_init();
Timer3_init();
Timer4_init();
EA = 1; //打开总中断
while (1);
}
//========================================================================
// 函数: void Timer0_init(void)
// 描述: timer0初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer0_init(void)
{
TR0 = 0; //停止计数
#if (Timer0_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer0设置的中断过快!"
#elif ((Timer0_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
ET0 = 1; //允许中断
//PT0 = 1; //高优先级中断
TMOD &= ~0x03;
TMOD |= 0;//工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
TMOD &= ~0x04;//定时
INTCLKO &= ~0x01;//不输出时钟
#if (Timer0_Reload < 65536UL)
AUXR |=0x80;//1T mode
TH0 = (u8)((65536UL - Timer0_Reload) / 256);
TL0 = (u8)((65536UL - Timer0_Reload) % 256);
#else
AUXR &= ~0x80;//12T mode
TH0 = (u8)((65536UL - Timer0_Reload/12) / 256);
TL0 = (u8)((65536UL - Timer0_Reload/12) % 256);
#endif
TR0 = 1; //开始运行
#else
#error "Timer0设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void Timer1_init(void)
// 描述: timer1初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer1_init(void)
{
TR1 = 0; //停止计数
#if (Timer1_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer1设置的中断过快!"
#elif ((Timer1_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
ET1 = 1; //允许中断
//PT1 = 1; //高优先级中断
TMOD &= ~0x30;
TMOD |= (0 << 4); //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
//TMOD |=0x40;//对外计数或分频
TMOD &= ~0x40;//定时
//INTCLKO |=0x02;//输出时钟
INTCLKO &= ~0x02;//不输出时钟
#if (Timer1_Reload < 65536UL)
AUXR |=0x40;//1T mode
TH1 = (u8)((65536UL - Timer1_Reload) / 256);
TL1 = (u8)((65536UL - Timer1_Reload) % 256);
#else
AUXR &= ~0x40;//12T mode
TH1 = (u8)((65536UL - Timer1_Reload/12) / 256);
TL1 = (u8)((65536UL - Timer1_Reload/12) % 256);
#endif
TR1 = 1; //开始运行
#else
#error "Timer1设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void Timer2_init(void)
// 描述: timer2初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer2_init(void)
{
AUXR &= ~0x1c; //停止计数, 定时模式, 12T模式
#if (Timer2_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer2设置的中断过快!"
#elif ((Timer2_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
IE2 |= ET2; //允许中断
//INTCLKO |=0x04;//输出时钟
INTCLKO &= ~0x04;//不输出时钟
#if (Timer2_Reload < 65536UL)
AUXR |=(1<<2); //1T mode
T2H = (u8)((65536UL - Timer2_Reload) / 256);
T2L = (u8)((65536UL - Timer2_Reload) % 256);
#else
T2H = (u8)((65536UL - Timer2_Reload/12) / 256);
T2L = (u8)((65536UL - Timer2_Reload/12) % 256);
#endif
AUXR |=(1<<4); //开始运行
#else
#error "Timer2设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void Timer3_init(void)
// 描述: timer3初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer3_init(void)
{
T4T3M &= ~0x0f; //停止计数, 定时模式, 12T模式, 不输出时钟
#if (Timer3_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer3设置的中断过快!"
#elif ((Timer3_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
IE2 |= ET3; //允许中断
//T4T3M |=0x01; //输出时钟
T4T3M &= ~0x01; //不输出时钟
#if (Timer3_Reload < 65536UL)
T4T3M |=(1<<1); //1T mode
T3H = (u8)((65536UL - Timer3_Reload) / 256);
T3L = (u8)((65536UL - Timer3_Reload) % 256);
#else
T3H = (u8)((65536UL - Timer3_Reload/12) / 256);
T3L = (u8)((65536UL - Timer3_Reload/12) % 256);
#endif
T4T3M |=(1<<3); //开始运行
#else
#error "Timer3设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void Timer4_init(void)
// 描述: timer4初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer4_init(void)
{
T4T3M &= ~0xf0; //停止计数, 定时模式, 12T模式, 不输出时钟
#if (Timer4_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer4设置的中断过快!"
#elif ((Timer4_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
IE2 |= ET4; //允许中断
//T4T3M |=0x10; //输出时钟
T4T3M &= ~0x10; //不输出时钟
#if (Timer4_Reload < 65536UL)
T4T3M |=(1<<5); //1T mode
T4H = (u8)((65536UL - Timer4_Reload) / 256);
T4L = (u8)((65536UL - Timer4_Reload) % 256);
#else
T4H = (u8)((65536UL - Timer4_Reload/12) / 256);
T4L = (u8)((65536UL - Timer4_Reload/12) % 256);
#endif
T4T3M |=(1<<7); //开始运行
#else
#error "Timer4设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer0_int (void) interrupt 1
{
P17 = ~P17;
}
//========================================================================
// 函数: void timer1_int (void) interrupt TIMER1_VECTOR
// 描述:timer1中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer1_int (void) interrupt 3
{
P16 = ~P16;
}
//========================================================================
// 函数: void timer2_int (void) interrupt TIMER2_VECTOR
// 描述:timer2中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer2_int (void) interrupt 12
{
P15 = !P15;
}
//========================================================================
// 函数: void timer3_int (void) interrupt TIMER3_VECTOR
// 描述:timer3中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer3_int(void) interrupt 19
{
P13 = ~P13;
}
//========================================================================
// 函数: void timer4_int (void) interrupt TIMER4_VECTOR
// 描述:timer4中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer4_int(void) interrupt 20
{
P14 = ~P14;
}
用C251编译原封不动的STC公司例程<<02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序>>用软件仿真T2-T4定时器也不能进入中断入口,是编译器问题? 程序没问题,注意头文件需要使用实验箱例程包里面“COMM”文件夹下面的头文件,不要使用其它地方的头文件。 我是直接在STC32G实验箱演示程序文件夹内的<<02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序>编译的 完全没问题
/************* 功能说明 **************
本程序演示5个定时器的使用, 设置时, 可以指定定时时间(us)或系统时钟数.
当设置不当, 将会返回错误(数值过大).
====================================================
定时器0配置为16位自动重装, 20000HZ中断率.
允许高速时钟输出时从P3.5输出10KHZ时钟信号.
中断时从P2.0取反输出10KHZ方波信号.
定时器1配置为16位自动重装, 2000HZ中断率.
允许高速时钟输出时从P3.4输出1000HZ时钟信号.
中断时从P2.1取反输出1000HZ方波信号.
定时器2固定为16位自动重装, 1000HZ中断率.
允许高速时钟输出时从P1.3输出500HZ时钟信号.
中断时从P2.2取反输出500HZ方波信号.
定时器3固定为16位自动重装, 5000us中断.
允许高速时钟输出时从P0.1输出100HZ时钟信号.
中断时从P2.3取反输出100HZ方波信号.
定时器4固定为16位自动重装, 10000us中断.
允许高速时钟输出时从P0.3输出50HZ时钟信号.
中断时从P2.4取反输出50HZ方波信号.
用户可以修改输出频率,但注意如果允许中断, 则中断频率不要太高(一般100KHZ以下)。
******************************************/
#define MAIN_Fosc 24000000UL //定义主时钟
#include "..\STC32G.h"
u8 Timer0_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
u8 Timer1_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
u8 Timer2_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
u8 Timer3_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
u8 Timer4_Config(u8 t, u32 reload); //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us), 返回0正确, 返回1装载值过大错误.
//========================================================================
// 函数: void main(void)
// 描述: 主函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void main(void)
{
WTST = 0;
/* P_SW2= 0x80;
XOSCCR = 0xc0; //启动外部晶振
while (!(XOSCCR & 1)); //等待时钟稳定
CLKDIV = 0x00; //时钟不分频
CLKSEL = 0x01; //选择外部晶振
*/
EA = 1; //打开总中断
P_SW2 |=0x80;
Timer0_Config(0, MAIN_Fosc / 20000); //t=0: reload值是主时钟周期数,(中断频率, 20000次/秒)
Timer1_Config(0, MAIN_Fosc / 2000); //t=0: reload值是主时钟周期数,(中断频率,2000次/秒)
Timer2_Config(0, MAIN_Fosc / 1000); //t=0: reload值是主时钟周期数,(中断频率,1000次/秒)
Timer3_Config(1, 5000); //t=1: reload值是时间(单位us)
Timer4_Config(1, 10000); //t=1: reload值是时间(单位us)
P2n_standard(0x1f); //P2.0~P2.4设置为准双向口
P3n_standard(0x30); //P3.4 P3.5设置为准双向口
P0n_standard(0xff); //P0.1 P0.3设置为准双向口
P1n_standard(0x08); //P1.3 设置为准双向口
EA = 1; //打开总中断
while (1)
{
}
}
//========================================================================
// 函数:u8 Timer0_Config(u8 t, u32 reload)
// 描述: timer0初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-12-20
//========================================================================
u8 Timer0_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
TR0 = 0; //停止计数
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) AUXR |= 0x80; //1T mode
else
{
AUXR &= ~0x80; //12T mode
reload = reload / 12;
}
reload = 65536UL - reload;
TH0 = (u8)(reload >> 8);
TL0 = (u8)(reload);
ET0 = 1; //允许中断
// PT0 = 1; //高优先级中断
TMOD = (TMOD & ~0x03) | 0; //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
// TMOD |=0x04; //对外计数或分频
INTCLKO |=0x01; //输出时钟
TR0 = 1; //开始运行
return 0;
}
//========================================================================
// 函数: u8 Timer1_Config(u8 t, u32 reload)
// 描述: timer1初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确,1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-12-20
//========================================================================
u8 Timer1_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
TR1 = 0; //停止计数
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) AUXR |= 0x40; //1T mode
else
{
AUXR &= ~0x40; //12T mode
reload = reload / 12;
}
reload = 65536UL - reload;
TH1 = (u8)(reload >> 8);
TL1 = (u8)(reload);
ET1 = 1; //允许中断
// PT1 = 1; //高优先级中断
TMOD = (TMOD & ~0x30) | (0 << 4); //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装
// TMOD |=0x40; //对外计数或分频
INTCLKO |=0x02; //输出时钟
TR1 = 1; //开始运行
return 0;
}
//========================================================================
// 函数: u8 Timer2_Config(u8 t, u32 reload)
// 描述: timer2初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确,1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-12-20
//========================================================================
u8 Timer2_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
AUXR &= ~0x1c; //停止计数, 定时模式, 12T模式
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) AUXR |= (1<<2); //1T mode
else reload = reload / 12; //12T mode
reload = 65536UL - reload;
T2H = (u8)(reload >> 8);
T2L = (u8)(reload);
IE2|=(1<<2); //允许中断
INTCLKO |=0x04; //允许输出时钟
// AUXR |=(1<<3); //对外计数或分频
AUXR |=(1<<4); //开始运行
return 0;
}
//========================================================================
// 函数: u8 Timer3_Config(u8 t, u32 reload)
// 描述: timer3初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确,1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-12-20
//========================================================================
u8 Timer3_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
P_SW2 |= 0x80; //SFR enable
T4T3M &= 0xf0; //停止计数, 定时模式, 12T模式, 不输出时钟
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) T4T3M |=(1<<1); //1T mode
else reload = reload / 12; //12T mode
reload = 65536UL - reload;
T3H = (u8)(reload >> 8);
T3L = (u8)(reload);
T3T4PIN = 0x01; //选择IO, 0x00: T3--P0.4, T3CLKO--P0.5, T4--P0.6, T4CLKO--P0.7; 0x01: T3--P0.0, T3CLKO--P0.1, T4--P0.2, T4CLKO--P0.3;
IE2 |=(1<<5); //允许中断
// T4T3M |=(1<<2); //对外计数或分频
T4T3M |=1; //允许输出时钟
T4T3M |=(1<<3); //开始运行
return 0;
}
//========================================================================
// 函数: u8 Timer4_Config(u8 t, u32 reload)
// 描述: timer3初始化函数.
// 参数: t: 重装值类型, 0表示重装的是系统时钟数, 其余值表示重装的是时间(us).
// reload: 重装值.
// 返回: 0: 初始化正确,1: 重装值过大, 初始化错误.
// 版本: V1.0, 2018-12-20
//========================================================================
u8 Timer4_Config(u8 t, u32 reload) //t=0: reload值是主时钟周期数,t=1: reload值是时间(单位us)
{
P_SW2 |= 0x80; //SFR enable
T4T3M &= 0x0f; //停止计数, 定时模式, 12T模式, 不输出时钟
if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重装的是时间(us), 计算所需要的系统时钟数.
if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
if(reload < 65536UL) T4T3M |=(1<<5); //1T mode
else reload = reload / 12; //12T mode
reload = 65536UL - reload;
T4H = (u8)(reload >> 8);
T4L = (u8)(reload);
T3T4PIN = 0x01; //选择IO, 0x00: T3--P0.4, T3CLKO--P0.5, T4--P0.6, T4CLKO--P0.7; 0x01: T3--P0.0, T3CLKO--P0.1, T4--P0.2, T4CLKO--P0.3;
IE2 |=(1<<6); //允许中断
// T4T3M |=(1<<6); //对外计数或分频
T4T3M |=(1<<4); //允许输出时钟
T4T3M |=(1<<7); //开始运行
return 0;
}
//========================================================================
// 函数: void timer0_ISR (void) interrupt TMR0_VECTOR
// 描述:timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer0_ISR (void) interrupt TMR0_VECTOR
{
//如不是自动重装模式, 请自行添加装初值的代码
P20 = ~P20;
}
//========================================================================
// 函数: void timer1_ISR (void) interrupt TMR1_VECTOR
// 描述:timer1中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer1_ISR (void) interrupt TMR1_VECTOR
{
//如不是自动重装模式, 请自行添加装初值的代码
P21 = ~P21;
}
//========================================================================
// 函数: void timer2_ISR (void) interrupt TMR2_VECTOR
// 描述:timer2中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer2_ISR (void) interrupt TMR2_VECTOR
{
P22 = ~P22;
}
//========================================================================
// 函数: void timer3_ISR (void) interrupt TMR3_VECTOR
// 描述:timer3中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer3_ISR (void) interrupt TMR3_VECTOR
{
P23 = ~P23;
}
//========================================================================
// 函数: void timer4_ISR (void) interrupt TMR4_VECTOR
// 描述:timer4中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2018-12-20
//========================================================================
void timer4_ISR (void) interrupt TMR4_VECTOR
{
P24 = ~P24;
}
stc32g.h 文件可以向STC索取,太大贴不了。
试了5楼程序可解决此问题,谢谢5楼!
页:
[1]