找回密码
 立即注册
查看: 1546|回复: 18

STC8H8K64U-LQFP32串口2发送不了,也进不了中断,诚心求教

[复制链接]

1

主题

8

回帖

89

积分

注册会员

积分
89
发表于 2024-7-17 12:54:24 | 显示全部楼层 |阅读模式
以前只弄过一段时间模拟电路,对C语言和单片机的了解还是很久很久以前的事了。目前没啥事,闲着,想捡起来重新学习一下单片机,还没学几个月,很多地方一知半解,小白白。
最近尝试着用STC8H8K64U-LQFP32做一个简单的控制板,大概思路就是扫描按键、结合ADC分析,然后输出几个继电器。后来想着把几个模拟量用一个专门的IC去测量,STC8H就只定期用串口2读取这个测量IC的数据就可以了,各司其职。
前期的按键、LCD、ADC都在开发板和洞洞板调试通过了,最后遗留这个测量IC,封装比较小不好用洞洞板手焊,就直接打了几个样,想着最后来调试这个串口2。
好了,猜对了,理所当然的,就是这个串口2搞不定了,真是个忧伤的故事。忧伤啊!
这个也是我个人的短板,以前从没接触过通信方面的东西,折腾了几天,搞不定了,厚着脸皮上来求教。
已经考虑了下次打样换个方案,直接用STC8H测量所有的ADC,但有点不死心,因为这次这点问题都放弃了,后面肯定还要碰到类似问题。可能我认为绕不过的问题,在大佬眼中就是一句话的事。
谢谢了!
谢谢各位大佬帮我看看下面的程序。基本上是拷的手册的范例或者ISP串口小工具计算器。
程序运行到串口2发送字节的时候,就卡住了,不进中断,也就没办法给busy清零,可能:意味着发送没有完毕,没有进入中断,或者发送失败,一直发送中?
因为至少要发送2个字节,就算busy初始为0,发送了第一个字节后,如果不进中断清零,第二个字节就会卡在while(busy);

目前尝试过的有,没办法了,瞎折腾了:

1、改变中断优先级,设为最高3级。
2、外置上拉10K电阻装上或者扒掉。
3、定时器开启、打开中断全部都放在初始化函数,或者放在其他地方
4、调整Uart2Send()中三条语句的顺序
5、buffer[4]数值长度调整
6、示波器探P1.1发现有定期循环的脉冲组

7、P1.0一直有高电平,无脉冲波形
8、尝试去掉busy
9、去掉所有的不相干的程序和功能,只留这个串2来测试

10、打了4块样,每一个都一样的情况,软件没问题的话,那就是硬件设计有误了。功能比较简单,就是简单的输入输出控制,STC部分直接拷的官版建议电路,对面的测量IC也是官版电路。因为本来就是打样回来测试的板在,所以该有的电阻电容官版建议的玩意一个不少。除了电压正负,两个IC之间就只有串口2根线了。
如果硬件有误的话,怎么测试判断呢?


typedef unsigned char u8;
typedef unsigned int u16;   
typedef unsigned long u32;
#define READ_ERROR 0

//IO定义部分,封成一个小函数,放在public
        P_SW2 |= 0x80;  //扩展寄存器XFR访问使能

      P0M0 = 0x00;      P0M1 = 0x00;   
      P1M0 = 0x00;      P1M1 = 0x00;
      P2M0 = 0x0e;   P2M1 = 0x00;        //P2.1,P2.2,P2.3推挽   
    P3M1 = 0x00;   P3M0 = 0x00;   
    P4M1 = 0x00;   P4M0 = 0x00;   
    P5M1 = 0x00;   P5M0 = 0x00;   
    P6M1 = 0x00;   P6M0 = 0x00;  
    P7M1 = 0x00;   P7M0 = 0x00;   
        
      P_SW2 |=0x00;        //设置串口2为P1.0,P1.1   
     P1PU = 0x02;         //本来P1.0,P1.1两个都做了10K上拉,现在调试没过,全扒了,对方的串口输出有上拉
        
     P2DR &= ~0x0e;     //P2.1,P2.2,P2.3强推挽

