找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3153|回复: 15
收起左侧

STC8A8K64S4A12单片机串口2程序问题 求帮助

[复制链接]
ID:560941 发表于 2021-10-17 20:17 | 显示全部楼层 |阅读模式
程序:void uart_init()
{        
        /* ----------------------------------------------------串口2初始化------------------------------*/
        S2CON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x04;                //定时器2时钟为Fosc,即1T
        if(com2_baud == 1)
        {
                T2L = 0xE0;                //设定定时初值 9600
                T2H = 0xFE;                //设定定时初值
        }
        AUXR |= 0x10;                //启动定时器2
        /*引脚选择*/

                      P_SW2 |= 0x81;        //RXD2_2/P4.0, TXD2_2/P4.2
                          P_SW2 &= ~0x80;//关闭访问扩展特殊寄存器        
        }
        IE2 |= 0x01;         //使能串口2中断
}

/******************************************
函数名:putbuf
功能:输出一个字符
*******************************************/
void putbuf(char dat)
{
        S2BUF = dat;
        while(S2CON&S2TI==0);
}

/******************************************
函数名:Delay1000ms()
功能:延迟1s
*******************************************/
void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        i = 57;
        j = 27;
        k = 112;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

/******************************************
函数名:sendstring(char * dat)
功能:输出字符串
*******************************************/
void sendstring(char * dat)
{
        while(*dat != '\0')
        {
                putbuf(*dat++);
        }
}

/******************************************
函数名:com2_isr() interrupt 8
功能:串口2中断服务函数
*******************************************/
void com2_isr() interrupt 8
{
        unsigned char res; //串口2接收数据临时存放区
    if (S2CON & S2RI)
    {        
        S2CON &= ~S2RI;                         //清中断标志      
    }
    if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;                         //清中断标志        
    }
}

void main(void)
{
        uart_init();
        EA =1;
        while(1)
        {
                sendstring("TEST ! \r\n");
                Delay1000ms();
        }
}


////接到串口助手,一直显示数据:0A(HEX格式),怎么回事???哪里出错了??

回复

使用道具 举报

ID:560941 发表于 2021-10-17 21:49 | 显示全部楼层
最新发现:连续发送字符串,比如“ABC”,只会输出最后一个字符。同样我上面程序里输出“TEST ! \r\n”,只会输出‘\n’,为什么会这样啊
回复

使用道具 举报

ID:624769 发表于 2021-10-17 23:40 | 显示全部楼层
       while(S2CON&S2TI==0);

这个不能偷懒,要这样写:    while((S2CON&S2TI)==0);
回复

使用道具 举报

ID:65956 发表于 2021-10-18 08:26 | 显示全部楼层
你要测试输出,先把接收中断关闭试试就知道什么原因了,按你这个发送也进入中断,肯定会和你发送字符这个函数冲突的
回复

使用道具 举报

ID:277550 发表于 2021-10-18 10:03 | 显示全部楼层

发送情况,加一个全局的“忙”变量来处理,开始发送设置“忙”,中断中设置不忙。这样防止冲突。
回复

使用道具 举报

ID:560941 发表于 2021-10-18 19:06 | 显示全部楼层
188610329 发表于 2021-10-17 23:40
while(S2CON&S2TI==0);

这个不能偷懒,要这样写:    while((S2CON&S2TI)==0);

不是这个原因,试了不行。。
回复

使用道具 举报

ID:560941 发表于 2021-10-18 19:39 | 显示全部楼层
aking991 发表于 2021-10-18 08:26
你要测试输出,先把接收中断关闭试试就知道什么原因了,按你这个发送也进入中断,肯定会和你发送字符这个函 ...

后面试了,不开中断也这样
回复

使用道具 举报

ID:560941 发表于 2021-10-18 19:44 | 显示全部楼层
devcang 发表于 2021-10-18 10:03
发送情况,加一个全局的“忙”变量来处理,开始发送设置“忙”,中断中设置不忙。这样防止冲突。

这个方法确实是可行的,但是我就不懂为什么串口1可以用中断标志位来设置等待,串口2就不可以了。。
回复

使用道具 举报

ID:560941 发表于 2021-10-18 20:01 | 显示全部楼层
devcang 发表于 2021-10-18 10:03
发送情况,加一个全局的“忙”变量来处理,开始发送设置“忙”,中断中设置不忙。这样防止冲突。

