dabing0577 发表于 2023-5-31 21:36:11

求一个可以运行的串口1和二个定时器的初始化程序

本帖最后由 dabing0577 于 2023-5-31 21:45 编辑

STC15F2K60S2 系列
定时器1的16位自动重装载模式;1ms中断
定时器0的16位自动重装载模式;10ms中断
定时器2用作串口1的波特率发生器
的初始化例子.



dabing0577 发表于 2023-5-31 21:42:36

版主如有看见帖子   恳请抽空做一个例子发一下
按照sts_isp里独自的案例组合起来   不能正常运行

梁工 发表于 2023-5-31 23:06:08

到STC官网下载各种例子程序包吧,你要的都有。初学者,一定要从官方例子开始。

www.stcai.com

angmall 发表于 2023-6-1 08:40:09

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器0的16位自动重装载模式举例---------------*/
/* --- Mobile: (86)13922805190 -------------- -------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序      */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序      */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz

//STC15F2K60S2 系列
//定时器1的16位自动重装载模式;1ms中断
//定时器0的16位自动重装载模式;10ms中断
//定时器2用作串口1的波特率发生器
//的初始化例子.



#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 11059200L          //系统频率
#define BAUD 115200             //串口波特率

#define NONE_PARITY   0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY   2       //偶校验
#define MARK_PARITY   3       //标记校验
#define SPACE_PARITY    4       //空白校验

#define PARITYBIT NONE_PARITY   //定义校验位

//-----------------------------------------------

#define T0MS (65536-FOSC/10000)      //1T模式
//#define T0MS (65536-FOSC/12/10000) //12T模式

#define T1MS (65536-FOSC/1000)      //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式


sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sfr AUXR = 0x8e;                //Auxiliary register

sfr T2H   = 0xd6;               //定时器2高8位
sfr T2L   = 0xd7;               //定时器2低8位

sfr P_SW1   = 0xA2;             //外设功能切换寄存器1

#define S1_S0 0x40            //P_SW1.6
#define S1_S1 0x80            //P_SW1.7

sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P22 = P2^2;

bit busy;

void SendData(BYTE dat);
void SendString(char *s);

//-----------------------------------------------

/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
    P10 = ! P10;                  //将测试口取反
}

//-----------------------------------------------

/* Timer1 interrupt routine */
void tm1_isr() interrupt 3
{
    P11 = ! P11;                  //将测试口取反
}


//-----------------------------------------------

/* main program */
void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    AUXR |= 0x80;                   //定时器0为1T模式
//AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                  //设置定时器为模式0(16位自动重装载)
    TL0 = T0MS;                     //初始化计时值
    TH0 = T0MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    AUXR |= 0x40;                   //定时器1为1T模式
//AUXR &= 0xdf;                   //定时器1为12T模式

    TMOD |= 0x00;                  //设置定时器为模式0(16位自动重装载)
    TL1 = T1MS;                     //初始化计时值
    TH1 = T1MS >> 8;
    TR1 = 1;                        //定时器1开始计时
    ET1 = 1;             


    ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
   
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//P_SW1 = ACC;
//
//ACC = P_SW1;
//ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//P_SW1 = ACC;

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    T2L = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    T2H = (65536 - (FOSC/4/BAUD))>>8;
    AUXR |= 0x14;                //T2为1T模式, 并启动定时器2
    AUXR |= 0x01;               //选择定时器2为串口1的波特率发生器
    ES = 1;                     //使能串口1中断
    EA = 1;

    SendString("STC15F2K60S2\r\nUart Test !\r\n");


    while (1);
}


/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4
{
    if (RI)
    {
      RI = 0;               //清除RI位
      P0 = SBUF;            //P0显示串口数据
      P22 = RB8;            //P2.2显示校验位
    }
    if (TI)
    {
      TI = 0;               //清除TI位
      busy = 0;               //清忙标志
    }
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
      TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
      TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;               //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
      SendData(*s++);         //发送当前字符
    }
}




dabing0577 发表于 2023-6-1 09:44:52

梁工 发表于 2023-5-31 23:06
到STC官网下载各种例子程序包吧,你要的都有。初学者,一定要从官方例子开始。

www.stcai.com


平时都是用STM32f1xx系列做项目
stc官方给的例子是很丰富; 不过这几个定时器和串口组合在一起时候
不是预想中运行.
斑斑可以做一个例子发出吗

angmall 发表于 2023-6-1 11:32:55

angmall 发表于 2023-6-1 08:40
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited --- ...



一个可以运行的串口1和二个定时器的初始化程序




梁工 发表于 2023-6-1 11:54:32

dabing0577 发表于 2023-6-1 09:44
平时都是用STM32f1xx系列做项目
stc官方给的例子是很丰富; 不过这几个定时器和串口组合在一起时候
不 ...

订做例子如下:



/*************        功能说明        **************
请先别修改程序, 直接下载"UART1.hex"测试.


串口1全双工中断方式收发通讯程序, 本例程使用11.0592MHZ时钟,如要改变,请修改下面的"定义主时钟"的值并重新编译。

本例串口1切换到P3.0--RXD, P3.1--TXD, 串口设置为:115200,8,n,1.

上电时先发送一串字符串"STC15xxxx UART1 测试程序!\r\n".

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.


同时定时器0工作于16位自动重装模式,1ms中断, 中断取反P3.2输出500HZ方波.
同时定时器1工作于16位自动重装模式, 10ms中断, 中断取反P3.3输出50HZ方波.
******************************************/






dabing0577 发表于 2023-6-1 13:23:49

谢谢楼上二位热心网友
还有一个问题
定时器和串口初始化顺序按照官网例子进行
有优先顺序吗?

我昨天的例子就是因为把定时器放在串口前进行初始化造成定时器不能中断

梁工 发表于 2023-6-1 13:38:08

dabing0577 发表于 2023-6-1 13:23
谢谢楼上二位热心网友
还有一个问题
定时器和串口初始化顺序按照官网例子进行


无关先后!
但是要注意,定时器0和定时器1共用的寄存器,一定要用“与”和“或操作”,不要影响别的位。如果你发现初始化有先后,则基本100%是犯了上述错误。

dabing0577 发表于 2023-6-1 13:58:59

梁工 发表于 2023-6-1 13:38
无关先后!
但是要注意,定时器0和定时器1共用的寄存器,一定要用“与”和“或操作”,不要影响别的位。 ...

我也根据经验就是这样寄存器的事情;故建议官网给出的例子中;换芯片的人   把不同模块例子放一起也能进行工作.    现在研发很卷   基本上没有时间去研究寄存器的各个值之间的关系   没有在线可用的如同ulink一样方便的仿真器是stc15的短板
页: [1] 2
查看完整版本: 求一个可以运行的串口1和二个定时器的初始化程序