最近在使用STM8S003F模拟串口发送数据,网上资源很多,但是没有找到我需要的,因此自己写一篇文章,做一个总结,这篇文章主要是不用库函数实现发送简单的过程。
1、串口通信原理和模拟串口发送数据的原理
标准串口数据格式为:起始位(1bit)+数据位(8bit)+校验位(1bit)+停止位(1bit)。其中起始位为低电平,停止位为高电平。
串口通讯需要设置波特率和检查COM口。
思路是这样的,我们使用定时器TIM2来定时,每隔一端时间发送一个位,从而实现模拟串口发送数据。
2、获得定时器ARR自动装载的值
为了简便,我们不要校验位,因此共有10个位的数据。
我以stm8中9600bit/s的波特率计算的过程为例(1秒钟传输9600位)。
可以计算出传输1位所需要的时间 T1 = 1/9600 约为104us。
stm8 内部晶振频率为16M,我采用16分频也就是1M,故MCU震荡周期为 1/1M = 1us。
由上面的计算我们可以知道要发送一位数据,定时器中定时的自动装载的值应设为为 104/1 =104。
3、实现过程
在实现过程中,我们在工程文件夹SimUART中共分了4个文件夹(分别为System:存放系统文件;Project:存放项目文件;User:存放main.c和UserApp.c;My_Lib:存放其它常用的文件)。根据我们将用到的单片机的资源,我们在My_Lib中分了三个文件,分别是——Delay:存放与延时函数相关的文件;IO:存放与IO口相关函数的文件;Time:与定时器相关函数的文件。下面我贴出相关函数的.c文件,而.h文件省略不写,有需要的同学可以根据文章后面的网址下载使用。我的编程环境是IAR,需要自己建立IAR工程。MARK,以后介绍。下面详细介绍(Project和System省略不写,其中System只用了stm8s.h)。
3.1、一切从main.c开始
首先,在main.c中我们需要对用到的单片机的资源进行初始化。我们将其写在All_Config()【在UserApp.c中】函数内,代码如下:
//head file
#include "UserApp.h"
#include "IO.h"
#include "User.h"
#include "Time.h"
//初始化函数
void All_Config( void )
{
Clock_Config();
IO_Init();
TIM2_Init();
}
其中User.h是我将自己常用的宏写在了一个文件里面,对应于main.c。
在没有接外部时钟的时候,STM8S003F在启动时主时钟默认为HSI RC时钟的8分频,我们这里的初始化仅指定为16MHZ高速内部RC振荡器(HSI),也可以省略不写,Clock_Config()【在UserApp.c中】函数代码如下:
//初始化时钟 选择内部16M晶振
void Clock_Config()
{
CLK->CKDIVR &= ~( BIT(4) | BIT(3) );
}
我选择单片机的PD2作为我的模拟串口的数据发送口,IO_Init()【在IO.c中】函数代码如下:
//head file
#include "IO.h"
#include "User.h"
void IO_Init()
{
//TXD:TXD位推挽输出 PD2
UART_PORT->ODR |= UART_PIN_TX; //0000 0000
UART_PORT->DDR |= UART_PIN_TX; //0000 1000
UART_PORT->CR1 |= UART_PIN_TX; //0000 1000
UART_PORT->ODR &= ~UART_PIN_TX;
UART_PORT->ODR |= UART_PIN_TX;
}
其中在IO.h中的宏定义为:
#define UART_PORT GPIOD
#define UART_PIN_TX 0X04 // PD2
#define UART_PIN_RX 0X08 // PD3
下面是定时器的初始化,在使用定时器的时候我们分为以下几步:
a、选择定时器,我们选择TIM2;
b、定时器的时钟分频(注意要看是使用的默认8分频还是有更改),我开始没有分频,需要16分频;
c、填充定时器自动装载的值,我这里是104;
d、开启定时器;
注意计数器CNTR上电自动为0,我们还是清零一下,使用的自动装载寄存器后,自动重装载寄存器决定了定时器的上溢时机,当定时器的计数器中数值达到了自动重装载寄存器规定的值,计数器就要归零。也就是说自动重装载寄存器决定了定时器的周期。
在这篇文章介绍的模拟串口发送数据的方法中并没有使用中断。TIM2_Init()【在TIM2.c中】函数代码如下:
//head file
#include "TIM2.h"
#include "User.h"
void TIM2_Init()
{
CLK->PCKENR1 |= CLK_PCKENR1_TIM2; //TIM2 enable
TIM2->PSCR = 0x04; //16分频 1MHZ 1us
TIM2->ARRH = 104 >> 8; //自动装载 每52us复位一次TIM2
TIM2->ARRL = 104; //每1us递减1
TIM2->CNTRH = 0;TIM2->CNTRL = 0;
TIM2->CR1 |= TIM2_CR1_CEN; //开启定时器}
完成初始化以后,我们应该写发送程序,为了简单的发送,我们选择发送0x55,因为它在示波器中显示方波。我们在UserApp.c中写我们的实现我们的模拟串口的发送。
发送数据的规则是:
a、共10位数据(因此需要16为的数据,8位是不行的),由于我们发送的数据是8位,所以有一个转换的过程;
b、先发低位,再发高位;
c、在发送函数中有时间延时代码,保证没法每一次数据都是一个计数时间(即完成一次104计数)
发送函数SimUART_TxByte()【在UserApp.c中】代码如下
void SimUART_TxByte( u8 SendData )
{
static u16 Send_All = 0;
static u8 BitNum = 0; //位计数
Send_All = SendData;
Send_All = ( Send_All << 1 ) | 0X0200; //需要发送的10个位的数据
TIM2->CNTRH = 0;
TIM2->CNTRL = 0;
TIM2->SR1 &= ~TIM2_SR1_UIF;
//先发低位,再发高位
for( BitNum = 0; BitNum<10 ; BitNum++ )
{
if( Send_All & 0X0001 ) //如果是高电平,发高电平
{
UART_PORT->ODR |= UART_PIN_TX;
}
else //如果是低电平,发低电平
{
UART_PORT->ODR &= ~UART_PIN_TX;
}
Send_All >>= 1; //右移一位
//等待波特率时间
while( (TIM2->SR1 & TIM2_SR1_UIF) == 0 );
TIM2->SR1 &= ~TIM2_SR1_UIF;
}
}
其中UART_PIN_TX为IO.c中的宏定义。
3.2、补全main()函数
完成上面的代码之后我们可以测试一下,下面我们完成main()函数,代码如下:
//head file
#include "User.h"
#include "UserApp.h"
#include "Delay.h"
int main( void )
{
char Test = 0;
//char Test = 0x55; //测试数据
All_Config(); //初始化
while(1) //发送循环
{
SimUART_TxByte( Test++ );
Delay_50000(); //延时,防止数据过多
}
//return 0;
}
在0x55发送正确之后,我们发送0x00到0xFF,若波特率不正确将会出现发送不连贯的现象。为了防止数据过多,我们需要一个延迟函数,Delay_50000()【IO.C中】函数代码如下:
//Head file
#include "Delay.h"
void Delay_50000()
{
int a,b;
for( a=0 ; a<100 ; a++ )
{
for( b=0 ; b<500 ; b++ );
}
}
4、结束语
至此我们使用IO口模拟串口(未使用库函数)发送数据的功能已经实现,相关代码可以移步下面的地址下载使用,欢迎大家和我一起学习和交流。
上一篇:STM8S单片机串口调试
下一篇:stm8s中UART的用法(四种UART中断)
推荐阅读最新更新时间:2024-11-08 15:52
设计资源 培训 开发板 精华推荐
- DER-637 - 35 W 高功率因数、隔离式反激式开关式谷填充 PFC LED 驱动器
- NCP1608BOOSTGEVB:100 W 升压评估板
- ADP7142CP-EVALZ、LFCSP 评估板,用于评估 ADP7142 40V、200mA 低噪声、CMOS LDO
- OP295GSZ方波振荡器的典型应用,无论电源如何变化,频率稳定
- 使用符合 EN55022 A 类(双输出)EMC 滤波的 RP40-4812SFR DC/DC 转换器的典型应用
- NCP1094GEVB:PoE-PD 接口控制器评估板
- 使用灌/源电压调节器创建虚拟接地
- 使用 Silicon Labs 的 SI3400 的参考设计
- TS1115 550MA低压差正可调稳压器典型应用电路
- 使用 Analog Devices 的 LTC2925CUF 的参考设计
- 科学家研发基于AI的身份验证工具 可保护车辆免受网络攻击威胁
- Microchip推出广泛的IGBT 7 功率器件组合,专为可持续发展、电动出行和数据中心应用而设计
- 面向未来驾驶体验 博世推出新型微电子技术
- 英飞凌与马瑞利合作 利用AURIX™ TC4x MCU系列推动区域控制单元创新
- 5C超充,该怎么卷?
- 《2025年度中国汽车十大技术趋势》正式揭晓!你最看好哪个?
- Microchip推出新型VelocityDRIVE™软件平台和车规级多千兆位以太网交换芯片,支持软件定义汽车
- 英特尔中国正式发布2023-2024企业社会责任报告
- can转485数据是如何对应的
- MCU今年的重点:NPU和64位