Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AVR C串行通信:打印号码固定按钮_C_Putty_Avr - Fatal编程技术网

AVR C串行通信:打印号码固定按钮

AVR C串行通信:打印号码固定按钮,c,putty,avr,C,Putty,Avr,我正在使用微控制器和I/O板。我的代码检查I/O板上某些固定按钮的开/关状态,并根据按钮的状态对int值执行按位操作,因此它以二进制表示0-15或0000到1111之间的数字 我的I/O板 我的主板上有4个固定按钮DS1-DS4,DS1是LSB,而DS4是MSB。例如: DS1 = ON, DS2 = OFF, DS3 = OFF, DS4 = OFF num = 0001 binary and 1 in decimal 及 我有一个名为printDec的函数,它接受一个int值,根据位数找

我正在使用微控制器和I/O板。我的代码检查I/O板上某些固定按钮的开/关状态,并根据按钮的状态对int值执行按位操作,因此它以二进制表示0-15或0000到1111之间的数字

我的I/O板

我的主板上有4个固定按钮DS1-DS4,DS1是LSB,而DS4是MSB。例如:

DS1 = ON, DS2 = OFF, DS3 = OFF, DS4 = OFF
num = 0001 binary and 1 in decimal

我有一个名为printDec的函数,它接受一个int值,根据位数找到它的大小,并将其转换为字符数组或字符串,然后将其传输到串行通信屏幕,每次传输一个字符

 #include <avr/io.h>
#include <util/delay.h>

#include <stdlib.h>
#include <string.h>


#define F_CPU 16000000UL


/*
    Input Button
    ---------------------------------------
    Romeo Board : | d2  | d3  | d4  | d5  | 
    Atmega chip : | pd2 | pd3 | pd4 | pd5 |
    I/O Board   : | DS1 | DS2 | DS3 | DS4 |

*/

void initUART(unsigned int baud);
void transmitByte(unsigned char data);
unsigned char receiveByte(void);

int getNumOfDigits(int num);
void printDec(int num);

int main(void) {

    int num = 0;
    int old_num = 0;

    DDRD = 0b00000000; 
    PORTD = 0b00111100;

    int hasPrinted = 0;

    initUART(9600);

    while(1) {

        // 1st bit LSB
        if((PIND & 0b00000100) == 0) {
            num = num | 0b00000001;
        } else {
            num = num & 0b11111110;
        }

        // 2nd bit 
        if((PIND & 0b00001000) == 0) {
            num = num | 0b00000010;
        } else {
            num = num & 0b11111101;
        }

        // 3rd bit
        if((PIND & 0b00010000) == 0) {
            num = num | 0b00000100;
        } else {
            num = num & 0b11111011;
        }

        //4th bit MSB
        if((PIND & 0b00100000) == 0) {
            num = num | 0b00001000;
        } else {
            num = num & 0b11110111;
        }




        if(num != old_num) {


            old_num = num;
            printDec(num);  
            transmitByte('-');
            transmitByte('-');
            transmitByte('>');


        }


        /* 

            Tested printDec without button it seems to work fine

        if(hasPrinted == 0) {

            printDec(15);   
            transmitByte(','); 

            printDec(16);
            transmitByte(','); 

            printDec(21);
            transmitByte(','); 

            printDec(num);
            transmitByte(',');

            num = num | 0b00001111;
            printDec(num);
            transmitByte(',');

            num = num & 0b00000011;
            printDec(num);
            transmitByte(',');

            hasPrinted = 1;
        }
        */
    }

    return 0;
}


void initUART(unsigned int baud) {

    /*
        Initialize settings for uart functions.
        Must be done once at the beginning of the program.
    */

    //Normal mode UBRR formula
    unsigned int ubrr = F_CPU/16/baud-1;

    //shift MSB and store in UBRR0H
    UBRR0H = (unsigned char) (ubrr >> 8);

    //store LSB in UBRR0L
    UBRR0L = (unsigned char) ubrr;

    //Enable transmitter/receiver
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    //8-Bit Characters, 0 Stop bits, No parity
    UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); 

}

void transmitByte(unsigned char data) {

    /*
        Write byte to UART
    */

    //Wait for empty transmit buffer
    while(!(UCSR0A & (1 << UDRE0)));

    //Start transmission by writing to UDR0
    UDR0 = data;

}

unsigned char receiveByte(void){

    /*
        Read byte from UART
    */

    //Wait for incoming byte
    while(!(UCSR0A & (1 << RXC0)));

    //Return the byte
    return UDR0;
}

int getNumOfDigits(int num) {

    int s;

    while(num != 0) {

        num /= 10;
        ++s;
    }

    return s;
}

void printDec(int num) {

    unsigned char *str;
    int size;
    int i;

    size = getNumOfDigits(num);
    str = (char *) malloc(size+1);
    sprintf(str, "%d", num);

    for(i = 0; i < size; i++) {

        transmitByte(str[i]);

        _delay_ms(100);
    }

    free(str);



}
当我用串行通信油灰尝试这段代码时,它会打印正确的值一段时间,然后突然打印出所有这些奇怪的符号以及我想要的值。我不知道为什么按下按钮时效果很好,但固定按钮却不行,我不明白为什么所有这些奇怪的符号都出现在屏幕上

一个问题是:

int getNumOfDigits(int num) {  
    int s;  
    while  (num != 0) {   num /= 10;   ++s; }  
    return s;
}
本地变量s未初始化,因此您会收到垃圾

也就是说,考虑到嵌入AVR的上下文,该代码非常臃肿,无法传输0到15之间的1或2位数字

试着用另一种方式思考printDec:

transmitByte(num / 10 + '0');
transmitByte(num % 10 + '0');
它以两位数字00的十进制形式传输num。。。15首先,它获取十位数,然后通过为“0”字符添加ascii码,将其转换为所需的ascii码。单位数字也一样

如果您希望0到9之间的数字为一位数,请写下以下内容:

if (num >= 10) transmitByte(num / 10 + '0');
transmitByte(num % 10 + '0');

这个版本的printDec更为嵌入:-

奇怪的符号是什么?你也可以打印字符和符号以及字符和符号的十六进制代码,并用这些数据更新你的问题吗?我更新了屏幕的输出,它应该在那里,我也可以发布一个视频,只是为了更好地澄清它。
if (num >= 10) transmitByte(num / 10 + '0');
transmitByte(num % 10 + '0');