我已经创建了从UART发送和接收的函数,并且发送数据似乎没有问题。在数据可视化器中,我们可以看到值,甚至可以绘制它们。 但是,当通过蓝牙发送这些数据时,我们无法获取值以将其绘制在许多可用应用程序中的任何一个中。 我相信我们通过UART向蓝牙发送数据的方式存在问题,这就是为什么我们无法随后绘制值的原因。
首先,请给我们建议以下代码是否正确,是否有错误以及是否有更好的方法通过UART发送数据以制造蓝牙的建议好好工作。目标是能够绘制(绘制)电话上的值。
非常感谢
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
//----------VARIABLES
float V_n,V_nm1,V_measure=0;
volatile int Velo_pulse;
float Exp_fltr_Coeff=0.2;
unsigned int Counter_ADC=0b0001;
unsigned int Value1;
char String[]="";
//----------Functions Definition
//---timers
void Timer1_Control();
void AttachInterrupt();
//---AnalogueRead
void Set_Ports();
void AnalogRead_Setup();
unsigned int AnalogRead();
//---UART
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr, unsigned int Value1);
int main(void){
USART_init(); //Call the USART initialization code
Set_Ports();
AnalogRead_Setup();
AttachInterrupt();
Timer1_Control();
sei();
while(1){
_delay_ms(1);
}
return 0;
}
void USART_init(void){
UBRR0H = (unsigned char)(BAUD_PRESCALLER>>8); //UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
UBRR0L = (unsigned char)(BAUD_PRESCALLER);
UCSR0B = (1<<RXEN0)|(1<<TXEN0); //Enable receiver / transmitter
UCSR0C = (1<<USBS0)|(3<<UCSZ00); //Set frame format: 8data, 2stop bit
}
unsigned char USART_receive(void){
while(!(UCSR0A & (1<<RXC0))); //Wait for data to be received (buffer RXCn in the UCSRnA register)
return UDR0;
}
void USART_send( unsigned char data){
while(!(UCSR0A & (1<<UDRE0))); //Waiting for empty transmit buffer (buffer UDREn in the UCSRnA register)
UDR0 = data; //Loading Data on the transmit buffer
}
void USART_putstring(char* String, unsigned int Value1){
sprintf(String,"%d\r\n",Value1);
while(*String != 0x00){
USART_send(*String);
String++;}
}
void Set_Ports()
{
DDRD = 0b11111111; //All port is output
DDRD ^= (1 << DDD5); // PD5 is now input
}
ISR(ADC_vect)
{
//ADMUX ^= Counter_ADC; //Swapping between ADC0 an ADC1
}
void AnalogRead_Setup()
{
ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0); // Set ADC prescaler to 16 - 1 MHz sample rate @ 16MHz
ADMUX |= (1 << REFS0); // Set ADC reference to AVCC
ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading
ADCSRA |= (1 << ADATE); // Set ADC to Free-Running Mode
ADCSRA |= (1 << ADIE); // Interrupt in Conversion Complete
ADCSRA |= (1 << ADEN); // Enable ADC
}
unsigned int AnalogRead(unsigned int PortVal)
{
if (PortVal==5){
ADMUX |= (0 << MUX3) | (1 << MUX2) | (0 << MUX1) | (1 << MUX0); //sets the pin 0101 sets pin5
} else if (PortVal==4){
ADMUX |= (0 << MUX3) | (1 << MUX2) | (0 << MUX1) | (0 << MUX0); //sets the pin 0101 sets pin4
}
ADCSRA |= (1 << ADSC); // Start A2D Conversions
//while(ADCSRA & (1 << ADSC));
return ADCH;
}
//----------Timer Functions
ISR (TIMER1_COMPA_vect) // Timer1 ISR (compare A vector - Compare Interrupt Mode)
{
cli();
V_measure=(Velo_pulse*60/0.250);
//USART_putstring(String,Velo_pulse);
Velo_pulse=0;
V_n=Exp_fltr_Coeff*V_measure+(1-Exp_fltr_Coeff)*V_nm1;
V_nm1=V_n;
USART_putstring(String,(int)V_n);
sei();
}
ISR (INT0_vect)
{
Velo_pulse++;
//USART_putstring(String,Velo_pulse);
}
void Timer1_Control()
{
TCCR1A=0b00000000; //Clear the timer1 registers
TCCR1B=0b00000000;
TCNT1=0b00000000;
TCCR1B=0b00001101; //Sets prescaler (1024) & Compare mode
OCR1A=2604; // 160ms - 6 Hz
TIMSK1=0b00000010;
}
void AttachInterrupt()
{
DDRD ^= (1 << DDD2); // PD2 (PCINT0 pin) is now an input
PORTD |= (1 << PORTD2); // turn On the Pull-up // PD2 is now an input with pull-up enabled
EICRA = 0b00000011; // set INT0 to trigger on rising edge change
EIMSK = 0b00000001; // Turns on INT0
}
答案 0 :(得分:0)
查看字符串初始化:
char String[]="";
这将分配一个大小为1(终止为零)的字符数组。
然后您调用此数组引用作为第一个参数:
USART_putstring(String,(int)V_n);
USART_putstring
如下:
void USART_putstring(char* String, unsigned int Value1){
sprintf(String,"%d\r\n",Value1);
while(*String != 0x00){
USART_send(*String);
String++;}
}
注意sprintf(String,"%d\r\n",Value1);
它将数值转换为char缓冲区。即缓冲区应该足够大以包含数字,换行符\r\n\
和零(字符串终止符)的文本表示形式。
但是由于您的字符串缓冲区的大小仅为1个字符,所以它完全取决于运气,在sprintf
之后会发生什么:也许有一些未使用的内存区域,所以整个事情看起来好像在起作用。也许还有其他一些变量,它们的值将被覆盖,这将使程序将来的行为异常。也许有一些重要数据,您的应用将崩溃。添加几行并重新编译代码后,行为可能会更改。
重点是:小心缓冲区。代替使用常量进行初始化,而是设置缓冲区的确切大小。数字长度最大为6个符号(假设您使用的是AVR-GCC,它的int
宽度为16位,因此最小为-32768,因此最大长度为6个符号),而{{ 1}} + 1表示终止零。即缓冲区的大小至少应为9 。
\r\n\