采用内部12MHz晶振测试。
从测试数据来看,时间有一定的波动。
从定时器计数值来看,比大部分STC型号速度要快。(CH559 芯片是一款兼容 MCS51 指令集的增强型 E8051 内核单片机,其 79%的指令是单字节单周期指令,平均指令速度比标准 MCS51 快 8~15 倍。),感觉写的没有STC那么夸张,这是实打实。
- 需要指出的是:在官方示例代码中,对时钟4分频代码
宏定义
写的有问题需要注意:
#define mTimer0Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK) //定时器,时钟=Fsys/4
这样写,一旦后面的代码调用此
宏
,编译将会报错。应该写成宏定义函数
:
#define mTimer0Clk4DivFsys( ) {T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK;} //定时器,时钟=Fsys/4
0
和1
Timer0/1 是 2 个 16 位定时/计数器,通过 TCON 和 TMOD 来配置 Timer0 和 Timer1,TCON 用于定时/计数器 T0 和 T1 的启动控制与溢出中断以及外部中断控制。每个定时器都是由 2 个 8 位寄存器组成的 16 位定时单元。定时器 0 的高字节计数器是 TH0,低字节是 TL0;定时器 1 的高字节计数器是TH1,低字节是 TL1。定时器 1 还可以作为 UART0 的波特率发生器。
当定时器0计数达到指定数值时,将P12引脚电平状态翻转。
/********************************** (C) COPYRIGHT *******************************
* File Name : Timer0.C
* Author : WCH
* Version : V1.3
* Date : 2016/06/24
* Description : CH559 Timer0接口函数
*******************************************************************************/
#include "..\DEBUG.C" //调试信息打印
#include "..\DEBUG.H"
//#define FOSC 24000000uL
#define T1MS (65536-FREQ_SYS*50/12/1000) //定时器预装载值
sbit led =P1^2;
UINT16 CNT =0;
#pragma NOAREGS
//CH559 Timer0时钟选择
//bTMR_CLK同时影响Timer0&1&2,使用时要注意
#define mTimer0ClkFsys( ) (T2MOD |= bTMR_CLK | bT0_CLK) //定时器,时钟=Fsys
#define mTimer0Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK) //定时器,时钟=Fsys/4
#define mTimer0Clk12DivFsys( ) (T2MOD &= ~(bTMR_CLK | bT0_CLK)) //定时器,时钟=Fsys/12
#define mTimer0CountClk( ) (TMOD |= bT0_CT) //计数器,T0引脚的下降沿有效
//CH559 Timer0 开始(SS=1)/结束(SS=0)
#define mTimer0RunCTL( SS ) (TR0 = SS ? START : STOP)
/*******************************************************************************
* Function Name : CH559GPIODrivCap(UINT8 Port,UINT8 Cap)
* Description : 端口0、1、2、3驱动能力设置
* Input : UINT8 Port端口选择(0、1、2、3)
UINT8 Cap驱动能力选择((0)5mA、(1)20mA(注意:P1口是10mA))
* Output : None
* Return : SUCCESS成功
FAIL失败
*******************************************************************************/
UINT8 CH559GPIODrivCap(UINT8 Port,UINT8 Cap)
{
if(Port >= 4){
return FAIL;
}
if(Cap == 0){ //驱动电流最大5mA
PORT_CFG &= ~(bP0_DRV << Port);
}
else{
PORT_CFG |= (bP0_DRV << Port); //驱动电流最大20mA
}
return SUCCESS;
}
/*******************************************************************************
* Function Name : CH559GPIOModeSelt(UINT8 Port,UINT8 Mode,UINT8 PinNum)
* Description : 端口0、1、2、3引脚模式设置
* Input : UINT8 Port端口选择(0、1、2、3)
UINT8 Cap驱动方式选择(bPn_OC & Pn_DIR & Pn_PU)
0(000):仅输入,无上拉;
1(001):仅输入,带上拉;
2(01x):推挽输出,高低电平强驱动;
3(100):开漏输出,无上拉,支持输入;
4(110):开漏输出,无上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
5(101):准双向(标准51模式),开漏输出,带上拉
6(111):准双向(标准51模式),开漏输出,带上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
UINT8 PinNum(引脚选择0-7)
* Output : None
* Return : SUCCESS成功
FAIL失败
*******************************************************************************/
UINT8 CH559GPIOModeSelt(UINT8 Port,UINT8 Mode,UINT8 PinNum)
{
UINT8 Pn_DIR,Pn_PU;
if(Port >= 4){
return FAIL;
}
switch (Mode){
case 0: //仅输入,无上拉
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU &= ~(1<<PinNum);
break;
case 1: //仅输入,带上拉
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU |= 1<<PinNum;
break;
case 2: //推挽输出,高低电平强驱动
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR |= (1<<PinNum);
break;
case 3: //开漏输出,无上拉,支持输入
PORT_CFG |= (bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU &= ~(1<<PinNum);
break;
case 4: //开漏输出,无上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
PORT_CFG |= (bP0_OC << Port);
Pn_DIR |= 1<<PinNum;
Pn_PU &= ~(1<<PinNum);
break;
case 5: //弱准双向(标准51模式),开漏输出,带上拉
PORT_CFG |= (bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU |= 1<<PinNum;
break;
case 6: //准双向(标准51模式),开漏输出,带上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
PORT_CFG |= (bP0_OC << Port);
Pn_DIR |= 1<<PinNum;
Pn_PU |= 1<<PinNum;
break;
default:
break;
}
if(Port == 0){
P0_DIR = Pn_DIR;
P0_PU = Pn_PU;
}
if(Port == 1){
P1_DIR = Pn_DIR;
P1_PU = Pn_PU;
}
if(Port == 2){
P2_DIR = Pn_DIR;
P2_PU = Pn_PU;
}
if(Port == 3){
P3_DIR = Pn_DIR;
P3_PU = Pn_PU;
}
return SUCCESS;
}
/*******************************************************************************
* Function Name : mTimer0ModSetup(UINT8 mode)
* Description : CH559定时计数器0模式0设置
* Input : UINT8 mode,Timer0模式选择
0:模式0,13位定时器,TL0的高3位无效
1:模式1,16位定时器
2:模式2,8位自动重装定时器
3:模式3,两个8位定时器
* Output : None
* Return : None
*******************************************************************************/
void mTimer0ModSetup(UINT8 mode)
{
TMOD &= 0xf0;
TMOD |= mode;
}
/*******************************************************************************
* Function Name : mTimer0SetData(UINT16 dat)
* Description : CH559Timer0 TH0和TL0赋值
* Input : UINT16 dat;定时器赋值
* Output : None
* Return : None
*******************************************************************************/
void mTimer0SetData(UINT16 dat)
{
// UINT16 tmp;
// tmp = 65536 - dat;
// TL0 = tmp & 0xff;
// TH0 = (tmp>>8) & 0xff;
TL0 = dat;
TH0 = dat>>8;
}
/*******************************************************************************
* Function Name : mTimer0Interrupt()
* Description : CH559定时计数器0定时计数器中断处理函数
*******************************************************************************/
void mTimer0Interrupt( void ) interrupt INT_NO_TMR0 using 1 //timer0中断服务程序,使用寄存器组1
{ //方式3时,TH0使用Timer1的中断资源
// CAP1 = !CAP1;
// mTimer0SetData(0x2000) //非自动重载方式需重新给TH0和TL0赋值
CNT ++;
if(CNT>=60600){
led = !led; //1秒钟状态翻转
CNT=0;
printf("led");
}
}
void main( )
{
CfgFsys( );//CH559时钟选择配置
mDelaymS(5); //等待外部晶振稳定
mInitSTDIO();//串口0,可以用于调试,默认波特率57600bps
printf("start ...\n");
printf("%hu",(UINT16)T1MS);
CH559GPIODrivCap(1,1);
CH559GPIOModeSelt(1,2,2);
led =0;
mTimer0ModSetup(2); //方式2,自动重载8为定时器
mTimer0ClkFsys( ); //时钟选择Fsys定时器方式
mTimer0SetData(T1MS); //定时器赋初值8995
mTimer0RunCTL( 1 ); //启动定时器
// printf("%02X %02X",(UINT16)TH0,(UINT16)TL0);
ET0 = 1; //使能定时计数器0中断
EA = 1; //使能全局中断
while(1);
}
[2022-10-13 23:33:33.420]# RECV ASCII>
led
[2022-10-13 23:33:34.404]# RECV ASCII>
led
[2022-10-13 23:33:35.404]# RECV ASCII>
led
[2022-10-13 23:33:36.394]# RECV ASCII>
led
[2022-10-13 23:33:37.378]# RECV ASCII>
led
[2022-10-13 23:33:38.362]# RECV ASCII>
led
[2022-10-13 23:33:39.347]# RECV ASCII>
led
[2022-10-13 23:33:40.347]# RECV ASCII>
led
[2022-10-13 23:33:41.336]# RECV ASCII>
led
[2022-10-13 23:33:42.321]# RECV ASCII>
led
[2022-10-13 23:33:43.305]# RECV ASCII>
led
[2022-10-13 23:33:44.290]# RECV ASCII>
led
[2022-10-13 23:33:45.274]# RECV ASCII>
led
[2022-10-13 23:33:46.263]# RECV ASCII>
led
[2022-10-13 23:33:47.263]# RECV ASCII>
led
[2022-10-13 23:33:48.248]# RECV ASCII>
led
DEBUG.C
文件中:/********************************** (C) COPYRIGHT *******************************
* File Name : DEBUG.C
* Author : WCH
* Version : V1.9
* Date : 2021/12/15
* Description : CH559 DEBUG Interface
(1)、串口0输出打印信息,波特率可变;
*******************************************************************************/
#include
#include "CH559.H"
#define FREQ_SYS 6000000 //Fsys/4
#ifndef BUAD
#define BUAD 9600 //57600
#endif
#define OSC_EN_XT 1 //启用外部时钟
/********************************** (C) COPYRIGHT *******************************
* File Name : Timer0.C
* Author : WCH
* Version : V1.3
* Date : 2016/06/24
* Description : CH559 Timer0接口函数
*******************************************************************************/
#include "..\DEBUG.C" //调试信息打印
#include "..\DEBUG.H"
#include
//#define FOSC 24000000uL
#define T1MS (65536-FREQ_SYS*50/12/1000) //重装载计数值
sbit led =P1^2;
UINT16 CNT =0;
#pragma NOAREGS
//CH559 Timer0时钟选择
//bTMR_CLK同时影响Timer0&1&2,使用时要注意
#define mTimer0ClkFsys( ) (T2MOD |= bTMR_CLK | bT0_CLK) //定时器,时钟=Fsys
#define mTimer0Clk4DivFsys( ) {T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK;}//定时器,时钟=Fsys/4
#define mTimer0Clk12DivFsys( ) (T2MOD &= ~(bTMR_CLK | bT0_CLK)) //定时器,时钟=Fsys/12
#define mTimer0CountClk( ) (TMOD |= bT0_CT) //计数器,T0引脚的下降沿有效
//CH559 Timer0 开始(SS=1)/结束(SS=0)
#define mTimer0RunCTL( SS ) (TR0 = SS ? START : STOP)
/*******************************************************************************
* Function Name : CH559GPIODrivCap(UINT8 Port,UINT8 Cap)
* Description : 端口0、1、2、3驱动能力设置
* Input : UINT8 Port端口选择(0、1、2、3)
UINT8 Cap驱动能力选择((0)5mA、(1)20mA(注意:P1口是10mA))
* Output : None
* Return : SUCCESS成功
FAIL失败
*******************************************************************************/
UINT8 CH559GPIODrivCap(UINT8 Port,UINT8 Cap)
{
if(Port >= 4){
return FAIL;
}
if(Cap == 0){ //驱动电流最大5mA
PORT_CFG &= ~(bP0_DRV << Port);
}
else{
PORT_CFG |= (bP0_DRV << Port); //驱动电流最大20mA
}
return SUCCESS;
}
/*******************************************************************************
* Function Name : CH559GPIOModeSelt(UINT8 Port,UINT8 Mode,UINT8 PinNum)
* Description : 端口0、1、2、3引脚模式设置
* Input : UINT8 Port端口选择(0、1、2、3)
UINT8 Cap驱动方式选择(bPn_OC & Pn_DIR & Pn_PU)
0(000):仅输入,无上拉;
1(001):仅输入,带上拉;
2(01x):推挽输出,高低电平强驱动;
3(100):开漏输出,无上拉,支持输入;
4(110):开漏输出,无上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
5(101):准双向(标准51模式),开漏输出,带上拉
6(111):准双向(标准51模式),开漏输出,带上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
UINT8 PinNum(引脚选择0-7)
* Output : None
* Return : SUCCESS成功
FAIL失败
*******************************************************************************/
UINT8 CH559GPIOModeSelt(UINT8 Port,UINT8 Mode,UINT8 PinNum)
{
UINT8 Pn_DIR,Pn_PU;
if(Port >= 4){
return FAIL;
}
switch (Mode){
case 0: //仅输入,无上拉
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU &= ~(1<<PinNum);
break;
case 1: //仅输入,带上拉
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU |= 1<<PinNum;
break;
case 2: //推挽输出,高低电平强驱动
PORT_CFG &= ~(bP0_OC << Port);
Pn_DIR |= (1<<PinNum);
break;
case 3: //开漏输出,无上拉,支持输入
PORT_CFG |= (bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU &= ~(1<<PinNum);
break;
case 4: //开漏输出,无上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
PORT_CFG |= (bP0_OC << Port);
Pn_DIR |= 1<<PinNum;
Pn_PU &= ~(1<<PinNum);
break;
case 5: //弱准双向(标准51模式),开漏输出,带上拉
PORT_CFG |= (bP0_OC << Port);
Pn_DIR &= ~(1<<PinNum);
Pn_PU |= 1<<PinNum;
break;
case 6: //准双向(标准51模式),开漏输出,带上拉,当转变输出由低到高时,仅驱动2个时钟的高电平
PORT_CFG |= (bP0_OC << Port);
Pn_DIR |= 1<<PinNum;
Pn_PU |= 1<<PinNum;
break;
default:
break;
}
if(Port == 0){
P0_DIR = Pn_DIR;
P0_PU = Pn_PU;
}
if(Port == 1){
P1_DIR = Pn_DIR;
P1_PU = Pn_PU;
}
if(Port == 2){
P2_DIR = Pn_DIR;
P2_PU = Pn_PU;
}
if(Port == 3){
P3_DIR = Pn_DIR;
P3_PU = Pn_PU;
}
return SUCCESS;
}
/*******************************************************************************
* Function Name : mTimer0ModSetup(UINT8 mode)
* Description : CH559定时计数器0模式0设置
* Input : UINT8 mode,Timer0模式选择
0:模式0,13位定时器,TL0的高3位无效
1:模式1,16位定时器
2:模式2,8位自动重装定时器
3:模式3,两个8位定时器
* Output : None
* Return : None
*******************************************************************************/
void mTimer0ModSetup(UINT8 mode)
{
TMOD &= 0xf0;
TMOD |= mode;
}
/*******************************************************************************
* Function Name : mTimer0SetData(UINT16 dat)
* Description : CH559Timer0 TH0和TL0赋值
* Input : UINT16 dat;定时器赋值
* Output : None
* Return : None
*******************************************************************************/
void mTimer0SetData(UINT16 dat)
{
// UINT16 tmp;
// tmp = 65536 - dat;
// TL0 = tmp & 0xff;
// TH0 = (tmp>>8) & 0xff;
TL0 = dat;
TH0 = dat>>8;
}
/*******************************************************************************
* Function Name : mTimer0Interrupt()
* Description : CH559定时计数器0定时计数器中断处理函数
*******************************************************************************/
void mTimer0Interrupt( void ) interrupt INT_NO_TMR0 using 1 //timer0中断服务程序,使用寄存器组1
{ //方式3时,TH0使用Timer1的中断资源
// CAP1 = !CAP1;
// mTimer0SetData(0x2000) //非自动重载方式需重新给TH0和TL0赋值
CNT ++;
if(CNT>=60600){
led = !led; //1秒钟状态翻转
CNT=0;
printf("led");
}
}
void main( )
{
CfgFsys( );//CH559时钟选择配置
mDelaymS(5); //等待外部晶振稳定
mInitSTDIO();//串口0,可以用于调试,默认波特率57600bps
printf("start ...\n");
printf("%hu",(UINT16)T1MS);
CH559GPIODrivCap(1,1);
CH559GPIOModeSelt(1,2,2);
led =0;
mTimer0ModSetup(2); //方式2,自动重载8为定时器
// mTimer0ClkFsys( ); //时钟选择Fsys定时器方式:时钟=Fsys
// mTimer0Clk12DivFsys();//时钟=Fsys/12
mTimer0Clk4DivFsys(); //时钟=Fsys/4
// T2MOD &= ~bTMR_CLK;
// T2MOD |= bT0_CLK;//同上
mTimer0SetData(T1MS); //定时器赋初值8995
mTimer0RunCTL( 1 ); //启动定时器
// printf("%02X %02X",(UINT16)TH0,(UINT16)TL0);
ET0 = 1; //使能定时计数器0中断
EA = 1; //使能全局中断
while(1);
}
[2022-10-14 21:30:37.923]# RECV ASCII>
led
[2022-10-14 21:30:38.915]# RECV ASCII>
led
[2022-10-14 21:30:39.910]# RECV ASCII>
led
[2022-10-14 21:30:40.902]# RECV ASCII>
led
[2022-10-14 21:30:41.898]# RECV ASCII>
led
[2022-10-14 21:30:42.896]# RECV ASCII>
led
[2022-10-14 21:30:43.881]# RECV ASCII>
led
[2022-10-14 21:30:44.874]# RECV ASCII>
led
[2022-10-14 21:30:45.854]# RECV ASCII>
led
[2022-10-14 21:30:46.848]# RECV ASCII>
led
[2022-10-14 21:30:47.845]# RECV ASCII>
led
[2022-10-14 21:30:48.838]# RECV ASCII>
led
[2022-10-14 21:30:49.828]# RECV ASCII>
led
[2022-10-14 21:30:50.809]# RECV ASCII>
led
[2022-10-14 21:30:51.802]# RECV ASCII>
led
[2022-10-14 21:30:52.794]# RECV ASCII>
led
[2022-10-14 21:30:53.788]# RECV ASCII>
led
[2022-10-14 21:30:54.782]# RECV ASCII>
led
[2022-10-14 21:30:55.775]# RECV ASCII>
led
[2022-10-14 21:30:56.767]# RECV ASCII>
led
[2022-10-14 21:30:57.758]# RECV ASCII>
led
[2022-10-14 21:30:58.753]# RECV ASCII>
led
[2022-10-14 21:30:59.745]# RECV ASCII>
led
[2022-10-14 21:31:00.738]# RECV ASCII>
led
[2022-10-14 21:31:01.736]# RECV ASCII>
led
[2022-10-14 21:31:02.712]# RECV ASCII>
led
[2022-10-14 21:31:03.707]# RECV ASCII>
led
[2022-10-14 21:31:04.702]# RECV ASCII>
led
[2022-10-14 21:31:05.692]# RECV ASCII>
led
[2022-10-14 21:31:06.687]# RECV ASCII>
led
[2022-10-14 21:31:07.680]# RECV ASCII>
led
[2022-10-14 21:31:08.675]# RECV ASCII>
led
[2022-10-14 21:31:09.655]# RECV ASCII>
led
[2022-10-14 21:31:10.649]# RECV ASCII>
led
[2022-10-14 21:31:11.643]# RECV ASCII>
led
[2022-10-14 21:31:12.637]# RECV ASCII>
led
[2022-10-14 21:31:13.630]# RECV ASCII>
led
[2022-10-14 21:31:14.625]# RECV ASCII>
led
[2022-10-14 21:31:15.619]# RECV ASCII>
led
[2022-10-14 21:31:16.612]# RECV ASCII>
led
[2022-10-14 21:31:17.591]# RECV ASCII>
led
[2022-10-14 21:31:18.584]# RECV ASCII>
led
[2022-10-14 21:31:19.578]# RECV ASCII>
led
[2022-10-14 21:31:20.572]# RECV ASCII>
led
[2022-10-14 21:31:21.569]# RECV ASCII>
led
[2022-10-14 21:31:22.548]# RECV ASCII>
led
[2022-10-14 21:31:23.543]# RECV ASCII>
led
[2022-10-14 21:31:24.536]# RECV ASCII>
led
[2022-10-14 21:31:25.530]# RECV ASCII>
led
[2022-10-14 21:31:26.522]# RECV ASCII>
led
[2022-10-14 21:31:27.515]# RECV ASCII>
led
[2022-10-14 21:31:28.510]# RECV ASCII>
led
[2022-10-14 21:31:29.499]# RECV ASCII>
led
[2022-10-14 21:31:30.492]# RECV ASCII>
led
[2022-10-14 21:31:31.486]# RECV ASCII>
led
[2022-10-14 21:31:32.482]# RECV ASCII>
led
[2022-10-14 21:31:33.460]# RECV ASCII>
led
[2022-10-14 21:31:34.456]# RECV ASCII>
led
[2022-10-14 21:31:35.446]# RECV ASCII>
led
[2022-10-14 21:31:36.442]# RECV ASCII>
led
[2022-10-14 21:31:37.438]# RECV ASCII>
led
[2022-10-14 21:31:38.432]# RECV ASCII>
led
[2022-10-14 21:31:39.409]# RECV ASCII>
led
[2022-10-14 21:31:40.417]# RECV ASCII>
led
[2022-10-14 21:31:41.397]# RECV ASCII>
led
[2022-10-14 21:31:42.390]# RECV ASCII>
led
[2022-10-14 21:31:43.383]# RECV ASCII>
led
[2022-10-14 21:31:44.377]# RECV ASCII>
led
[2022-10-14 21:31:45.370]# RECV ASCII>
led
[2022-10-14 21:31:46.365]# RECV ASCII>
led
[2022-10-14 21:31:47.358]# RECV ASCII>
led
[2022-10-14 21:31:48.350]# RECV ASCII>
led
[2022-10-14 21:31:49.343]# RECV ASCII>
led