×
嵌入式 > 技术百科 > 详情

STM8 普通IO配置模拟串口输出

发布时间:2024-05-18 发布时间:
|

刚接到上级的需求,由于stm8的串口资源较少,需要在原来工程的基础上加多一个io来输出串口数据。串口在每个学习单片机的人来说都是耳熟能详的东西。没有串口基础的同学建议先去学习串口知识点再来阅读。


首先我们知道串口数据配置里面包含:波特率、流控、数据起始位、数据位、奇偶校验位、停止位。针对本人经常选的配置为:

数据起始位默认都是1。数据实体如下:

由于本人选用波特率为115200 bps ,通过计算器算出每发送一位需要8.68us。这是一个非常低延时的值,这时候就要考虑写一个高精度的短延时的函数。那么问题来了,现在每次一个语句都是以微秒为单位的,任何写多一个语句和写少一个语句都会影响到这个延时函数,计算起来相当复杂。(去年自己写过高精度延时函数,但是是针对stm8在时钟频率是2mhz,且函数参数单位是1.5us的,但是最小延时只能是21us,无法把延时降到8.68us左右当时写出这个延时函数花费1-2天的时间去测试和验证,测试起来比较繁琐和麻烦)


为了更快更有效的完成这个需求,本人采取扫描方式来找到自己想要的延时时间。前提要先写好io模拟串口驱动,本人在stm8平台上对PD3做串口输出。


普通io模拟串口驱动分别写在了一个c文件和h文件中:


.C:


#include "analog_uart.h"

uint16_t ANALOG_TICK_N = 1;// 115200bps:18 ,9600bps:270

void analog_uart_init(void) { //初始化

GPIO_Init(TXD_PORT, TXD_PIN,GPIO_MODE_OUT_PP_HIGH_FAST);

}

inline void bxxx_delay(void) { //延时值作为波特率需要的延时时间函数

for(uint16_t i = 0; i < ANALOG_TICK_N ; ++i) {

asm("nop");

}

}

static inline void TXD_Write(uint8_t i) { //io 输出高或低电平

if(i == 0) {

TXD_PORT->ODR &= (uint8_t)(~TXD_PIN);

} else {

TXD_PORT->ODR |= (uint8_t)TXD_PIN;

}

}

static void sent_byte(uint8_t byte) { // 模拟串口输出1个字节

uint8_t i = 8;

TXD_Write(0);

bxxx_delay();

while(i--) {

TXD_Write((uint8_t)(byte&0x01));

bxxx_delay();

byte = byte >> 1;

}

TXD_Write(1);

bxxx_delay();

}

void analog_uart_sent_data(uint8_t * data,uint16_t size) { // 模拟串口输出字符串

uint16_t i = size;

while(i--) {

sent_byte(*data);

++data;

bxxx_delay();

}

}

void print_tick_num(void) { //打印延时值出来,通过应用端对延时值做递增,在串口助手查找延时值

uint8_t buf[10] = "N:";

uitoa(ANALOG_TICK_N,(char *)buf+2);

analog_uart_sent_data(buf,strlen((char *)buf));

}

/***

* Description : 将无符号整数转为字符串.

* Arguments : val 待转换的整数.

* str 转换后字符串储存的数组指针.

* Returns : 返回转换后的指针.

* Caller : Application.

* Notes : None.

*******************************************************************************

*/

static char* uitoa(uint32_t val, char *str)

{

uint32_t power,j;

char *p = NULL;

if (str != NULL)

{

p = str;

j = val;

for (power = 1; j >= 10; j /= 10)

{

power *= 10;

}

for (; power > 0; power /= 10)

{

*p++ = '0' + val / power;

val %= power;

}

*p = '


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实时控制.安全.如何加速实现未来工厂落地?