找回密码
 立即注册
查看: 278|回复: 10

(已解决)求助贴: 串口2发送中文和英文字符串,32G12K128英文正常,中文不正常

[复制链接]

该用户从未签到

2

主题

15

回帖

54

积分

注册会员

积分
54
发表于 2024-1-8 19:36:22 | 显示全部楼层 |阅读模式
本帖最后由 ZJJSXXD 于 2024-1-9 12:33 编辑

新手刚学习串口功能,现在单片机用串口2发送中文和英文字符串,
STC-ISP  串口助手,文本模式接收,
8H8K64接收的英文和中文字符都正常,
32G12K128接收的英文字符正常,中文不正常,
32G12K128程序是用"布丁橘长"大佬分享的程序修改的,
请各位前辈有空帮忙看看,是什么原因?
这是8H8K正常的程序:
#include        "STC8Hxxx.h"
#define uchar unsigned char
#define uint  unsigned int
#define UART2_BUF_LENGTH    128
uchar  TX2_Cnt;    //发送计数
uchar  RX2_Cnt;    //接收计数
bit B_TX2_Busy; //发送忙标志
uchar  RX2_Buffer[UART2_BUF_LENGTH]; //接收缓冲
void Delay_ms(uint ms)
{
          uint i;
          while( (ms--) != 0)
                        {
                                        for(i = 0; i < 1850; i++);
                        }            
}
void System_Init(void)
{               
                P_SW2 |= 0x80;        
                P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口        
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口        
}
void Uart2_Init(void)
{
                S2CON=0x10;                     //0001 0000 模式0: 1 位起始位; 8 位数据;  1 位停止位;允许接收
                AUXR |= 0x04;                                //定时器2时钟为Fosc,即1T
                T2L = 0x8f;                                         //波特率9600 24MHz
                T2H = 0xfd;                                 
                AUXR |= 0x10;                                //定时器2开始计时
    P_SW2 |= 0;         //UART2 switch to: 0: P1.0 P1.1,  1: P4.6 P4.7        
    IE2   |= 1;         //允许中断        
}
void Uart2_ISR(void) interrupt UART2_VECTOR   
{
                if(S2CON&0x01)                        //RI==1        
                                {
                                                S2CON=S2CON & 0xfe;  //串口接收中断标记需软件清零                RI = 0;
                                                RX2_Buffer[RX2_Cnt] = S2BUF;
                                                if(++RX2_Cnt >= UART2_BUF_LENGTH)   RX2_Cnt = 0;
                                }
}
void Uart2_SendChar(unsigned char Udat)
{
                S2BUF=Udat;                                    //将要发送的数据放入串口数据缓冲区
                while(!(S2CON&S2TI));        //等待发送完成
                S2CON &= ~2;                            //Clear Tx flag
}
void UART2_Send_Str(unsigned char *PBuf)
{
                while (*PBuf)                                                                                        // 字符串结束标志‘\0’前循环
                        {
                                        Uart2_SendChar(*PBuf++);                // 逐个发送字符串的字符
                        }
}
void main(void)
{
                Delay_ms(10);                        
                System_Init();                         //系统初始化
                Uart2_Init();                                //串口2初始化
                EA = 1;     
                UART2_Send_Str("STC32G UART2 Test Programme!\r\n");
                Delay_ms(10);        
                UART2_Send_Str("正常运行.txt\r\n");
                while(1)
                                {               
                                                
                                }
}
回复 送花

使用道具 举报

该用户从未签到

2

主题

15

回帖

54

积分

注册会员

积分
54
 楼主| 发表于 2024-1-8 19:38:22 | 显示全部楼层
下面是32G12K的程序,
//        @布丁橘长 2023/04/18
#include <STC32G.H>
#define MAIN_Fosc 24000000UL               
#define BRT (65536 - (MAIN_Fosc / 9600+2) / 4)                // 加 2 操作是为了让 Keil 编译器,自动实现四舍五入运算
typedef         unsigned char        u8;
typedef         unsigned int        u16;

bit busy;                                                                                        // 串口忙标志
char wptr;                                                                                // 写指针
char rptr;                                                                                // 读指针
char buffer[16];                                                        // 接收缓存,长度16

