STM8S003F使用IO口模拟串口(四)正真意义上的模拟串口

2020-01-20来源: eefocus关键字:STM8S003F  IO口  模拟串口

在前三篇文章中由简到烦的介绍了模拟串口的设计规则,但是在前三篇文章中所实现的方法并不能满足我们在实际工程中的使用。在这篇文章中,我将详细的描述模拟串口的实现,并提供相关代码来供大家参考。


1 原理

为了书写的方便,我将使用我的模版文件,关于模版文件的详细介绍请参考这篇文章。同样的,我们认为一个字节是10个位【起始位(1bit)+数据位(8bit)+停止位(1bit)】。


同样的为了方便,我们先实现发送功能再实现接收功能。为了扩大本文章所述内容的适用性,我将使用MAX3485芯片,关于这款芯片的使用方法我将进行详细介绍,同时也请参见《》。


1.1 设计逻辑

发送数据:串口调试助手1发送数据——调用模拟串口发送——模拟串口发送数据——串口调试助手2接收数据

接收数据:串口调试助手2发送数据——模拟串口接收(中断接收)——模拟串口接收数据——调用自带串口——自带串口发送数据——串口调试助手1接收数据

1.2 IO口模拟串口发送原理

空闲状态为高电平,开始位为0,然后发送8个数据位,然后是奇偶校验位,停止位为高电平。数字电路中只有0、1两种状态,这是我们用IO口可以实现的,我们认为高电平是1,低电平是0。也就是说我们用只到了IO口的输出功能(对于实现TX功能的IO口而言),那么到底发多长时间的高电平呢?这是由TIM2决定的,TIM2通过计数器实现。这个时间取决于什么呢?取决于波特率。也就是说,只要我们初始化设置好了TIM2我们就不需要考虑时间问题了。为方便我们现发送低位,然后逐渐右移来发送高位。如何判断发送完一个字节呢?我们认为10位为一个字节。如何判断发送玩所有的字节呢?我们使用一个缓存区(也就是数组)缓存区的字节发送完了我们就认为发送完了。


1.3 IO口模拟串口接收原理

发送我们可以自己来控制(也就是通过函数开相关中断),但是接收怎么处理呢?我们认为不发送的状态就是接收状态,也就是说,只要不是发送,我们接收数据的中断就是使能的。如何判断数据来了呢?我们知道起始位是高电平,因此我们只用到了IO口的输入功能(对于实现RX功能的IO口而言),我们在初始化状态下设置此IO口为低电平,只要IO口接收到了高电平我们就会知道。我们是怎么知道的呢?因为这时会产生一个IO外部中断,所以我们就可以进入中断函数来操作了。进入IO外部中断函数之后我们就开启TIM2的比较捕获中断来判断接下来的8个位是什么电平。开启比较捕获中断后我们就进入的比较捕获中断函数,在这个函数中我们判断IO口的位来给我们的接收字节变量赋值。当接收了10位以后(起始位的时候就开始计数了)我们就认为接收了1个字节。当接收了8个字节的时候我们就可以放入我们的缓存区(数组),接收字节容量的大小根据缓存区的大小来决定。我们接收制定的大小以后,我们就可以在更新中断函数里面写相关的操作代码了,我们这里写的是调用自带串口发送数据。




2 实现过程

同样的,在实现过程中,我们在工程文件夹SimUART中共分了4个文件夹

System:存放系统文件;

Project:存放项目文件;

User:存放main.c和UserApp.c;

My_Lib:存放其它常用的文件。



根据我们将用到的单片机的资源,我们在My_Lib中分了5个文件夹,分别是:

Time:与定时器和中断相关函数的文件。

SimUART:与模拟串口相关函数的文件。

USART:与串口相关函数的文件(因为我们需要串口进行测试)。

EXTI:与中断相关函数的文件,我们用到中断初始化。

MAX3485:我们用到MAX3485芯片。



下面我贴出相关函数的.c文件,而.h文件省略不写,有需要的同学可以点击下载使用。我的编程环境是IAR,需要自己建立IAR工程。下面详细介绍(Project和System省略不写,其中System只用了stm8s.h)。


