yishiliuye 发表于 2024-8-29 11:58:47

已解决:15w4k48s4使用串口1定时器2通过rs232发送给pc单个字符出问题,大佬帮忙看看

本帖最后由 yishiliuye 于 2024-8-30 09:22 编辑

已解决,查阅数据手册,这款单片机使用外部晶振必须设置24M。
#include "STC15W.H"
#include "intrins.h"

#define    FOSC 24000000L            //系统频率
#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 S1_S0 0x40                //P_SW1.6
#define S1_S1 0x80                //P_SW1.7

bit busy;
sbit BT1 = P3^2;               // 定义BT1按键接在P32
sbit BT2 = P3^3;               // 定义BT2按键接在P33

void SendData(unsigned char dat);
void Delay1000ms(void);
void UartInit(void);
//void SendString(char *s);

void main()
{
    PortSwitch();
    UartInit();

    while(1)
    {   
    unsigned char dat1 = 0x51;
    unsigned char dat2 = 0x54;
    if (BT1 == 0)            // 检测BT1是否被按下
    {
      while (BT1 == 0);   // 消抖
      SendData(dat1);      // 发送字符'Q'
      Delay1000ms();                                                
    }
    if (BT2 == 0)            // 检测BT2是否被按下
   {
      while (BT2 == 0);    // 消抖
      SendData(dat2);      // 发送字符'T'
      Delay1000ms();
    }
    }
}

/*----------------------------
Uart初始化程序
-----------------------------*/
void UartInit(void)
{
    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;

    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;

#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;

}

/*----------------------------
Delay 延时程序
-----------------------------*/
void Delay1000ms(void)    //@11.0592MHz
{
    unsigned char data i, j, k;

    _nop_();
    _nop_();
    i = 43;
    j = 6;
    k = 203;
    do
    {
      do
      {
            while (--k);
      } while (--j);
    } while (--i);
}

/*----------------------------
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(unsigned char dat)
{
    while (busy);                //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    switch (PARITYBIT)
    {
      case ODD_PARITY:
            TB8 = P;
            break;
      case EVEN_PARITY:
            TB8 = !P;
            break;
      case MARK_PARITY:
            TB8 = 1;
            break;
      case SPACE_PARITY:
             TB8 = 0;
            break;
      case NONE_PARITY:
      default:
            break;
    }
    busy = 1;
    SBUF = ACC;                  //写数据到UART数据寄存器
}

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

DebugLab 发表于 2024-8-29 12:26:09




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


#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   //定义校验位

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;               //辅助寄存器
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 P22 = P2^2;

bit busy;

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

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;

    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++);         //发送当前字符
    }
}


yishiliuye 发表于 2024-8-29 12:34:05

DebugLab 发表于 2024-8-29 12:26
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz ...

额,我就是用这个例程改的呀,原来这个也试过了,但是接收到的数据还是不对。{:5_270:}{:5_270:}

Yim_Hom 发表于 2024-8-29 12:41:18

https://www.stcaimcu.com/forum.php?mod=viewthread&tid=10403&page=1#pid102561
这是之前回复别人的,程序是我自己写的,没有参照官方例程,每一个寄存器的注释都很详细,
我用的IAP15W4K,理论上你能通用。
贴出来的图片也是按照程序前后顺序,附带了说明。
看完这个估计你就懂了。

yishiliuye 发表于 2024-8-29 12:56:09

Yim_Hom 发表于 2024-8-29 12:41
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=10403&page=1#pid102561
这是之前回复别人的,程 ...

感谢,我去看看

Yim_Hom 发表于 2024-8-29 13:03:48

yishiliuye 发表于 2024-8-29 12:56
感谢,我去看看

不客气
只是一种思路引导{:4_245:}

yishiliuye 发表于 2024-8-29 13:16:11

Yim_Hom 发表于 2024-8-29 12:41
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=10403&page=1#pid102561
这是之前回复别人的,程 ...

感觉设置的没什么问题呀,接收到的数据还是有问题,一直只能接受到f0{:5_270:}

yishiliuye 发表于 2024-8-29 13:21:13

yishiliuye 发表于 2024-8-29 13:16
感觉设置的没什么问题呀,接收到的数据还是有问题,一直只能接受到f0

总感觉少了什么非常关键的东西,但是又找不到{:5_317:}

Yim_Hom 发表于 2024-8-29 13:29:48



这是回复你的那位发的例程,
你对比看下你的,我大概扫了一眼,看着有区别。

他发的你可以直接复制粘贴试下

我这个是能保证绝对没问题😊

Yim_Hom 发表于 2024-8-29 13:30:24

在外面手机上码字,看的比较累。
页: [1] 2 3
查看完整版本: 已解决:15w4k48s4使用串口1定时器2通过rs232发送给pc单个字符出问题,大佬帮忙看看