首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何利用HC05微控制器从ATmega16蓝牙模块接收字符串

如何利用HC05微控制器从ATmega16蓝牙模块接收字符串
EN

Stack Overflow用户
提问于 2019-07-06 13:14:55
回答 1查看 632关注 0票数 0

我在接收从HC05到ATmega16的字符串时遇到了问题。我可以接收字符,但不能接收字符串。

我想用ATmega16和蓝牙模块(HC05)无线控制直流电机。我正在发送定时器OCR1A值从串行监视器应用程序到ATmega16通过HC05,但没有成功。

代码语言:javascript
运行
复制
#define F_CPU 16000000UL 
#include<string.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>

void UART_init()
{
    UCSRB |= (1 << RXEN) | (1 << TXEN);
    UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCS Z1);
    UBRRL = 0x67;
}

unsigned char UART_RxChar()
{
    while( (UCSRA & (1 << RXC)) == 0 );
    return(UDR);
}

void UART_TxChar( char ch )
{
    while( !(UCSRA & (1 << UDRE)) );  /* Wait for empty transmit buffer*/
    UDR = ch ;
}

void UART_SendString( char* str )
{
    unsigned char j = 0;

    while( j <= 2 )
    {
        UART_TxChar( str[j] );
        j++;
    }
}

int main( void )
{
    char buff[3];
    char j;
    int i = 0, k = 0;
    DDRD = (1 << PD5);

    UART_init();

    while( 1 )
    {
        buff[0] = UART_RxChar();
        buff[1] = UART_RxChar();
        buff[2] = UART_RxChar();

        j = UART_RxChar();

        if( j == '!' )
        {
            UART_SendString( buff );   // this is to check whether the atmega16 received correct values for timer or not.
            UART_SendString( "\n" );
        }
    }
}

预期的结果是,当我在串行监控应用程序中输入号码时,我应该在串行监视器应用程序上返回相同的号码。

在实际结果中,有时我会得到不同的字符,有时会出现空字符。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-07 08:04:06

字符串buff是未终止的,因此UART_SendString( buff );将发送任何垃圾信息,直到找到NUL (0)字节为止。

代码语言:javascript
运行
复制
char buff[4] = {0};

将有空间为NUL和初始化将确保buff[3]是一个NUL终结者。

或者,单独发送这三个字符,因为没有终止符,它们不构成有效的C (ASCIIZ)字符串。

除了缺少nul终止之外,您的代码还需要精确地输入表单nnn!nnn!nnn!...。如果另一端实际上是用CR或CR+LF终端发送行- nnn!<newline>nnn!<newline>nnn!<newline>...,则接收循环将失去同步。

一个更安全的解决方案是在接收到'!'字符时使用先前接收的三个字符。这可以通过多种方式来完成--对于长缓冲区来说,建议使用一个环形缓冲区,但对于三个字符,简单地改变插入一个新字符时留下的字符可能是足够有效的--例如:

代码语言:javascript
运行
复制
char buff[4] ;
for(;;)
{
    memset( buff, '0', sizeof(buff) - 1 ) ;

    char ch = 0 ;
    while( (ch != '!' )
    {   
        ch = UART_RxChar() ;
        if( isdigit(ch) )
        {
            // Shift left one digit
            memmove( buff, &buff[1], sizeof(buff) - 2 ) ; 

            // Insert new digit at the right
            buff[sizeof(buff) - 2] = ch ;
        }
        else if( ch != '!' )
        {
            // Unexpected character, reset buffer
            memset( buff, '0', sizeof(buff) - 1 ) ;
        }
    }

    UART_SendString( buff ) ;
    UART_SendString( "\n" ) ;
}

这也有一个优点,即当输入的数字小于三位数时,它将工作,并将丢弃包含非数字字符的任何序列。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56914428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档