2.1 一切从main()函数开始

同样的,我们建立完工程后需要从main()函数开始,我们使用的是模版工程(大家可以点击查看设计思路),所以我们main.c不需要做任何改动,我们从初始化开始。


2.2 初始化

初始化相关代码如下:


/************************************************* 

*Function: All_Config

*Calls: void

*Called By: main.c

*Input: void

*OUTPUT: void

*Return: void

*DESCRIPTION: 1.初始化函数

                2.选择内部16M晶振

*Others: nothing

*************************************************/

void All_Config()

{

    //必备初始化

    Clock_Config();      //时钟初始化 

    PilotLED_Init();                //初始化指示灯 

    TIM4_Init();        //定时器4初始化

    

    

    //常规初始化

    UART_Init(SYS_CLOCK, 9600); //串口初始化

    MAX3485_Init();                  //485通讯

    

    //功能初始化

    /*****************************************

    1.模拟串口

    *****************************************/

    SimUART_IO_Init();        //模拟串口IO口初始化

    TIM2_Init();                    //定时器2初始化

    EXTI_Init();                    //中断初始化

}

我们的指示灯使用的是TIM4来控制,所以需要初始化TIM4。如果不需要485通讯可以把这里的485初始化去掉。其他的不说,我下面只介绍模拟串口的初始化功能,其他请参见代码。根据原理我们知道,我们需要用到TXD管脚的输出功能和RXD管脚的输入功能,具体代码如下:

/********************************************************* 

*Function: IO_Init

*Calls: void

*Called By: All_Config

*Input: void

*OUTPUT: void

*Return: void

*DESCRIPTION: 1.模拟串口IO口初始化(RX:PC3  TX:PC4)

                2.用到的模拟串口IO口的初始化PC4:发送 PC3:接收

                3.使用不同的IO口作为模拟串口的时候,我们在使

                  用中断(这里使用的TIM2)需要选用不同的中断向量。

*Others: nothing

*********************************************************/

void SimUART_IO_Init()

{

    /************************************

    1.模拟串口IO口初始化

    2.PC4:发送

    3.PC3:接收    

    ************************************/

    //TXD:TXD位推挽输出  PC4

    SimUART_PORT->ODR |=  SimUART_PIN_TX;

    SimUART_PORT->DDR |=  SimUART_PIN_TX; 

    SimUART_PORT->CR1 |=  SimUART_PIN_TX; 

    SimUART_PORT->CR2 &= ~SimUART_PIN_TX;  

    //RXD:悬浮输入 高电平 PC3

    SimUART_PORT->IDR |=  SimUART_PIN_RX; 

    SimUART_PORT->DDR &= ~SimUART_PIN_RX; 

    SimUART_PORT->CR1 &= ~SimUART_PIN_RX; 

    SimUART_PORT->CR2 &= ~SimUART_PIN_RX; 

}



2.3 模拟串口发送数据

完成时钟、定时器、中断的初始化以后我们就可以开始主体程序的设计了,逻辑伪代码如下:

void SimUART_TxByte( u8 SendData )

{

    将发送数据放入缓存区;

    缓存区待发送计数++;

    缓存区放满了 就不放了;

    开启发送 相关的中断;

}

 

void SimUART_TxBytes(const u8* SendData , u8 len )

{

    //循环添加,直到添加完毕

    while( len )

    {

        将发送数据放入缓存区;

        需要添加的计数--;

        需要发送的数据的指针++;

        缓存区待发送计数++;

        缓存区放满了 就不放了;

    }

    

    开启发送 相关的中断;

}


具体实现代码如下:

/*************************************************

*Function: SimUART_TxByte

*Input: u8 SendData:需要发送的字节

*OUTPUT: void

*DESCRIPTION: 发送一个字节

*************************************************/

void SimUART_TxByte( u8 SendData )

{

    TxDataBuf[SimUART_SendBuf_IN] = SendData;

    SimUART_SendBuf_IN++;

    

    //缓存区放满了 就不放了

    if( SimUART_SendBuf_IN >= sizeof(TxDataBuf) )

    {

        SimUART_SendBuf_IN = 0;

    }

    

    //开启发送 相关的中断

    TIM2->IER |= TIM2_IER_UIE;      //更新中断使能

}

 

 

