43866|37

7815

帖子

57

TA的资源

裸片初长成(中级)

楼主
 

【stm8s003系列例程】2 基本串口收发(中断接收方式) [复制链接]

 
本帖最后由 辛昕 于 2014-1-4 18:40 编辑

对于串口而言,最基本的就是 收发。
因为本例程系列及我个人的风格,我总是只让例程的功能——同时也就纯粹到 只展示这个功能的最小配置和最少代码。

而对我而言,串口 收发(1字节——因此也就不涉及另外 对 收发的缓冲处理 等 实质上 和 串口基本功能无关的 代码)。
当然大多数时候,我接收都是中断方式,而发送则无此必要——但是,我知道,在对速度有要求或者需要并行处理的场所,还需要 发送中断,但这个比较少用,因此不考虑。

下面是代码。
在贴以前,我讲一些对相关库,代码的改动。

首先,stm8s这个库,它的stm8s_uart1.c里,在计算波特率时,它需要获取当前时钟频率
它采用的是 CLK_GetClockFreq();
这个函数定义在stm8s_clk.h里
然而,在这里,它并没有包含这个头文件——我知道,它是想模仿C标准库,保证内部的十几个库之间不存在互相包含关系。
很可惜它犯了错误。

因为我做这个串口例程时始终错误,我走了不少弯路,最后想起来查对相关寄存器,发现这个波特率BRR1 BRR2从来就没正常过。
而对比我此前的105例程却是可以的。(因为我此前也改动过,而我却忘了,也没有记录下来。)

也许在某些编译器上可以允许这种错误,但是调用和返回不会出错,但是这种对具体环境的依赖绝对是 除了找死还是找死。

其次,采用 CLK_GetClockFreq() 这个函数获取系统时钟,也有不妥当之处。
因为这个函数依赖一个外部宏,那就是 HSE_VALUE;
因为事实上,STM8S内部没有真正可以用于采样获取时钟频率的硬件。
它只不过是通过 寄存器(对HSI LSI),以及这个 HSE_VALUE宏来确定频率。

我们都知道,如果我希望把这个库单独封装,那么,对外部晶振频率这种随时会变化的环境,采用宏写入库,那将是一个大麻烦。

因此这个地方是造成这个 库无法单独封装 的又一个障碍。

我暂时没想到太好的办法。
但显然,这个地方是一个隐患。

过后也许会考虑比较单纯的,采取单独增加填写 BRR1 BRR2寄存器的函数,或者想办法把外部晶振频率传递入库,让它可以获得真正的 实际频率。

注:以上两处,涉及 库 以及 CLOCK部分,而这两部分我先前已经发过贴,我会把这些内容同步更新到那两个贴里。
此帖出自编程基础论坛

最新回复

楼主大神,我是编程小白一个,最近在学习STM8S003,看你这个接收中断,不应该进入中断接收完一个字节再清中断标志么,还有连续发送的时候不应该计数么,看了网上很多串口代码都感觉不是很好~~也许是我没看懂!   详情 回复 发表于 2019-9-27 11:41

赞赏

1

查看全部赞赏

点赞 关注(3)
个人签名

强者为尊,弱者,死无葬身之地

 

回复
举报

7815

帖子

57

TA的资源

裸片初长成(中级)

沙发
 
  1. //这是 主要的调用 串口模块 的函数,包含 由 main调用的测试函数(in while-loop)
  2. #include "stm8s_uart1.h"
  3. #include "Uart1.h"
  4. #include "stm8s_clk.h"

  5. U8 RecvByte = 0;   
  6. U8 RecvFlag = 0;

  7. void FillRecvByte(U8 byte)
  8. {
  9.    RecvByte = byte;
  10. }

  11. int isUart1Received(void)
  12. {
  13.     return RecvFlag;
  14. }

  15. void clearUartReceivedFlag(void)
  16. {
  17.     RecvFlag = 0;
  18. }

  19. void setUartReceivedFlag(void)
  20. {
  21.     RecvFlag = 1;
  22. }


  23. void Uart1_Initial(void)
  24. {     
  25.     UART1_DeInit();
  26.     UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, \
  27.                UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
  28.    
  29.     UART1_ITConfig(UART1_IT_RXNE, ENABLE);
  30.     UART1_Cmd(ENABLE);
  31. }

  32. void Uart1_Send1Byte(U8 TxData)
  33. {
  34.       while(UART1_GetFlagStatus(UART1_FLAG_TXE) == 0);
  35.       UART1_SendData8(TxData);  
  36. }

  37. void Uart_Recv_Trans_BasicTest(void)
  38. {
  39.      while(1)
  40.      {
  41.           if(RecvFlag)
  42.           {
  43.              RecvFlag = 0;
  44.              Uart1_Send1Byte(~RecvByte);
  45.           }
  46.      }
  47. }
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