void Delay_ms(u16 ms)
{
          u16 i;
          while( (ms--) != 0)
                        {
                                        for(i = 0; i < 1850; i++);
                        }            
}
void sysini()
{
                EAXFR = 1;                                                                         // 使能访问 XFR
                CKCON = 0x00;                                                         // 设置外部数据总线速度为最快
                WTST = 0x00;                                                                // 设置程序代码等待参数,等待时间为0个时钟,CPU执行程序速度最快

                P0M1 = 0x00;P0M0 = 0x00;                // 设置P0口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P1M1 = 0x00;P1M0 = 0x00;                // 设置P1口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P2M1 = 0x00;P2M0 = 0x00;                // 设置P2口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P3M1 = 0x00;P3M0 = 0x00;                // 设置P3口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P4M1 = 0x00;P4M0 = 0x00;                // 设置P4口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P5M1 = 0x00;P5M0 = 0x00;                // 设置P5口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P6M1 = 0x00;P6M0 = 0x00;                // 设置P6口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P7M1 = 0x00;P7M0 = 0x00;                // 设置P7口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
}
void Uart2Init()                                                        // UART2初始化
{
                S2CFG = 0x01;                                                                // 串口2此位必须为1,否则可能产生不可预期后果
               
                S2CON = 0x50;                                                                // 模式1(8位数据)、接收使能
                T2L = BRT;                                               
                T2H = BRT >> 8;                                                        // 波特率对应的重装载值
                T2x12 = 1;                                                                        // 1T模式
                T2R = 1;                                                                                // 启动定时器2
                busy = 0;                                                                                // 清零忙标志
}
void Uart2Isr() interrupt 8
{
                if (S2TI)                                                                                // 发送中断标志置1时
                                {
                                                S2TI = 0;                                                                        // 清零发送中断标志
                                                busy = 0;                                                                        // 清零忙状态
                                }
                if (S2RI)                                                                                // 接收中断标志置1时
                                {
                                                S2RI = 0;                                                                        // 清零接收中断标志
                                                buffer[0] = S2BUF;                                // 接收长度1
                                }
}
void UartSend(char dat)                                // 发送字符函数
{
                while (busy);                                                                // 当串口忙时,等待
                busy = 1;                                                                                // 忙标志置1
                S2BUF = dat;                                                                // 发送数据dat
}
void UartSendStr(char *PBuf)                        // 发送字符串函数
{
                while (*PBuf)                                                                        // 字符串结束标志‘\0’前循环
                        {
                                        UartSend(*PBuf++);                                                // 逐个发送字符串的字符
                        }
}

void main(void)
{
    Delay_ms(10);                       
                sysini();                                                                                // STC32初始化设置
                Uart2Init();                                                                // 串口2初始化
                ES2 = 1;                                                                                // 使能串口2中断
                EA = 1;                                                                                        // 使能EA总中断
                UartSendStr("STC32G UART2 Test Programme!\r\n");
                Delay_ms(10);      
                UartSendStr("正常运行.txt\r\n");
                while (1)
                        {
                                       
                        }
}
32G.jpg

点评

zhp
发送汉字不正常是由于keil编译器0xfd的问题 修改为这样就可以了 printf("正\xfd常运行.txt\n"); [attachimg]32303[/attachimg]  详情 回复 发表于 2024-1-9 11:54
回复 支持 反对 送花

使用道具 举报

该用户从未签到

551

主题

9449

回帖

1万

积分

管理员

积分
13999
发表于 2024-1-8 19:45:47 | 显示全部楼层
回复 支持 反对 送花

使用道具 举报

该用户从未签到

2

主题

15

回帖

54

积分

注册会员

积分
54
 楼主| 发表于 2024-1-8 20:48:11 | 显示全部楼层
32G1.jpg 用最新版本的STC-ISP软件,还是中文不对。
回复 支持 反对 送花

使用道具 举报

  • TA的每日心情
    郁闷
    昨天 09:49
  • 签到天数: 141 天

    [LV.7]常住居民III

    20

    主题

    1078

    回帖

    2565

    积分

    金牌会员

    积分
    2565
    发表于 2024-1-9 10:02:18 | 显示全部楼层
    大概是你的编码问题把。。
    参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
    技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    郁闷
    昨天 09:49
  • 签到天数: 141 天

    [LV.7]常住居民III

    20

    主题

    1078

    回帖

    2565

    积分

    金牌会员

    积分
    2565
    发表于 2024-1-9 10:21:22 | 显示全部楼层
    如果是用了GB3212的话 还要注意keil 吞掉0xfd的问题
    参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
    技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    半小时前
  • 签到天数: 142 天

    [LV.7]常住居民III

    27

    主题

    1338

    回帖

    4173

    积分

    论坛元老

    积分
    4173
    发表于 2024-1-9 11:20:50 | 显示全部楼层
    恭喜你,踩坑了。
    "正常运行.txt\r\n"第一个字就是FD编码汉字:
    截图202401091119377158.jpg
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    16

    主题

    720

    回帖

    2568

    积分

    超级版主

    积分
    2568
    发表于 2024-1-9 11:54:14 | 显示全部楼层
    ZJJSXXD 发表于 2024-1-8 19:38
    下面是32G12K的程序,
    //        @布丁橘长 2023/04/18
    #include

    发送汉字不正常是由于keil编译器0xfd的问题
    修改为这样就可以了
    printf("正\xfd常运行.txt\n");

    截图202401091154113065.jpg

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    2

    主题

    15

    回帖

    54

    积分

    注册会员

    积分
    54
     楼主| 发表于 2024-1-9 12:30:33 | 显示全部楼层
    谢谢各位前辈,
    确实就是0xFD的编码问题引起的,
    8H8K我是用Keil4软件的,以前已经打过补丁了,所以正常,
    32G12K是用Keil5软件的,没有打过补丁,
    凑巧第1次试,就碰上了,一时就没有头绪了

    官方论坛,解决问题就是专业迅速,
    祝论坛越来越旺,
    32G系列的芯片越用越广泛。

    点评

    看好你哟~  发表于 2024-1-9 13:31
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-16 10:13 , Processed in 0.081822 second(s), 68 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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