//全局变量、数组定义
u8 buffer[4];        //缓存返回的4字节数据
bit busy=0;
u8 wptr;

void Uart2_Init(void)    //串口2初始化。4800bps@11.0592MHz
{
    S2CON = 0x90;        //D0,90都不影响我的忧伤。S2SM0模式1,9位数据可变波特率,REN置1可接受数据。B6为空,0xD0(1101 0000)或者0x90(1001 0000)
    T2L = 0xC0;        
    T2H = 0xFD;            //设置定时初始值
    IP2H=0x01;
    IP2=0x01;        //串口2为最高优先级。设不设都不影响我搞不定。
    busy=0;
    wptr = 0x00;
    AUXR |= 0x04;        //1T模式。04,10合体也无法让心情好转
    AUXR |= 0x10;        //定时器2开始计时,T2R置1,T2_C/T置0,用作定时器
}

void Uart2Isr() interrupt 8 //串口2中断函数
{
    if (S2CON & 0x02)        //检测串口2发送完成中断请求标志S2TI是否置1
    {
        S2CON &= ~0x02;        //S2TI清零
        busy=0;                    //挺闲的
    }
   
    if (S2CON & 0x01)            //检测串口2接收完成中断请求标志S2RI是否置1
    {
        S2CON &= ~0x01;        //S2RI清零
        buffer[wptr++] = S2BUF;        //把接收的数据依次放入数组   
        wptr &= 0x03;        //限定4字节长度,避免溢出。
    }   
}

void Uart2Send(u8 dat)    //发送1个字节
{        
    while(busy);                //出问题的地方。会一直卡在此处循环,不进中断给busy清零,意味着发送没有完毕?没有进入中断?此处应该插个斗志昂扬的BGM循环播放。
    busy=1;   
    S2BUF=dat;            //此条放哪里都改变不了结局,欧耶!
}

u32 read_IC_dat(u8 address)
{   
    u8 CMD=0;        
    u8 CHECKSUM=0;
    u32 read_value=0;   
    CMD=0x7F&address;        //CMD的B7置0,其余不变   
   
    Uart2_Init();        //串口2初始化
    IE2 = 0x01;            //ES2置1,允许串行口2中断,ET2置0,禁止T2中断,其余全部置0禁止
    EA=1;                        //打开总中断

    Uart2Send(0x6A);     //发送HEAD字节
    Uart2Send(CMD);        //发送命令   
    delay_ms(5);        //延时,等待接收数据,放在buffer数组。要不要延时都不行。
   
    CHECKSUM=~(0x06A+CMD+buffer[0]+buffer[1]+buffer[2]);//校验计算
    if(CHECKSUM==buffer[3])        //buffer[3]为接收到的校验和
    {
        read_value=(buffer[0]<<16)|(buffer[1]<<8)|buffer[2];
        return read_value;
    }
    else return READ_ERROR;
}

void main(void)//主函数
{
    //略
    //主函数就是循环扫描IO口输入按键和ADC,输出几个继电器控制,并定时通过串口2读取IC值到LCD显示,并辅助MCU判断和警告。
}



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-7-17 13:04:38 | 显示全部楼层
没有时间阅读你长篇大论的错误代码

以下是我写的串口收发框架,实测稳定可靠,供参考
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4598

截图202407171304345176.jpg

DebugLab
回复 支持 反对

使用道具 举报 送花

1

主题

8

回帖

89

积分

注册会员

积分
89
发表于 2024-7-17 13:10:44 | 显示全部楼层
Debu*** 发表于 2024-7-17 13:04
没有时间阅读你长篇大论的错误代码

以下是我写的串口收发框架,实测稳定可靠,供参考

