14494|19

327

帖子

1

TA的资源

纯净的硅(初级)

楼主
 

STM32F103RC UART1奇怪的BUG [复制链接]

 
本帖最后由 shipeng 于 2018-4-16 09:23 编辑

我在main函数中int main(void)
{
    RCC_Configuration();
    BKP_Init();
   delay_init();
   NVIC_Configuration();
   uart_init(115200);
   USART_SendData(USART1,0xFF);//这条可以成功发出。
   delay_ms(1000);
   USART_SendData(USART1,0xFF);//1秒延时之后紧跟着发的这条0xFF发不出来!!!
   while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
   USART_SendData(USART1,0xFF);//这条可以成功发出。
   while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    while(1)
    {
        IWDG_ReloadCounter();

     }
}
以下是相关函数的详细信息:
void delay_init()         
{

#ifdef OS_CRITICAL_METHOD
        u32 reload;
#endif
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //HCLK/8
        fac_us=SystemCoreClock/8000000;        //1/8  
         
#ifdef OS_CRITICAL_METHOD
        reload=SystemCoreClock/8000000;   
        reload*=1000000/OS_TICKS_PER_SEC;
                                                        //reload  
        fac_ms=1000/OS_TICKS_PER_SEC;
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
        SysTick->LOAD=reload;
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;           //SYSTICK   
#else
        fac_ms=(u16)fac_us*1000;
#endif
}                                                                    

void delay_ms(u16 nms)
{                                    
        u32 temp;                  
        SysTick->LOAD=(u32)nms*fac_ms;
        SysTick->VAL =0x00;
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
        do
        {
                temp=SysTick->CTRL;
        }
        while(temp&0x01&&!(temp&(1<<16)));
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
        SysTick->VAL =0X00;                 
}

void uart_init(u32 bound){

    GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
         
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
         USART_DeInit(USART1);
         //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //USART1_RX          PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

   //USART 3õê¼»ˉéèÖÃ

        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE);

}

请教大家为何会有一个字节发不出来?
此帖出自stm32/stm8论坛

最新回复

因为平常写东西,不是用库就是封装成函数,所以可能就过去了。 这个问题,最大的问题就是忘了一句话—— 在发送以前要先检查确认当前处在闲状态。 别的,都不重要   另外就是,有些单片机的串口 写完成状态是需要手动清除的。   详情 回复 发表于 2023-8-31 12:23
点赞 关注
个人签名模电临时工
 

回复
举报

379

帖子

3

TA的资源

一粒金砂(高级)

沙发
 
第一次发送少了
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
此帖出自stm32/stm8论坛

点评

第一次发送后延时1秒,肯定发送完了。问题是我注释掉第一条“ USART_SendData(USART1,0xFF);”中间那条也还是发不出来,实在摸不着头脑  详情 回复 发表于 2018-4-16 09:29
 
 

回复

373

帖子

0

TA的资源

纯净的硅(中级)

板凳
 
首先确定1秒的延时函数写的是不是有问题
此帖出自stm32/stm8论坛

点评

延时函数我也有在下方给出没有做UART的相关操作。  详情 回复 发表于 2018-4-16 09:31
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

4
 
wenyangzeng 发表于 2018-4-14 14:06
第一次发送少了
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

第一次发送后延时1秒,肯定发送完了。问题是我注释掉第一条“ USART_SendData(USART1,0xFF);”中间那条也还是发不出来,实在摸不着头脑
此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

5
 
wudayongnb 发表于 2018-4-14 20:27
首先确定1秒的延时函数写的是不是有问题

延时函数我也有在下方给出没有做UART的相关操作。
此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复

369

帖子

0

TA的资源

一粒金砂(中级)

6
 
路过看看,顶一下
此帖出自stm32/stm8论坛
 
个人签名充放电数显全套方案,双口快充慢充检测电流电压,两线三线直流电压表,配套三个8尺寸15*8MM带AV电流电压单位专利数码屏,资料QQ2981074992 邮箱同上
 
 

回复

875

帖子

1

TA的资源

纯净的硅(高级)

7
 
原理不应该是这样的,因该首先是串口把数据接收过来,然后再把数据发送到上位机显示出来
此帖出自stm32/stm8论坛
 
 
 

回复

875

帖子

1

TA的资源

纯净的硅(高级)

8
 
这根本不是什么BUG而是你没有搞懂串口发送的原理而已,你好好看看串口通信机制,就应该没问题了
此帖出自stm32/stm8论坛

点评

教训的好  详情 回复 发表于 2018-4-16 18:52
 
 
 

回复

525

帖子

235

TA的资源

版主

9
 
楼主问题解决了吗?
这是想往上位机发送三个0xff的意思嘛?
调试的时候设置断点观测程序执行到底哪里出问题,你这样的表述并不是很清晰。
此帖出自stm32/stm8论坛

点评

没有解决啊,这个不是上位机这个是通过串口读一个模块里面信息,需要先发一串命令数据帧到模块RXD但是现在由于第一个字节发不出来导致帧头出错,如果在帧头字节前面加一个无意义的字节则可以解决问题,当然这个无意  详情 回复 发表于 2018-4-16 18:56
 
个人签名爱电子,爱生活
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

10
 
曹伟1993 发表于 2018-4-16 10:55
这根本不是什么BUG而是你没有搞懂串口发送的原理而已,你好好看看串口通信机制,就应该没问题了

教训的好
此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

11
 
wsdymg 发表于 2018-4-16 15:28
楼主问题解决了吗?
这是想往上位机发送三个0xff的意思嘛?
调试的时候设置断点观测程序执行到底哪里出问 ...

