历史上的今天
返回首页

历史上的今天

今天是:2025年03月23日(星期日)

正在发生

2020年03月23日 | 分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”

2020-03-23 来源:eefocus

日因工作关系,需要用STM8L101F3P6这款单片机用IO口模拟串行通讯,波特率2400bps,前辈同事已经写完了程序,我需要拿来研究一下该款MCU的低功耗的情况,而在调试的过程中,发现1个奇怪的问题,描述如下:


在while(1){}的循环中,无论是接收还是发送。第一次循环的收发数据都是错的,此后的循环均正确。比如:PC一个字符一个字符的发送0x01,0x02,0x03,接收到3个字符MCU就发回来,但第1次循环接收到是错误数据0x40,0xA0,0xE0,此后再循环收发均正确。。。百思不得其解,在while(1)循环内还会出这种问题?


代码如下:

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

描述:用延时法模拟串口通讯,中断方式接收

硬件:2MHz,内部默认16Mhz,8分频,STM8L101F3P6,RXD---PB7.TXD---PB4

波特率:2400

测试:上电后,分别发送0x01,0x02,0x03,3个字符。

问题:第1次循环接收到的字符不正确,但第2次以后均正确

时间:2012.07.26 于单位

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

#include "stm8l10x.h"

#include "stm8l10x_clk.h"

#include "stm8l10x_gpio.h"

 

#define RXD_IN  (GPIO_Pin_7) //RXD

#define TXD_OUT (GPIO_Pin_4) //TXD

 

unsigned char ReadBuf[64]; //接收缓冲

 

void CLK_Init(void)

{

CLK_DeInit();

CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8);

}

 

void IOInit(void)

{

GPIO_Init(GPIOA, GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3, GPIO_Mode_Out_PP_Low_Slow );

GPIO_Init(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 , GPIO_Mode_Out_PP_Low_Slow );

//2012.07.26 添加

//造成问题的原因在于此,添加下面的语句可解决问题

//串行通讯的起始位为低电平,上电之后TXD,RXD都应置为高电平

//GPIO_Init(GPIOB, TXD_OUT, GPIO_Mode_Out_PP_High_Slow);

GPIO_Init(GPIOB, RXD_IN, GPIO_Mode_In_PU_IT);

 

GPIO_Init(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 , GPIO_Mode_Out_PP_Low_Slow );

GPIO_Init(GPIOD, GPIO_Pin_0, GPIO_Mode_Out_PP_Low_Slow );

}

 

void Delay_us(unsigned int nCount) 

for (; nCount != 0; nCount--);

}

 

void Delay(u16 nCount)

{

while (nCount != 0)

{

nCount--;

}

}

 

void Delay_ms(void)

{

int i=0;

for (i=0; i<397; i++);

}

 

void SEND_1(void)

{

GPIOB->ODR |=0x10;  //PB4=1,TXD 

}

 

void SEND_0(void)

{

GPIOB->ODR &=0xEF;  //PB4=0,TXD

}

 

void WriteByte(unsigned char sdata)

{

unsigned char i;

unsigned char value=0;

 

//发送起始位

SEND_0();

Delay_us(100);//45

//发送数据位

for(i=0;i<8;i++)

{

value=(sdata&0x01);      //先传低位

if(value) 

{

SEND_1();

}

else {

SEND_0();

}  

Delay_us(88);//40

sdata=sdata>>1;

}

 

//停止位

SEND_1();

Delay_us(100); //50

}

 

unsigned char ReadByte(void)

{

unsigned char i,value=0;

 

while(1)

{

if(!(GPIO_ReadInputData(GPIOB)&0x80))

{

//等过起始位

Delay_us(100);

//接收8位数据位

for(i=0;i<8;i++)

{

value>>=1;

if((GPIO_ReadInputData(GPIOB)&0x80))

{

value|=0x80;

}

Delay_us(90);

}

Delay_us(50);

return value;

}

}

}

 

unsigned char ReadAndWrite(unsigned char *RBuf)

{

GPIO_Init(GPIOB, RXD_IN, GPIO_Mode_In_PU_No_IT); // RXD

 

RBuf[0]=ReadByte();

RBuf[1]=ReadByte();

RBuf[2]=ReadByte();

 

WriteByte(RBuf[0]);

WriteByte(RBuf[1]);

WriteByte(RBuf[2]);

return 1;

}

 

void main(void)

{

unsigned char ccc;

 

CLK_Init();

IOInit();

 

EXTI_SetPinSensitivity(EXTI_Pin_7, EXTI_Trigger_Rising_Falling);

enableInterrupts();

 

while(1)

{

ccc=ReadAndWrite(ReadBuf);

}

}


病症如下:

-----------------------------------------------------------------------------------------------------------------------------------

上电后:

此时已经能看出问题了,想想看。

-----------------------------------------------------------------------------------------------------------------------------------

发送0x01:

-----------------------------------------------------------------------------------------------------------------------------------

发送0x02:

-----------------------------------------------------------------------------------------------------------------------------------

发送0x03:

-----------------------------------------------------------------------------------------------------------------------------------

症状:

-----------------------------------------------------------------------------------------------------------------------------------

再发0x01:

-----------------------------------------------------------------------------------------------------------------------------------

再发0x02:

-----------------------------------------------------------------------------------------------------------------------------------

再发0x03:

看到这,我想应该知道问题出现在哪了吧?哈哈。

-----------------------------------------------------------------------------------------------------------------------------------

分析:


用IO口模拟串行通讯,串口通讯的起始位用低电平0表示,停止位用高电平1来表示。在没有进行数据收发的时候,要使TXD保持高电平,以便能识别出特发数据的起始位。解决办法是,上电初始化时,使TXD引脚为高电平。