好的,感激答复,我下载学习一下
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2024-7-17 13:13:53 | 显示全部楼层
看您使用了ADC
STC8H8K64U有DMA支持ADC,可以自动累加超采样,以下内容供参考:


https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=2537&pid=19963


截图202407171313499994.jpg

DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-7-17 13:17:08 | 显示全部楼层
看着好像没啥问题,,上个最简出错的工程吧,,这款单片机我们也在用,,估计你别的什么地方有问题,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

1

主题

8

回帖

89

积分

注册会员

积分
89
发表于 2024-7-17 13:17:47 | 显示全部楼层
Debu*** 发表于 2024-7-17 13:13
看您使用了ADC
STC8H8K64U有DMA支持ADC,可以自动累加超采样,以下内容供参考:

已经用了STC的ADC功能,很好用,已测试通过。早知道我应该全部用STC的ADC口的,正计划改。
目前遇到的串口2问题我要先学习一下

点评

用DMA  发表于 2024-7-17 13:19
回复 支持 反对

使用道具 举报 送花

1

主题

8

回帖

89

积分

注册会员

积分
89
发表于 2024-7-17 13:24:37 | 显示全部楼层
_奶*** 发表于 2024-7-17 13:17
看着好像没啥问题,,上个最简出错的工程吧,,这款单片机我们也在用,,估计你别的什么地方有问题, ...

是的,电路板需要实现的功能很简单的,硬件更简单。特别是串口这部分,就直接拷的手册的范例,现在搞不定了,也不知道哪里出问题了。也是想让大佬们帮我看看软件的部分。如果都觉得没问题,我就想办法做别的测试。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-7-17 13:28:18 | 显示全部楼层
xwl*** 发表于 2024-7-17 13:24
是的,电路板需要实现的功能很简单的,硬件更简单。特别是串口这部分,就直接拷的手册的范例,现在搞不定 ...

不愿意发工程的话 你就照着官方的例程改吧  软件资源 里面有STC8H8K64U试验箱的例程。。
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:213
  • 最近打卡:2025-04-23 20:59:03
已绑定手机

36

主题

560

回帖

1885

积分

荣誉版主

积分
1885
发表于 2024-7-17 14:38:49 | 显示全部楼层
自从用了STC官方的板子以后,我重新适应STC8(以前没用过),然后基本官方库函数有的,我都用库函数来写,辅助看手册,这样相对效率高一些。
正好前几天写完了串口的基础功能,贴出来希望能帮到你。
我实现了串口1-4中断接收,阻塞发送,PC发来的内容,串口收到后再发送出去。
主程序:
回答1.jpg

然后是串口将接收到的内容发送回去,使用官方例程,会有丢帧的情况发生。
所以我自己重新改了:
回答2.JPG

然后是串口初始化:
回答3.JPG

最后是串口中断:
回答4.JPG


这个是我自己已经验证过的,你可以参照修改直接使用。
为什么不直接发例程,自己参考的过程中,把代码敲一遍,按照思路引导,看看自己的问题出在哪,能记住。
现成的东西放在那,更不可能能学会。

你也可以做一些测试,用你自己的函数,先发一个字符,再发一个字符串,然后收字符串,然后收发字符串,先把串口基础调通,
这样,接着无论是要收还是发,都知道自己要干什么,要干什么就得先做什么。
不然现成的例程你没有吃透,永远需要问,永远学不会。
希望能帮到你。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:213
  • 最近打卡:2025-04-23 20:59:03
已绑定手机

36

主题

560

回帖

1885

积分

荣誉版主

积分
1885
发表于 2024-7-17 14:50:05 | 显示全部楼层
最主要的你的串口初始化啊,发送那个IC dat啊,感觉好奇怪
做个标志位,采集到了通过串口发就行了,平时就让串口闲着,或者当标志位为0的时候把串口当作心跳包来用,都可以。
代码还是要实现低内聚高耦合,而不是什么东西都随处用。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 08:56 , Processed in 0.132244 second(s), 113 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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