没有解决啊,这个不是上位机这个是通过串口读一个模块里面信息,需要先发一串命令数据帧到模块RXD但是现在由于第一个字节发不出来导致帧头出错,如果在帧头字节前面加一个无意义的字节则可以解决问题,当然这个无意义的字节就发不出来了
此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复

58

帖子

0

TA的资源

一粒金砂(中级)

12
 
什么乱七八槽的。。。我给你例子,自己看,你那代码懒得看
void USART3_Init(void)  
{  
        GPIO_InitTypeDef GPIO_InitStructure;  
        USART_InitTypeDef USART_InitStructure;  

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

        GPIO_StructInit(&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

        GPIO_StructInit(&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init( GPIOC, &GPIO_InitStructure);

        GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3) ;
        GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3) ;

        USART_InitStructure.USART_BaudRate = 921600;  
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
        USART_InitStructure.USART_StopBits = USART_StopBits_1;  
        USART_InitStructure.USART_Parity = USART_Parity_No;  
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
        USART_Init(USART3, &USART_InitStructure);  

        USART_Cmd(USART3, ENABLE);

        USART3_NVIC_config();
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}

void USART3_SendByte(uint8_t ch)
{
        while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET)
                ;
        USART_SendData(USART3, ch);
}
此帖出自stm32/stm8论坛

点评

有个问题,我跟你的发送步骤不一样,你是先判断USART_FLAG_TXE再写发送数据: void USART3_SendByte(uint8_t ch) { while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET) ;  详情 回复 发表于 2018-4-18 10:42
 
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

13
 
chuck_pz 发表于 2018-4-17 19:00
什么乱七八槽的。。。我给你例子,自己看,你那代码懒得看
void USART3_Init(void)  
{  
        GPI ...

有个问题,我跟你的发送步骤不一样,你是先判断USART_FLAG_TXE再写发送数据:
void USART3_SendByte(uint8_t ch)
{
        while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET)
                ;
        USART_SendData(USART3, ch);
}
我是先写发送数据再判断USART_FLAG_TXE标志位:
USART_SendData(USART1,0xFF);//这条可以成功发出。
   while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
我的考虑是如果是上电首次发送,先判断USART_FLAG_TC标志位会不会始终是RESET因为之前没有发送动作,从而陷入死循环?但是存在即合理你这么做应该有验证的吧。
此帖出自stm32/stm8论坛

点评

你不会单步看下寄存器是什么状态啊!!! 我那个都用过很多次了  详情 回复 发表于 2018-4-18 11:32
 
个人签名模电临时工
 
 

回复

58

帖子

0

TA的资源

一粒金砂(中级)

14
 
shipeng 发表于 2018-4-18 10:42
有个问题,我跟你的发送步骤不一样,你是先判断USART_FLAG_TXE再写发送数据:
void USART3_SendByte(uin ...

你不会单步看下寄存器是什么状态啊!!!
我那个都用过很多次了
此帖出自stm32/stm8论坛

点评

我这种写法就是这个少发一个字节的问题,貌似和我的写法没有关系。我现在有个临时方案解决了少发一个字节的问题:在要发送前加入一个假发送动作也就是随便发一个字节实际这个字节无法发出但是紧随其后的就是我实际要  详情 回复 发表于 2018-4-18 13:48
 
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

15
 
chuck_pz 发表于 2018-4-18 11:32
你不会单步看下寄存器是什么状态啊!!!
我那个都用过很多次了

我这种写法就是这个少发一个字节的问题,貌似和我的写法没有关系。我现在有个临时方案解决了少发一个字节的问题:在要发送前加入一个假发送动作也就是随便发一个字节实际这个字节无法发出但是紧随其后的就是我实际要发送的数据。
此帖出自stm32/stm8论坛

点评

串口这东西简单啊,你这搞法不靠谱。。。  详情 回复 发表于 2018-4-18 20:35
 
个人签名模电临时工
 
 

回复

58

帖子

0

TA的资源

一粒金砂(中级)

16
 
shipeng 发表于 2018-4-18 13:48
我这种写法就是这个少发一个字节的问题,貌似和我的写法没有关系。我现在有个临时方案解决了少发一个字节 ...

串口这东西简单啊,你这搞法不靠谱。。。
此帖出自stm32/stm8论坛
 
 
 

回复

365

帖子

3

TA的资源

纯净的硅(初级)

17
 

你没认真看好用户手册,你的代码里不能用延时来代替读状态位清除TC标志的

  因为你没清TC,所以你在写入DR时才清除TC标志,所以那一次的写入无效,当写入后,清了TC,紧接着写入的数据才有效。

此帖出自stm32/stm8论坛

点评

道理是这个道理,那么多年前的老帖子我也不记得当初为啥要纠结这个小问题  详情 回复 发表于 2023-8-30 21:51
 
 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

18
 
hjl2832 发表于 2023-8-20 20:33 你没认真看好用户手册,你的代码里不能用延时来代替读状态位清除TC标志的  因为你没清TC,所以你在写 ...

道理是这个道理,那么多年前的老帖子我也不记得当初为啥要纠结这个小问题

此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

19
 

因为平常写东西,不是用库就是封装成函数,所以可能就过去了。

这个问题,最大的问题就是忘了一句话——

在发送以前要先检查确认当前处在闲状态。

别的,都不重要

 

另外就是,有些单片机的串口 写完成状态是需要手动清除的。

此帖出自stm32/stm8论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

327

帖子

1

TA的资源

纯净的硅(初级)

20
 
辛昕 发表于 2023-8-31 12:23 因为平常写东西,不是用库就是封装成函数,所以可能就过去了。 这个问题,最大的问题就是忘了一句话&mda ...

此帖出自stm32/stm8论坛
 
个人签名模电临时工
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表