打印
[STC单片机]

串口字符串发送问题

[复制链接]
2963|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
abchhcba2012|  楼主 | 2014-12-15 23:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

国产单片机也发了一份帖子,但是人不多啊,发到这里也请大家帮忙看一下,我用STC15W单片机串口2与计算机做通信实验,下面是实验程序,
#include "reg51.h"
#include "intrins.h"

typedef unsigned char uchar;
typedef unsigned int uint;

#define FOSC 18432000       //系统频率
#define BAUD 9600              //串口波特率
#define S2RI  0x01              //S2CON.0
#define S2TI  0x02              //S2CON.1
/*----------------------------
         寄存器定义
----------------------------*/
sfr AUXR  = 0x8e;                             //辅助寄存器
sfr S2CON =        0x9a;                        //串口2控制寄存器
sfr IE2   =        0xaf;                                //串口2中断控制寄存器
sfr S2BUF =        0x9b;                        //串口2缓存寄存器
sfr T2H   = 0xd6;                             //定时器2高8位
sfr T2L   = 0xd7;                             //定时器2低8位
sfr P_SW1 = 0xA2;                         //外设功能切换寄存器1
sfr P_SW2 = 0xBA;                         //外设功能切换寄存器2
sfr P1M1 = 0x91;                              //IO口模式控制寄存器
sfr P1M0 = 0x92;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xb1;
sfr P3M0 = 0xb2;
sbit PM01=P1^3;
sbit PM00=P1^4;
/*----------------------------
         函数声明
----------------------------*/
void SendData(uchar dat);
void SendString(uchar *s);
/*----------------------------
         主函数
----------------------------*/
void main()
{
           P1M1=0;                                                      //将IO口设置为上电弱上拉
        P1M0=0;
        P2M1=0;
        P2M0=0;
        P3M1=0;
        P3M0=0;
        PM01=0;
        PM00=1;
        P_SW2 = P_SW2&0xFE;
        P_SW1 = P_SW1&0x3F;                            //串口1设置为(P3.0/RxD, P3.1/TxD)
        S2CON =0x50;                                                  //串口2工作于模式0,开串口2接收
        SCON = 0x50;                                                  //串口1工作于模式1,开串口1接收
        T2L = (65536 - (FOSC/4/BAUD));              //设置波特率重装值
        T2H = (65536 - (FOSC/4/BAUD))/256;
        AUXR = 0x15;                                                  //设置定时器2工作1T,串口1、2用定时器2做波特率发生器
        PS=1;                                                          //设置串口1优先级为高
        ES = 1;                                                      //使能串口1中断
        IE2=0x01;                                                 //使能串口2中断
        EA = 1;                                                                  //开总中断
        SendString("STC15F2K60S2\r\nUart2 Test !\r\n");
        while(1);
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(uchar dat)
{
        S2BUF=dat;
        while(!(S2CON & S2TI));
         S2CON &= ~S2TI;              //清除S2TI位
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(uchar *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}
上电以后,串口助手显示的字符是SSTC15F2K60S2\r\nUart2 Test !,首字母发了两遍,不知道什么原因,请指点一下,谢谢。

相关帖子

沙发
ningling_21| | 2014-12-16 11:31 | 只看该作者
while (*s)                  //检测字符串结束标志

改成

while (*s!='\0')                  //检测字符串结束标志

使用特权

评论回复
板凳
ayb_ice| | 2014-12-16 11:48 | 只看该作者
ningling_21 发表于 2014-12-16 11:31
while (*s)                  //检测字符串结束标志

改成

这一样的效果好不好,就是可读性好点

使用特权

评论回复
地板
NE5532| | 2014-12-16 13:02 | 只看该作者
额,STC是告诉你,其实他跟SST是一样的。呵呵,吐个槽了。:lol

你试一下,只发一个字符看看啥效果呢?

使用特权

评论回复
5
abchhcba2012|  楼主 | 2014-12-16 14:00 | 只看该作者
ningling_21 发表于 2014-12-16 11:31
while (*s)                  //检测字符串结束标志

改成

还是一样的

使用特权

评论回复
6
abchhcba2012|  楼主 | 2014-12-16 14:01 | 只看该作者
NE5532 发表于 2014-12-16 13:02
额,STC是告诉你,其实他跟SST是一样的。呵呵,吐个槽了。

你试一下,只发一个字符看看啥效果呢? ...

额。。发一个字符还是有重复,我真的有点迷糊了

使用特权

评论回复
7
abchhcba2012|  楼主 | 2014-12-16 14:04 | 只看该作者
但是,用了STC的示例程序
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器2用作串口2的波特率发生器举例------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.**.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在**中应用此代码,请在**中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

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

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define FOSC 18432000L          //系统频率
#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 EVEN_PARITY   //定义校验位

sfr AUXR  = 0x8e;               //辅助寄存器
sfr S2CON = 0x9a;               //UART2 控制寄存器
sfr S2BUF = 0x9b;               //UART2 数据寄存器
sfr T2H   = 0xd6;               //定时器2高8位
sfr T2L   = 0xd7;               //定时器2低8位
sfr IE2   = 0xaf;               //中断控制寄存器2

#define S2RI  0x01              //S2CON.0
#define S2TI  0x02              //S2CON.1
#define S2RB8 0x04              //S2CON.2
#define S2TB8 0x08              //S2CON.3

sfr P_SW2   = 0xBA;             //外设功能切换寄存器2
#define S2_S0 0x01              //P_SW2.0

bit busy;

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

void main()
{
    P_SW2 &= ~S2_S0;            //S2_S0=0 (P1.0/RxD2, P1.1/TxD2)
//  P_SW2 |= S2_S0;             //S2_S0=1 (P4.6/RxD2_2, P4.7/TxD2_2)

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

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

    SendString("STC15F2K60S2\r\nUart2 Test !\r\n");
    while(1);
}

/*----------------------------
UART2 中断服务程序
-----------------------------*/
void Uart2() interrupt 8 using 1
{
    if (S2CON & S2RI)
    {
        S2CON &= ~S2RI;         //清除S2RI位
        P0 = S2BUF;             //P0显示串口数据
        P2 = (S2CON & S2RB8);   //P2.2显示校验位
    }
    if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;         //清除S2TI位
        busy = 0;               //清忙标志
    }
}

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

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}
串口显示的字符是正确的,感觉跟自己写的应该没什么区别啊

使用特权

评论回复
8
NE5532| | 2014-12-16 14:43 | 只看该作者
试着用一下软仿真,看中断进来了几次,是否有没有想到的地方。

使用特权

评论回复
9
abchhcba2012|  楼主 | 2014-12-16 14:53 | 只看该作者
嗯,我去试试

使用特权

评论回复
10
hddg| | 2014-12-17 16:50 | 只看该作者
改成和官方波特率一样试试。

使用特权

评论回复
11
mazhao141| | 2014-12-17 17:48 | 只看该作者
初始化的时候清一下状态寄存器

使用特权

评论回复
12
coody| | 2014-12-17 21:44 | 只看该作者
你的两个串口中断函数在哪里?

使用特权

评论回复
13
nbsmaps| | 2014-12-19 15:07 | 只看该作者
初始化加一句关中断的,我用你这个程序直接发接疏的是正常的,唯一区别是我加了关中断

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

68

帖子

0

粉丝