- STM8S103F3P6上的串行通信
- STM8S103F3P6上的串行通信引脚
- STM8S串行通信电路图
- 设置STVD进行串行通信
- 编程STM8S以进行串行通信
- 通过串行监视器控制LED
- STM8S串行库更深入的了解
由于采用了新的寄存器处理方法,并且不知道确切的位是什么,因此对新的微控制器进行编程通常会花费较长的时间。不用说,调试也是如此。这就是为什么程序员经常在代码中使用断点并使用调试器逐步执行断点的原因。但是使用调试器可能需要额外的硬件(多数时候是昂贵的)和额外的时间。作为Arduino的忠实粉丝,我们都可以同意的一件事是使用串行打印语句进行调试,并且了解我们的代码会使工作变得更加轻松。使用cosmic C编译器和SPL库,我们可以在STM8上复制相同的内容吗?好吧,这很有可能,而这正是我们在本系列教程的第三篇教程中要做的。如果您是此处的新手,还可以查看STM8S(教程1)和STM8S GPIO控制(教程2)入门。此外,我们还探索了使用Arduino对STM8S进行编程以快速入门的可能性。话虽如此,让我们进入教程。
STM8S103F3P6上的串行通信
从STM8S103F3P6的数据表中,我们可以看到我们的8位控制器以许多不同的模式支持UART通信。该控制器还具有用于同步UART通信的时钟输出引脚,并且还可以支持SmarCard,IrDA和LIN。但是,在本教程中,我们将不会探索任何一种方法,只是为了避免复杂性。我们将学习如何进行简单的UART读写。
本教程还提供了一个名为 stm8s103 serial.h 的头文件,使用该头文件可以执行简单的UART命令,例如“串行开始”,“串行读取”,“串行打印”等。基本上,您可以将char,int和string打印到串行监视器上。并从串行监视器读取char。在本教程的最后,您将能够从串行监视器控制LED并获取有关LED状态的反馈。上面提到的头文件取决于SPL库,因此请确保您已遵循入门教程。
STM8S103F3P6上的串行通信引脚
让我们从硬件方面开始。快速浏览下面给出的STM8S103F3P6微控制器的引脚,我们可以看到引脚1、2和3将用于UART通信。
在这三个引脚中,引脚1是UART时钟引脚,该引脚仅在同步UART通信期间使用,因此在此不再需要它。引脚2是UART发送器引脚,引脚3是UART接收器引脚。请注意,这些引脚还可以兼作模拟引脚或普通GPIO引脚。
STM8S串行通信电路图
这里的电路图非常简单,我们需要连接ST-LINK 2进行编程,并连接一个USB至TTL转换器以读取串行数据。请注意,我们的STM8S控制器工作在3.3V逻辑电平,因此请确保您的USB到TTL转换器也支持3.3V逻辑。完整的电路图如下所示。
您必须在笔记本电脑的一个USB端口中连接ST-link,在另一个USB端口中连接USB-TTL转换器,以便您可以同时编程和监视数据。 UART连接非常简单,只需将STM8S微控制器的地线和Rx / Tx引脚连接到USB至TTL转换器的Tx / Rx引脚即可。在这里,我使用ST-Link的Vcc引脚为控制器供电,而TTL转换器的vss引脚保持断开状态,您也可以采用其他方法。市场上有很多类型的USB到TTL转换器,只要确保它可以在3.3V逻辑信号上运行并简单查找Tx,Rx和GND引脚并进行上面所示的连接即可。我的硬件设置如下所示。
为了进行串行通信,我们提供了 STM8S_Serial.h 头文件。使用此头文件,您可以执行简单的类似于Arduino的功能进行串行通信。
您可以在我们的STM8S103F3_SPL Github页面上找到该项目的所有必需文件。如果仅需要此特定的头文件,则可以从以下链接下载它。
下载STM8S_Serial.h
设置STVD进行串行通信
为了进行串行通信,我们将使用前面讨论的 STM8S_Serial.h 头文件功能。但是该库还具有其他依赖性,其中包括许多与SPL UART和Clock相关的标头和C文件。因此,从这一点出发,最好将所有标头和C文件包括到我们的项目中,以避免编译错误。我的STVD工作环境如下所示。
确保像我们在第一个教程中一样,包含了所有SPL源文件和包括文件。还要确保您已添加 stm8s103_serial.h 头文件。此标头没有C文件。
编程STM8S以进行串行通信
准备好STVD项目设置后,我们就可以开始在 main.c 文件中编写代码了。本教程的完整代码可以在本页底部找到。解释如下。
第一步是包括所需的头文件,在这里,我添加了刚刚下载的主头文件(stm8s)和 stm8s_103_serial 头文件。
//必需的标头#include“ STM8S.h” #include“ stm8s103_serial.h” //https://github.com/CircuitDigest/STM8S103F3_SPL/blob/master/stm8s103%20Libraries/stm8s103_Serial.h
接下来,我们使用设计宏来指定输入和输出引脚。这里将仅控制连接到端口B的引脚5的板上LED,因此我们将其命名为 test_LED 。
#define test_LED GPIOB,GPIO_PIN_5 //测试LED连接到PB5
继续在主要功能内部,我们将引脚定义为输出。如果您不熟悉GPIO的基本功能,请回到STM8S GPIO教程。
//引脚偏移//将PB5声明为推挽输出引脚GPIO_Init(test_LED,GPIO_MODE_OUT_PP_LOW_SLOW);
然后,我们以9600波特率初始化串行通信端口。对于新手,9600是通信期间传输数据位的速度。如果在此处设置9600,则还必须在监视软件上进行设置。然后,我们还打印一个字符串“ Enter command”,然后移至下一行。
Serial_begin(9600); //以9600的波特率初始化串行通信Serial_print_string(“ Enter command”); //打印一个字符串Serial_newline(); //移动到下一行
转到无限while循环,我们使用 Serial_available 函数检查是否有任何传入的串行数据。如果是,我们将其读取并保存到名为ch的变量中,并使用 Serial_print进行 打印。然后,如果接收到的值为0,我们将关闭LED,如果为1,我们将打开LED
if(Serial_available()){Serial_print_string(“您已按下:”); ch = Serial_read_char(); Serial_print_char(ch); Serial_newline(); 如果(ch =='0')GPIO_WriteHigh(test_LED); //如果(ch =='1')GPIO_WriteLow(test_LED),则LED熄灭; //带领 }
至此,本教程的编程已完成,只需上载此页面底部给出的代码,您就应该能够从串行监视器控制LED。
通过串行监视器控制LED
上载代码后,您可以以9600波特率打开任何串行监视器。为了方便使用,我已经使用了Arduino串行监视器。按重置按钮,您应该看到消息“输入命令”。然后,如果您输入1并按Enter,则板上的led应该打开,对于0同样,它应该关闭。
可以在本页底部的链接视频中找到完整的工作。如有任何疑问,请将其留在评论部分。您还可以使用我们的论坛来发布其他技术问题。
STM8S串行库更深入的了解
对于那些想知道 STM8S103F3_Serial 头文件内部实际发生什么的好奇的人,请继续阅读…。
该头文件对于初学者级编程非常有效,但是,如果您使用的是STM8S控制器的不同版本或正在寻找一些高级选项,则可能需要对该头进行一些调整或直接使用SPL库。我是从UART1头文件开始编写该头文件的,我对头文件的解释如下。
从串行监视器读取字符
此功能有助于读取已从串行监视器发送到微控制器的单个字符。
char Serial_read_char(void){while(UART1_GetFlagStatus(UART1_FLAG_RXE)== RESET);复制代码 UART1_ClearFlag(UART1_FLAG_RXNE); 返回(UART1_ReceiveData8()); }
我们一直等到RXE标志被置位以完成接收,然后清除该标志以确认接收。最后,我们发送接收到的8位数据作为此功能的结果。
将字符打印到串行监视器
此功能将单个字符从微控制器传输到串行监视器。
void Serial_print_char(char值){UART1_SendData8(value); 而(UART1_GetFlagStatus(UART1_FLAG_TXE)== RESET); //等待发送}
该函数仅写入8位值,并通过将 UART1_FLAG_TXE 设置为SET来等待传输完成。
初始化串行通讯
该功能以所需的波特率初始化串行通信。
void Serial_begin(uint32_t baud_rate){GPIO_Init(GPIOD,GPIO_PIN_5,GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(GPIOD,GPIO_PIN_6,GPIO_MODE_IN_PU_NO_IT); UART1_DeInit(); //取消初始化UART外设UART1_Init(baud_rate,UART1_WORDLENGTH_8D,UART1_STOPBITS_1,UART1_PARITY_NO,UART1_SYNCMODE_CLOCK_DISABLE,UART1_MODE_TXRX_ENABLE);//(BaudRate,Wordlegth,StopBits,奇偶校验,SyncMode,模式)UART1_Cmd(ENABLE); }
除波特率外,还需要为串行通信设置其他参数,例如数据位数,停止位数,奇偶校验等。最常见的参数(类似于Arduino)是8位数据一个停止位且没有奇偶校验,因此这将是默认设置。您可以根据需要进行更改。
将整数打印到串行监视器
大多数时候,如果我们使用串行监视器进行调试或监视,我们可能希望将int类型的变量打印到串行监视器。这个功能确实做到了
void Serial_print_int(int number)//将int值打印到串行监视器的功能{char count = 0; char digit =“”; while(number!= 0)//将int拆分为char数组{digit = number%10; 数++; 数字=数字/ 10; } while(count!= 0)//以正确的方向打印char数组{UART1_SendData8(digit + 0x30); 而(UART1_GetFlagStatus(UART1_FLAG_TXE)== RESET); //等待发送计数-; }}
它接受一个整数值,并在第一个while循环中将其转换为字符数组,然后在第二个while循环中,我们将发送类似于print char函数的每个字符。
打印新行
这是打印新行的简单功能。要做的十六进制值为“ 0x0a”,我们只是使用8位发送命令将其发送出去。
无效Serial_newline(void){UART1_SendData8(0x0a); 而(UART1_GetFlagStatus(UART1_FLAG_TXE)== RESET); //等待发送}
将字符串打印到串行监视器
另一个有用的功能是在串行监视器上实际打印字符串。
void Serial_print_string(字符字符串){。char i = 0; while(字符串!= 0x00){UART1_SendData8(string); 而(UART1_GetFlagStatus(UART1_FLAG_TXE)== RESET); i ++; }}
同样,此函数还将字符串转换为char数组并发送每个字符。众所周知,所有字符串end将为null。因此,我们只需要继续遍历和传输字符,直到到达空0x00。
检查是否可以读取串行数据
此功能检查缓冲区中是否有任何可供读取的串行数据。
bool Serial_available(){if(UART1_GetFlagStatus(UART1_FLAG_RXNE)== TRUE)返回TRUE; 否则返回FALSE;}
它检查标志 UART1_FLAG_RXNE ,如果为true,则返回true,否则为false。