У меня есть лабораторное задание, в котором мне нужно использовать Atmega328P для работы с АЦП и с USART передавать цифровое значение на ЖК-дисплей MILFORD-4X20-BKP. ЖК-дисплей должен отображать значение в 2-байтовом формате (десятичное, 0-255) в первой строке и формат слова (4 байта, 0-1023) в третьей строке.Массив в Proteus с использованием вопроса о выпуске WinAVR C
Мне было удачно это сделать, но из-за того, что я был не уверен в размерах массива, я изначально имел их всех достаточно больших, чтобы не иметь проблемы. Когда я сменил его на то, что, по моему мнению, было необходимо, у меня была странная ошибка. Это странный символ, показанный ниже (или, я думаю, внизу). Символ в этом положении будет зависеть от значения потенциометра.
Итак, вот мое мышление. Я выделил 36 (+1 для pos 0) позиции для баффа, который был отправлен на ЖК-дисплей. Я выделил 3 к buff2 для значения слова (4 п позиций) и, наконец, 4 для buff1 для значения 2 байта (5 л позиции)
buff[36]; buff1[4]; buff2[3];
3n позиции для значения произведений слов, но когда я поставил 4n для значения 2 байта появляется ошибка. Посмотрите первое изображение.
Ошибка также появляется в виде части значения 0-255, появляющейся в конце строки 3, в зависимости от разных значений массива buff и buff1. На второй фотографии есть buff[37], buff1[2], buff2[3]
Последнее примечание: если я изменю значение на buff1[5]
, ошибка исчезнет ... но почему? Размер массива для 2 байтов должен быть меньше, чем для 4 байтов.
Я делаю лучше всего объяснить мою проблему, но не знаю, если я достаточно ясно. Я знаю, что мои массивы пересекаются в адрес памяти друг друга, но я не вижу, как и где.
/*
* Serial Lcd.c
*
* Use's a 4x20 serial LCD display.
*
* Adapted by Phil J to suit Atmega328P: 15/2/2015 (corrected Usart_Rx Int Vector address ref. for 328)
*
* Editted by Tomi Fodor
*
*/
#define F_CPU 16000000UL
#define BAUDRATE 9600 - change to External 16MHz crystal on MCU
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "stdlib.h"
#include "USART.h"
// Global Variables
// Note the use of the volatile keyword to ensure that the compiler knows that these variables can be changed at
// any time, including by the ISR
volatile int i=0;
volatile uint16_t buffer[]; // 20 place array
volatile char buff[36]; // var sent out value
volatile char buff1[4]; // var for the pot value/4 ***** HAS TO BE AT LEAST 4 FOR SOME REASON (5 w/o bug), SHOULD BE FINE AT 2
volatile char buff2[3]; // var for the actual pot value
volatile uint16_t StrRxFlag=0;
volatile int Ana, Bell; // pot value
int main(void)
{
buff[4]=' ';buff[5]='P';buff[6]='o';buff[7]='t';buff[8]=' ';buff[9]='V';buff[10]='a';buff[11]='l';buff[12]='(';buff[13]='D';buff[14]=')'; // constants to be displayed
_delay_ms(500);
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1); // Enables the ADC, sets the ADC to use the division factor 64 for the ADC clock
USART_interrupt_init();
USART_putstring("Ready "); // Send String to the LCD
// USART_putstring(buff3);
USART_send('\r'); // Send carriage return
// USART_send('\n'); // Send linefeed
_delay_ms(500); // Allows for the LCD module to initialize
while(1)
{
USART_send(254); // LCD control mode
USART_send(0); // LCD HOME command
USART_send(254);
USART_send(1); // LCD CLEAR SCREEN
buff[0] = ' '; // Required for offset of display
buff[4] = ' '; // Signifies terminator of pot
ADCSRA |= (1<<ADSC); // Starts A-D conversion
while (ADCSRA & (1<<ADSC)); // Wait till A-D conversion is complete
Ana = ADCW/4; // Get A-D result
Bell = ADCW; // Get actual A-D result
itoa(Ana,buff1,10); // Creats the dec value of the Analogue value [stdlib.h]
itoa(Bell,buff2,10); // actual
if (buff1[1] == '\0') // If only 1 digit
{
buff[1] = ' '; // Not hundreds
buff[2] = ' '; // Not tens
buff[3] = buff1[0]; // Place in single digit
}
else if(buff1[2] == '\0') // If only 2 digits
{
buff[1] = ' '; // Not hundreds
buff[2] = buff1[0]; // Shift
buff[3] = buff1[1]; // Shift
}
else
{
buff[1] = buff1[0]; // Shift
buff[2] = buff1[1]; // Shift
buff[3] = buff1[2]; // Shift
}
for(i=0;i<25;i++)
{
buff[i+15] = ' ';
}
buff[25]=' ';buff[26]='P';buff[27]='o';buff[28]='t';buff[29]=' ';buff[31]='V';buff[32]='a';buff[33]='l';buff[34]='(';buff[35]='D';buff[36]=')'; // constants to be displayed
if (buff2[1] == '\0') // If only 1 digit
{
buff[21] = ' '; // Not thousands
buff[22] = ' '; // Not hundreds
buff[23] = ' '; // Not tens
buff[24] = buff2[0]; // Place in single digit
}
else if(buff2[2] == '\0') // If only 2 digits
{
buff[21] = ' '; // Not thousands
buff[22] = ' '; // Not hundreds
buff[23] = buff2[0]; // Shift
buff[24] = buff2[1]; // Shift
}
else if(buff2[3] == '\0') // If only 3 digits
{
buff[21] = ' '; // Not thousands
buff[22] = buff2[0]; // Shift
buff[23] = buff2[1]; // Shift
buff[24] = buff2[2]; // Shift
}
else
{
buff[21] = buff2[0]; // Shift
buff[22] = buff2[1]; // Shift
buff[23] = buff2[2]; // Shift
buff[24] = buff2[3]; // Shift
}
USART_putstring(buff);
USART_send('\r');
_delay_ms(500);
}
}
//ISR(USART0_RX_vect) - not for 328
ISR(USART_RX_vect) //this is the right vector ref, not above
{
buffer[i]=UDR0; //Read USART data register
if(buffer[i++]=='\r') //check for carriage return terminator and increment buffer index
{
// if terminator detected
StrRxFlag=1; //Set String received flag
buffer[i-1]=0x00; //Set string terminator to 0x00
i=0; //Reset buffer index
}
}
Является ли код, показанный в вашем сообщении ==, коду, который вы скомпилировали, побежал и заметил вашу ошибку? – ryyker
Основной код, который я опубликовал, - это код, который я использовал, да. Это должен быть тот же код, который привел к проблемам, описанным выше, и показан на первом снимке. Я повторил часть того же кода в моем вопросе, который, возможно, привел к некоторой путанице. (buff [36], buff1 [4], buff2 [3]). –