找回密码
 立即注册
查看: 31|回复: 5

stc8g1k08A 配置内部晶振后串口输出显示不正常

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-10-17 11:35:10
已绑定手机

1

主题

1

回帖

15

积分

新手上路

积分
15
发表于 昨天 11:35 | 显示全部楼层 |阅读模式
我用stc8g1k08A默认晶振,使用默认配置方式,定时器中断中,串口能正常打印输出,但是键入如下配置后,串口打印输出是乱码,什么原因啊?麻烦帮我分析下:


/***************************主函数区域****************************/
void main(void)
{
        u8 i;
//------------------选择22.1184MHZ----------加入如下6行后,定时器输出是乱码------------------       
        P_SW2=0X80;
        CLKDIV=0X02;    //0X04;
        IRTRIM=T22M_ROMADDR;
        VRTRIM=VRT20M_ROMADDR;
        IRCBAND=0X00;
        CLKDIV=0;
//----------------------------------------------------       
//        HIRCCR = 0x80; //启动内部 IRC
//        while (!(HIRCCR & 1)); //等待时钟稳定
//        CLKDIV = 4;
//        CLKSEL = 0x00; //选择内部 IRC ( 默认 )       
       
       
       
       
        io_init();

       
        delay(5);                        //等待I/O模式配置稳定
        RED=1;GREEN=1;BLUE=1;        //上电后熄灭RGB灯
        UART1_init();        //串口1初始化
  UART2_init();               

        Time0_init();        //定时计数器0初始化
        EA=1;                                        //打开单片机总中断开关EA
        TR0=1;                                //定时器0开始计时       
       

       
        delay(100);                //等待配置稳定
  printf("**************************************************\r\n");

  while(1)
        {
               
               
               
               

  if(time_1s_flag==1)
         {
                time_1s_flag=0;
                 k++;  // SendData(0xaa);
                  printf("|测试定时器0输出------------------------%d-----:\r\n ",k);
//            SendData(0xaa);
         }   

回复

使用道具 举报 送花

3

主题

1873

回帖

594

积分

等待验证会员

积分
594
发表于 昨天 11:38 | 显示全部楼层
您好,关于您在使用 STC8G1K08A 单片机时,配置内部晶振后串口输出出现乱码的问题,以下将从多个角度进行专业分析,帮助您排查问题原因。

一、问题描述总结
使用默认晶振配置时,串口输出正常;
加入如下配置代码后,串口输出乱码:
  1. c
  2. PSW2 = 0X80;
  3. CLKDIV = 0X02;   
  4. IRTRIM = T22MROMADDR;
  5. VRTRIM = VRT20MROMADDR;
  6. IRCBAND = 0X00;
  7. CLKDIV = 0;
复制代码
串口初始化代码未更改;
问题出现在定时器中断中串口打印输出异常。

二、问题可能原因分析

1. 系统时钟配置错误导致波特率偏差

串口通信依赖于准确的系统时钟(SYSCLK)和波特率设置。若您修改了系统主频(例如从默认的 11.0592MHz 改为 22.1184MHz 或其他频率),但未同步更新串口波特率寄存器的设置,则会导致串口通信速率不匹配,表现为乱码。

建议检查以下内容:
系统时钟频率是否与串口波特率计算一致;
UART初始化函数中是否使用了正确的系统时钟值;
是否使用了固定波特率除数(如使用定时器1模式2),而未根据新的主频重新计算。

2. CLKDIV 设置不当导致系统时钟分频错误

您在代码中对 CLKDIV 进行了两次写入:
  1. c
  2. CLKDIV = 0x02;
  3. ...
  4. CLKDIV = 0;
复制代码

这可能导致系统时钟分频系数被覆盖,实际运行频率与预期不符。

建议:
确认 CLKDIV 的最终值是否符合预期;
CLKDIV = 0x02 表示系统时钟为 SYSCLK/3,CLKDIV = 0 表示 SYSCLK/1;
确保在设置完 CLKDIV 后没有被意外修改;
推荐将 CLKDIV 的设置放在最后,避免被其他配置影响。

3. IRTRIM / VRTRIM 配置不当导致时钟精度下降

您使用了:
  1. c
  2. IRTRIM = T22MROMADDR;
  3. VRTRIM = VRT20MROMADDR;
复制代码

这两个寄存器用于校准内部时钟频率。但需注意:
T22MROMADDR 和 VRT20MROMADDR 是否为芯片内部预存的校准值;
是否在使用前确认了该芯片支持该频率的校准值;
如果校准值不正确或未启用内部高频时钟(HIRC),可能导致系统时钟不稳定或频率不准。

建议:
确保 IRTRIM 和 VRTRIM 的值是芯片出厂校准值;
可以通过示波器测量系统时钟引脚(如使用 XTAL 引脚作为时钟输出)来验证实际主频;
若不确定校准值是否正确,可尝试使用默认高频 IRC(HIRC)进行测试。

4. CLKSEL 未设置导致时钟源选择错误

您注释掉了以下代码:
  1. c
  2. // HIRCCR = 0x80; //启动内部 IRC
  3. // while (!(HIRCCR & 1)); //等待时钟稳定
  4. // CLKDIV = 4;
  5. // CLKSEL = 0x00; //选择内部 IRC ( 默认 )
复制代码

这部分代码是标准的时钟初始化流程,用于选择内部高频时钟源并等待其稳定。

问题可能在于:
您设置了 CLKDIV 和 IRCBAND,但未明确设置 CLKSEL 来选择当前使用的时钟源;
若未正确切换时钟源,可能导致系统运行在错误的时钟上,进而影响串口波特率和定时器中断时间。

建议:
在设置完时钟相关寄存器后,明确设置 CLKSEL 以选择正确的系统时钟源;
建议在设置完所有时钟配置后添加延时或等待时钟稳定标志。

三、推荐调试步骤

步骤 1:确认系统主频是否设置正确

可通过以下方式验证:
使用定时器测量一个已知时间(如 1ms);
或使用示波器测量定时器中断的输出频率;
或通过串口输出一个固定频率的调试信息(如每秒输出一次 "Hello");
若输出频率明显不一致,说明系统时钟设置有误。

步骤 2:检查串口波特率配置是否匹配当前主频

例如,若使用定时器1生成波特率:
  1. c
  2. TH1 = TL1 = 256 - (SYSCLK / 12 / 32 / BAUD);
复制代码

请确认 SYSCLK 是否与当前主频一致(如 22.1184MHz)。

步骤 3:逐步注释时钟配置代码进行排查

逐一注释以下代码,观察串口是否恢复正常:
  1. c
  2. PSW2=0X80;
  3. CLKDIV=0X02;   
  4. IRTRIM=T22MROMADDR;
  5. VRTRIM=VRT20MROMADDR;
  6. IRCBAND=0X00;
  7. CLKDIV=0;
复制代码

以确定是哪一行配置导致了问题。

四、优化后的配置建议

以下是一个推荐的配置流程(假设目标系统时钟为 22.1184MHz):
  1. c
  2. PSW2 = 0x80;         // 解锁寄存器
  3. CLKDIV = 0;           // 不分频,系统时钟为 IRC 主频
  4. IRTRIM = T22MROMADDR; // 设置 IRC 校准值
  5. VRTRIM = VRT20MROMADDR;
  6. IRCBAND = 0x00;       // 选择 IRC 频段
  7. CLKSEL = 0x00;        // 选择内部 IRC 为系统时钟源
  8. PSW2 = 0x00;         // 锁定寄存器
复制代码

同时确保在串口初始化时使用正确的系统时钟值。

五、总结

| 可能原因 | 是否排查 | 建议操作 |
|----------|----------|-----------|
| 波特率配置不匹配 | ✅ | 检查串口初始化代码中的 SYSCLK 和波特率计算 |
| CLKDIV 设置错误 | ✅ | 确认最终 CLKDIV 值是否与预期一致 |
| IRTRIM / VRTRIM 值不正确 | ✅ | 确认是否为芯片出厂校准值 |
| 未设置 CLKSEL 导致时钟源错误 | ✅ | 明确设置 CLKSEL 选择系统时钟源 |
| 未等待时钟稳定 | ✅ | 增加延时或等待 HIRCCR 稳定标志 |

六、结语

STC8系列单片机的时钟系统较为灵活但也复杂,建议在配置时严格按照数据手册流程操作,尤其是时钟切换和校准步骤。若您方便提供串口初始化函数和定时器中断函数,我可以进一步分析是否存在其他潜在问题。

如需进一步协助,请提供以下信息:

1. 串口初始化函数;
2. 定时器中断服务函数;
3. 实际使用的系统主频和波特率;
4. 使用的开发环境(如 Keil、SDCC)和编译器版本。

祝您调试顺利!

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:534
  • 最近打卡:2025-10-17 09:22:01
已绑定手机

48

主题

2279

回帖

8026

积分

论坛元老

积分
8026
发表于 昨天 12:09 | 显示全部楼层
你的串口波特率发生器参数是按照22.1184MHz计算出来的吗?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-10-17 11:35:10
已绑定手机

1

主题

1

回帖

15

积分

新手上路

积分
15
发表于 昨天 13:06 | 显示全部楼层
#define FOSC 11059200UL     //系统外部时钟频率(无符号长整型)
#define BAUD 9600           //欲配置的串口通信波特率值
//   串口波特率发生器参数是按照11.0592MHz计算出来的
/****************************************************************/
//串口1初始化函数UART1_init(),无形参,无返回值
/****************************************************************/
void UART1_init(void)
{
        SCON=0x50;        //8位数据,可变波特率,允许接收
        AUXR|=0x40;        //定时器1时钟为Fosc,即1T
        AUXR&=0xFE;        //串口1选择定时器1为波特率发生器
        TMOD&=0x0F;        //设定定时器1为16位自动重装方式
        TL1=(65536-(FOSC/4/BAUD));   //设置波特率重装值
  TH1=(65536-(FOSC/4/BAUD))>>8;//设置波特率重装值
        ET1=0;                        //禁止定时器1中断
        TR1=1;                        //启动定时器1
  ES=1;                                //使能UART中断开关ES
  EA=1;                                //使能单片机总中断开关EA
}
截图202510171305001956.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:587
  • 最近打卡:2025-10-18 00:13:35
已绑定手机

86

主题

6294

回帖

1万

积分

超级版主

积分
11796
发表于 昨天 21:30 | 显示全部楼层
检查时钟和波特率设置是否匹配
截图202510172129557319.jpg
截图202510172130119219.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:541
  • 最近打卡:2025-10-18 08:44:28

33

主题

2606

回帖

5749

积分

论坛元老

积分
5749
发表于 12 小时前 | 显示全部楼层
还有一件事,CLKDIV一般ISP软件会给你配置好,软件上虽然写得是IRC的配置,实际上配置的结果已经是分频之后的时钟了,除非你自己清楚的明白,CLKDIV应该怎么改,否则就不要去操作他
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-18 23:42 , Processed in 0.123439 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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