大神,可不可以帮我解答这个问题
回复

使用道具 举报

ID:624769 发表于 2021-10-18 20:31 | 显示全部楼层
mlz159357 发表于 2021-10-18 19:06
不是这个原因,试了不行。。

你整个程序, 除了 while(S2CON&S2TI==0); 写错之外,其他地方看下来都没有问题.

要么,你换引脚看看?  用标准引脚试试看?
回复

使用道具 举报

ID:401564 发表于 2021-10-18 20:36 | 显示全部楼层
以下是我用STC8A4K照着官方写的,已经在开发板上验证成功了
手头上没有现成的8A8K电路板,但实际都是8A系列的,是一样的
你对比一下
/*================================
Stc8a4k串口2测试程序
单片机型号:STC8A4K
波特率:9600
==================================*/
#include "Stc8a.h"
bit busy;
char wptr;
char rptr;
char buffer[16];
//===========================================================
//函数名:Delay1000ms()
//功能:延迟1s
void Delay1000ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        i = 57;
        j = 27;
        k = 112;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
//===========================================================
void Uart2Isr() interrupt 8
{
    if (S2CON & S2TI)
    {
        S2CON &= ~S2TI;
        busy = 0;
    }
    if (S2CON & S2RI)
    {
        S2CON &= ~S2RI;
    }
}
//===========================================================
void Uart2Init()
{
    S2CON = 0x50;                //8位数据,可变波特率:9600
        AUXR &= 0xFB;                //定时器时钟12T模式
        T2L = 0xE8;                //设置定时初始值
        T2H = 0xFF;                //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
}
//===========================================================
void Uart2Send(char dat)
{
    while (busy);
    busy = 1;
    S2BUF = dat;
}
//===========================================================
void Uart2SendStr(char *p)
{
    while (*p!= '\0')
    {
        Uart2Send(*p++);
    }
}
//===========================================================
void main()
{
    Uart2Init();
    IE2 = 0x01;
    EA = 1;
    while (1)
    {      
            Uart2SendStr("Uart Test !\r\n");
            Delay1000ms();
    }
}
//===========================================================
回复

使用道具 举报

ID:560941 发表于 2021-10-20 14:47 | 显示全部楼层
Y_G_G 发表于 2021-10-18 20:36
以下是我用STC8A4K照着官方写的,已经在开发板上验证成功了
手头上没有现成的8A8K电路板,但实际都是8A系列 ...

嗯嗯,后来我也按照stc官方参考手册改了程序,也成功了。问题在于我的程序是用的中断标志位去设置等待发送完毕,官方手册是用一个全局变量“busy”来设置等待发送完毕。可我就是想不通为什么用中断标志位设置等待不可行呢?
回复

使用道具 举报

ID:560941 发表于 2021-10-20 14:47 | 显示全部楼层
188610329 发表于 2021-10-18 20:31
你整个程序, 除了 while(S2CON&S2TI==0); 写错之外,其他地方看下来都没有问题.

要么,你换引脚看看?   ...

引脚换了也不行。。。。
回复

使用道具 举报

ID:401564 发表于 2021-10-20 15:13 | 显示全部楼层
mlz159357 发表于 2021-10-20 14:47
嗯嗯,后来我也按照stc官方参考手册改了程序,也成功了。问题在于我的程序是用的中断标志位去设置等待发 ...

这个串口2的中断标志位位于9AH寄存器
这个寄存器不支持位寻址
&是按位与
所以,结果是怎么不重要,肯定不会是正确的
回复

使用道具 举报

ID:401564 发表于 2021-10-20 15:17 | 显示全部楼层
mlz159357 发表于 2021-10-20 14:47
嗯嗯,后来我也按照stc官方参考手册改了程序,也成功了。问题在于我的程序是用的中断标志位去设置等待发 ...

串口1的TI和RI支持位寻址,你可以试一下就知道我说的了
回复

使用道具 举报

ID:560941 发表于 2021-10-20 15:39 | 显示全部楼层
Y_G_G 发表于 2021-10-20 15:17
串口1的TI和RI支持位寻址,你可以试一下就知道我说的了

明白了,感觉有道理
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表