板凳
 
  1. // 接着是简单的 串口接收中断 服务程序
  2. #include "typedef.h"
  3. #include "Uart1.h"
  4. #include "stm8s_uart1.h"

  5. #include "stm8s_it.h"

  6. INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17)
  7. {}

  8. INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
  9. {
  10.     UART1_ClearITPendingBit(UART1_IT_RXNE);   
  11.     FillRecvByte(UART1_ReceiveData8());
  12.     setUartReceivedFlag();
  13. }
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

4
 
  1. // 最后是简单的main函数
  2. #include "stm8s.h"
  3. #include "Uart1.h"

  4. void main(void)
  5. {   
  6.     Uart1_Initial();
  7.     __enable_interrupt();
  8.     Uart_Recv_Trans_BasicTest();
  9. }

  10. // end of file -----------------------------------------------------------------
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

5
 
不得不感慨:
对于这种不专业的库,假如我们按照对专业的库的期待,真的会被玩死的。
比如说,这个系统时钟,考虑就如此不完善(依赖宏HSE_VALUE)
另一个不专业的地方就是,这个库处处显示出它很难单独封装,因为各种对外部的依赖,不好意思,上述这个例子仍然适用于此。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

6
 
stm8只能进入一次中断,下次发送数据就接收不到了
此帖出自编程基础论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

7
 
ST这颗MCU真垃圾。
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

8
 
月亦无恨 发表于 2014-5-15 17:38
stm8只能进入一次中断,下次发送数据就接收不到了
怎么了?
是不是因为没有清除对恰当的标志位

代码弄上来看看
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

9
 
这颗MCU倒不垃圾。
其实也挺不错的。
但要就某些单项相比,比如 抗电磁能力 ,别说ST,没几个能和LPC FREESCALE比。
类似的,这也是个事实。

关于MCU硬件方面的东西我本人不太懂,倒是听说综合起来也是比较弱的一个,但欧美系到底是欧美系。还是很可以的。

至于代码这些附加的部分,就算了。
家家都差不多。
这事情类似骂手机,你骂三星,有人骂小米——我在办公室里有天中午,大家把主流手机都骂了个遍,包括苹果。

所以,还是自己来吧,至少软件还是可以自己来的。

此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

10
 
辛昕 发表于 2014-12-31 16:00
怎么了?
是不是因为没有清除对恰当的标志位

代码弄上来看看


没有清除中断标记

此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

11
 
哦,原来是这样。
解决了就好。


此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

12
 
为什么发送 1 ,却受到L了
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

13
 
错失流年 发表于 2015-8-22 15:02
为什么发送 1 ,却受到L了

什么意思
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

14
 
GOOD
此帖出自编程基础论坛
 
 
 

回复

23

帖子

0

TA的资源

一粒金砂(中级)

15
 
你好,我最近刚上手STM8,用的是STM8S003,在论坛中看过你对这款单片机的见解,我遇到一些问题能否帮忙解决一下,在我使用STM8S003 AD的时候采样转换值一直为0,搞不懂哪里出来问题,不知道这种情况你有遇到吗?打扰之处还请谅解,谢谢。
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

16
 
zxcm 发表于 2016-3-20 11:02
你好,我最近刚上手STM8,用的是STM8S003,在论坛中看过你对这款单片机的见解,我遇到一些问题能否帮忙解决 ...

你还真的挺锲而不舍的。
不用回两次的,我都会看到的。

那个,我很久没用stm8了。
说到这个问题,我觉得,你可以考虑两件事

1.首先确定硬件上是有电压的。这个简单,拿个万用表。
注意量的时候,是要对ADC的电源和地,我记得stm8s003似乎是没有特定的一组ADC的电源和地的,你自个看看引脚,如果有,要注意这些地方。
这是硬件上的。

2.软件上的,先不要自己写程序,用例程来跑跑,如果硬件上有点哑,例程跑了也有,那就对比你的程序和它的程序。
假如例程都没有,那这事,八九成就是硬件问题了。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

301

帖子

2

TA的资源

一粒金砂(中级)

17
 
不要用getclk吧,配置的晶体还能来回变么?
此帖出自编程基础论坛
 
 
 

回复

23

帖子

0

TA的资源

一粒金砂(中级)

18
 
辛昕 发表于 2016-3-21 00:25
你还真的挺锲而不舍的。
不用回两次的,我都会看到的。

那个,我很久没用stm8了。
说到这个问题,我 ...

好的,谢谢
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

19
 

那个,记得下次别这么锲而不舍了啊乖~~
虽然这个帖子已经死了,但我还是活的好好的。

此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

20
 
dwdsp 发表于 2016-3-21 08:16
不要用getclk吧,配置的晶体还能来回变么?

这,不晓得你怎么突然说这个。
其实说起来,stm32也好,啥啥MCU也好,还没先进到配备了一个真的能测量实际运行时钟频率的外设。
所以他们基本也都是 一个宏写的实际外接晶振值。
然后配合寄存器的设置,看分了多少频,倍了多少频。
以及使用了外部源还是内部源,是通过这种方式计算出来结果的。

所以,getclk也没啥问题,反正就是个计算过程。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表