/*************************************************

*Fu

[1] [2] [3]
关键字:STM8S003F  IO口  模拟串口 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic486238.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机引脚与端口,引脚和GPIO的区别
下一篇:STM8 IO口模拟串口通信

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8S003F3 选项字
STM8S003F3 GPIO功能复用的设置,有两种办法,一种是程序烧录可参考本类中最近文章,另一种是SWIM方法,在IAR中直接设置。现将这种方法的步骤介绍如下:1. 在IAR中进入download / debug模式2. 点击ST-LINK选项3. 修改对应的选项字选择对应的选项字,右键点击选择STM8S003F3选项字功能如规格书描述如下:
发表于 2020-02-20
STM8S003F3 选项字
STM8S103F3实现串口中断接,中断发功能
;   }  }}UART1_CR2 |= 0x80; //直接开启发送中断}需要发送的数据串,调用此发送函数,将会触发中断发送服务函数,在这里说明一点,stm8s103f3这款芯片的发送中断服务函数与接收中断服务函数不是同一个,这与stm32系列的芯片不太一样,后者是发送和接收中断共用同一个服务函数,在中断向量表中可观察到不同。#pragma vector= UART1_T_TC_vector    //0x13__interrupt void SYS_UART1_TX_IRQHandler(void){  if(UART1_SR & 0x80)  { 
发表于 2020-02-17
N76E003替换STM8S003F3
有款国产mcu ne76e003据说可以pin to pin完美替换。主要信息和价格N76E003AT20和STM8S003F3P6技术指标对比STM8S003F3P6:一共20个脚,最多支持16个GPIO,支持16个外部中断;2个16位定时器[TIM1/TIM2],最多可以输出3路PWM信号;5个ADC通道,支持SPI/I2C/UART;8KBYTE FLASH,1K RAM,128 BYTE EEPROM;还有内置16M 高速振荡器,WDG等等。单从器件的性能上来看:新唐的N76E003AT20相比之下更具备经典的优势:• 1T/8051 :1T超值单片机,8051我们更熟悉的经典内核;• 18KB Flash ROM:优于
发表于 2020-02-16
N76E003替换STM8S003F3
STM8 最小开发板/核心板 STM8S003F3P6开发与设计效果
STM8S核心板 亮点:   本开发板采用MicroUSB线取电,与智能手机数据线兼容,数据线简单易得,而非USB MINI线取电, USB MINI线不好找到,已经逐渐淘汰,这是本模块区别于其他的家产品的重要特点 。   超低的价格,人性化的设计,全套的资料,让您省钱,省时,省力,省心!STM8S核心板 主要特点:1.使用STM8S003F3P6为主控IC。2.可以用板子上的2.54排针取电或是焊盘取电,使用焊盘取电时,输入电压范围在4.5V-15V,可同时通过排针向外部输出3.3V!注意:5V排针与模块的输入
发表于 2020-02-15
STM8 最小开发板/核心板 STM8S003F3P6开发与设计效果
STM8S103F3实现串口中断接,中断发功能
;   }  }}UART1_CR2 |= 0x80; //直接开启发送中断}需要发送的数据串,调用此发送函数,将会触发中断发送服务函数,在这里说明一点,stm8s103f3这款芯片的发送中断服务函数与接收中断服务函数不是同一个,这与stm32系列的芯片不太一样,后者是发送和接收中断共用同一个服务函数,在中断向量表中可观察到不同。#pragma vector= UART1_T_TC_vector    //0x13__interrupt void SYS_UART1_TX_IRQHandler(void){  if(UART1_SR & 0x80)  { 
发表于 2020-02-13
STM8s103F3p 16位定时器 STM2
/************************************************************************************/* MAIN.C file *  * Copyright (c) 2002-2005 STMicroelectronics *///16位定时器2的中断方式//周期为50ms#include "stm8s103f.h"main(){ //端口初始化 PD_DDR=0x0f; PD_CR1=0x0f; PD_CR2=0x00; PD_ODR=0x0f
发表于 2020-02-13
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved