已解决: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++); //发送当前字符
}
}*/
//本示例在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++); //发送当前字符
}
}
DebugLab 发表于 2024-8-29 12:26
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz ...
额,我就是用这个例程改的呀,原来这个也试过了,但是接收到的数据还是不对。{:5_270:}{:5_270:}
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=10403&page=1#pid102561
这是之前回复别人的,程序是我自己写的,没有参照官方例程,每一个寄存器的注释都很详细,
我用的IAP15W4K,理论上你能通用。
贴出来的图片也是按照程序前后顺序,附带了说明。
看完这个估计你就懂了。 Yim_Hom 发表于 2024-8-29 12:41
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=10403&page=1#pid102561
这是之前回复别人的,程 ...
感谢,我去看看 yishiliuye 发表于 2024-8-29 12:56
感谢,我去看看
不客气
只是一种思路引导{:4_245:} 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:16
感觉设置的没什么问题呀,接收到的数据还是有问题,一直只能接受到f0
总感觉少了什么非常关键的东西,但是又找不到{:5_317:}
这是回复你的那位发的例程,
你对比看下你的,我大概扫了一眼,看着有区别。
他发的你可以直接复制粘贴试下
我这个是能保证绝对没问题😊
在外面手机上码字,看的比较累。