20120726-分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”
来源:互联网 发布:网络管理专业 编辑:程序博客网 时间:2024/04/30 15:51
近日因工作关系,需要用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)//TXDunsigned 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);//40sdata=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); // RXDRBuf[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引脚为高电平。
-----------------------------------------------------------------------------------------------------------------------------------
病好了:
- 20120726-分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”
- 51单片机IO口模拟串口通讯C源程(详细分析)
- 51单片机IO口模拟串口通讯C源程
- 51单片机IO口模拟串口通讯C源程序
- 20120725-51单片机IO口模拟串口通讯4
- 20120725-51单片机IO口模拟串口通讯5
- 20120725-51单片机IO口模拟串口通讯6
- 51单片机IO口模拟串口通讯3-中断法
- 51单片机IO口模拟串口通讯2-计数法
- 51单片机IO口模拟串口通讯1-延时法
- 51单片机IO口模拟串口通讯4
- 51单片机IO口模拟串口通讯5
- 模拟串口的实现--单片机IO口
- 20120725-51单片机IO口模拟串口通讯1-延时法
- 20120725-51单片机IO口模拟串口通讯2-计数法
- 20120725-51单片机IO口模拟串口通讯3-中断法
- STM32 IO口模拟串口通讯
- 两个单片机串口通讯IO口串电阻
- openssl简介-指令x509
- fastreport.net每页合计
- 《匆匆那年》-第二卷 喜欢
- 树形菜单复选框级联选择
- A*算法详解
- 20120726-分析解决“STM8L101单片机IO口模拟串口通讯发生的奇怪现象”
- windows过滤驱动程序设计入门(驱动程序基本结构,设备栈,IRP栈和工作原理)
- 位域应用——大小端模式对union体的影响的反思。
- The /proc File System
- 算法设计与分析课程Part1笔记(2)
- 《匆匆那年》-第三卷 过往
- Winform中显示Office文档(word,EXCEL,PPT)
- Dive Into Python 学习记录3-getattr 介绍/过滤列表/and or/lambda 函数
- 系统健壮性的思考