-----------------------------------------------------------------------------------------------------------------------------------

病好了:

推荐阅读

史海拾趣

EMS GmbH公司的发展小趣事

EMS GmbH公司自创立之初,就专注于汽车转换器注塑件(微动开关)的研发和生产。公司投入大量资源进行技术创新,逐步积累起了一系列核心专利技术。这些技术不仅涵盖了汽车转换器注塑件生产的所有关键技术,还获得了多个国际品质管理组织机构及主流整车厂的双重、三重认证。这些专利技术的积累,使EMS GmbH公司在汽车转换器注塑件领域确立了行业领先地位。

北京人民电器厂公司的发展小趣事

随着北京人民电器产品的不断优化和升级,其生产的GM系列直流断路器在发电、输变电系统中得到了广泛应用。众多电力企业和项目都选择了北京人民电器的产品,这不仅是对其产品质量和技术水平的认可,也进一步推动了公司在电力行业的深入发展。

国炬(GOOGLL)公司的发展小趣事
可能是由于元器件参数不对称、中点电压偏离或静态工作点设置不当等原因引起。解决方法包括调整元器件参数、调整中点电压或重新设置静态工作点。
Futaba Electric Co Ltd公司的发展小趣事
可能是由于元器件参数不对称、中点电压偏离或静态工作点设置不当等原因引起。解决方法包括调整元器件参数、调整中点电压或重新设置静态工作点。
CET Technology公司的发展小趣事

CET Technology作为电力行业的领军企业,受邀参加了2023年深圳企业创新发展大会。大会上,CET展示了其在电力系统、工业与能源等领域的最新技术成果,包括电力二次智能终端、电能管理专用工业软件等。这些产品与服务均体现了CET在电力技术领域的深厚实力和创新精神。通过参加此次大会,CET不仅与业界同行进行了深入交流,也进一步提升了公司的品牌影响力和市场竞争力。

峰岹(Fortior Tech )公司的发展小趣事

随着数字化转型的深入,CET Technology紧跟时代步伐,成功研发出数字化安全生产管控平台。该平台通过整合配电、给水、电梯、消防、空调、安防等各系统,建立统一的安全物联感知平台,实现对安全生产各要素的在线监测。利用3D可视化技术,关键信息得以直观呈现,为企业的安全生产管理提供了有力支持。此外,CET还引入了AI技术,对安全风险进行精准预测,助力企业防范和应对各类安全事件。

问答坊 | AI 解惑

ccd资料包

飞思卡尔智能车上用的ccd摄像头…

查看全部问答>

SPCE061A凌阳单片机编程红外遥控

我要做基于SPCE061A凌阳单片机红外遥控比赛计分器的设计, 需要软件编程红外识别,利用LED模组能显示比分,我需要知道利用的遥控器的名称和C编程的程序。重谢,有能帮我做的可以加QQ330254876讨论,重谢。…

查看全部问答>

【开发故事】DLP投影仪:坚持20年不放弃的男人

  不多的文章,与大家分享下:你有你的开发故事么?   美国德克萨斯州最大的城市达拉斯。在这个有着牧牛和牛仔历史的城市里,一项技术宣告诞生。这项技术在很长时间里“养在深闺人未识”,甚至一度处于行将消亡的境地。然而,凭借一个 ...…

查看全部问答>

哪类应届毕业生最受欢迎? 毕业生比拼职业技能

新一轮毕业生招聘季节即将到来,今年就业形势依然严峻。用人单位不仅要求大学生学习成绩好、在校表现好,还要求各方面的综合能力强,因此——     毕业生比拼职业技能     2009年的校园招聘大战已初露端倪,一家知名人才网 ...…

查看全部问答>

那位朋友知道那里能搞到RIL.lib的源代码?

我装了Platform Builder CE 6.0 ,在CellCore文件夹下也找到了RIL层的源程序,但是我却没找到RIL.lib中函数的实现,也就是Ril.def中定义的导出函数。比如: RIL_Initialize               &nbs ...…

查看全部问答>

发个最新构思和大家讨论讨论

本人一直很喜欢下载东西,verycd.com更是天天上,还喜欢上xunlei.com找软件 而且经常成夜成夜的挂着电脑,挂着迅雷, 电费不用说, 因为用P2P硬盘都坏掉几个, 数据吞吐量大概每天2G到10G, 看电影只看DVD高清晰版的, 装软件只下完整版的, 由于做软 ...…

查看全部问答>

AT+CMGS很慢,为什么?

我用MC39i发送PDU短信,在AT+CMGS这一步的时候很慢,要3、4秒才能出现\">\",为什么呢?有什么方法加快速度吗? 我看过别人也是用MC39i,但是一般1秒之内就可以发送出去了,怎么会差这么远呢?…

查看全部问答>

100分相送,如何在dopod818 PPC上注册蓝牙串口通讯???

如题:如何在dopod818 PPC上注册蓝牙串口通讯??? 主要的目的是想让GPS通过蓝牙控制dopod818手机发送/读取短信,和读取电话本信息,现在有的手机像dopod818没有蓝牙串口服务,要自己实现注册串口服务,然后通过打开串口进行通讯和发送AT命令来实 ...…

查看全部问答>

STR912怎么清串口中断标志?keiluv3和uv4居然不一样?

UART_ClearITPendingBit函数 uv3中是 void UART_ClearITPendingBit(UART_TypeDef* UARTx, u16 UART_IT) {   /* Clear the specified interrupt */   UARTx->ICR &= UART_IT; } uv4中是 void UART_ClearI ...…

查看全部问答>