There is an array of ConfigLamp [CONFIG_AMOUNT] structures. I appeal to him as follows:

ConfigLamp[0].ValuePWM=123; ConfigLamp[0].Flag.Bits.B0=1; 

And everything seems to be written, but after several cycles, judging by the simulation, the data that stores this array is overwritten with some kind of garbage.

What could be the problem? Can anyone tell me? would appreciate it.

Below is the array and structure declaration code:

 //Структура объеденения битовых полей. struct UnionsBits { unsigned B0:1; unsigned B1:1; unsigned B2:1; unsigned B3:1; unsigned B4:1; unsigned B5:1; unsigned B6:1; unsigned B7:1; }; union Byte { uint8_t Byte; struct UnionsBits Bits; }; #define CONFIG_AMOUNT 1 //Определения нового типа. typedef struct { uint8_t ValuePWM; union Byte Flag; }Config; Config ConfigLamp[CONFIG_AMOUNT]; //Массив структур. 
  • And where is the code in which "the data is overwritten by some kind of garbage"? - AnT
  • Added below. He is the most cleared of everything to simulate the proteus - Andrei Plotnikov
  • No “added below” is done here. Add new data to the question, not to the answers to yourself. - AnT
  • I did not know, next time I will do it. - Andrey Plotnikov

2 answers 2

You always call

 TWI_SendData(buf, 13); 

where inside it copies size 13 data to size 8 buffer

 #define TWI_BUFFER_SIZE 8 volatile static uint8_t twiBuf[TWI_BUFFER_SIZE]; 

It is not surprising that somewhere something will be overwritten when you fly out of the array.

  • This is not the case. for the test, I even deleted TWI_SendData (buf, 13) from the loop; - Andrey Plotnikov
  • @Andrey Plotnikov: Is that how it is? If you remove TWI_SendData from the loop, then you will never do anything else in main after assigning a bit field. At what point are you then watching your rubbing? - AnT
  • Well, here I posted screenshots radiokot.ru/forum/viewtopic.php?f=57&t=157698 The truth is there is not yet deleted this line without it, the same thing happens. - Andrey Plotnikov
  • Oops, I apologize to the campaign, it is all the same. - Andrey Plotnikov
 Полный код : #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <avr/eeprom.h> #include <stdint.h> #include <util/twi.h> //======================================================================== #define SET_BIT(port,bit) port|=(1<<bit) #define CLEAR_BIT(port,bit) port&= ~(1<<bit) #define INV_BIT(port,bit) port ^=(1<<bit) //======================================================================== /*размер буфера TWI модуля*/ #define TWI_BUFFER_SIZE 8 /**************************************************************************** Статусные коды TWI модуля ****************************************************************************/ /*Общие статусные коды */ #define TWI_START 0x08 // состояние START сформировано #define TWI_REP_START 0x10 // состояние повторный START сформировано #define TWI_ARB_LOST 0x38 // был потерян приоритет /*Статусные коды ведущего передатчика*/ #define TWI_MTX_ADR_ACK 0x18 // был передан пакет SLA+W и получено подтверждение #define TWI_MTX_ADR_NACK 0x20 // был передан пает SLA+W и не получено подтверждение #define TWI_MTX_DATA_ACK 0x28 // был передан байт данных и получено подтверждение #define TWI_MTX_DATA_NACK 0x30 // был передан байт данных и не получено подтверждение /*Статусные коды ведущего приемника*/ #define TWI_MRX_ADR_ACK 0x40 // был передан пакет SLA+R и получено подтвеждение #define TWI_MRX_ADR_NACK 0x48 // был передан пакет SLA+R и не получено подтверждение #define TWI_MRX_DATA_ACK 0x50 // байт данных принят и передано подтверждение #define TWI_MRX_DATA_NACK 0x58 // был принят байт данных без подтверждения /*Другие статусные коды*/ #define TWI_NO_STATE 0xF8 // неопределенное состояние; TWINT = “0” #define TWI_BUS_ERROR 0x00 // ошибка на шине из-за некоректных состояний СТАРТ или СТОП /*Пользовательские коды*/ #define TWI_SUCCESS 0xff /**************************************************************************** Определения констант ****************************************************************************/ #define TWI_READ_BIT 0 // позиция R/W бита в адресном пакете #define TWI_ADR_BITS 1 // позиция адреса в адресном пакете #define TRUE 1 #define FALSE 0 #define TWSR_MASK 0xfc //Структура объеденения битовых полей. struct UnionsBits { unsigned B0:1; unsigned B1:1; unsigned B2:1; unsigned B3:1; unsigned B4:1; unsigned B5:1; unsigned B6:1; unsigned B7:1; }; union Byte { uint8_t Byte; struct UnionsBits Bits; }; #define CONFIG_AMOUNT 1 //Определения нвого типа. typedef struct { uint8_t ValuePWM; union Byte Flag; }Config; Config ConfigLamp[CONFIG_AMOUNT]; //Массив структур. volatile static uint8_t twiBuf[TWI_BUFFER_SIZE]; volatile static uint8_t twiState = TWI_NO_STATE; volatile static uint8_t twiMsgSize; /*предделители для установки скорости обмена twi модуля*/ uint8_t pre[4] = {2, 8, 32, 128}; /**************************************************************************** Инициализация и установка частоты SCL сигнала ****************************************************************************/ uint8_t TWI_MasterInit(uint16_t fr) { uint8_t i; uint16_t twbrValue; for(i = 0; i<4; i++){ twbrValue = ((((F_CPU)/1000UL)/fr)-16)/pre[i]; if ((twbrValue > 0)&& (twbrValue < 256)){ TWBR = (uint8_t)twbrValue; TWSR = i; TWDR = 0xFF; TWCR = (1<<TWEN); return TWI_SUCCESS; } } return 0; } /**************************************************************************** Проверка - не занят ли TWI модуль. Используется внутри модуля ****************************************************************************/ static uint8_t TWI_TransceiverBusy(void) { return (TWCR & (1<<TWIE)); } /**************************************************************************** Взять статус TWI модуля ****************************************************************************/ uint8_t TWI_GetState(void) { while (TWI_TransceiverBusy()); return twiState; } /**************************************************************************** Передать сообщение msg из msgSize байтов на TWI шину ****************************************************************************/ void TWI_SendData(uint8_t *msg, uint8_t msgSize) { uint8_t i; while(TWI_TransceiverBusy()); //ждем, когда TWI модуль освободится twiMsgSize = msgSize; //сохряняем кол. байт для передачи twiBuf[0] = msg[0]; //и первый байт сообщения if (!(msg[0] & (TRUE<<TWI_READ_BIT))){ //если первый байт типа SLA+W for (i = 1; i < msgSize; i++){ //то сохряняем остальную часть сообщения twiBuf[i] = msg[i]; } } twiState = TWI_NO_STATE ; TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA); //разрешаем прерывание и формируем состояние старт } /**************************************************************************** Переписать полученные данные в буфер msg в количестве msgSize байт. ****************************************************************************/ uint8_t TWI_GetData(uint8_t *msg, uint8_t msgSize) { uint8_t i; while(TWI_TransceiverBusy()); //ждем, когда TWI модуль освободится if(twiState == TWI_SUCCESS){ //если сообщение успешно принято, for(i = 0; i < msgSize; i++){ //то переписываем его из внутреннего буфера в переданный msg[i] = twiBuf[i]; } } return twiState; } /**************************************************************************** Обработчик прерывания TWI модуля ****************************************************************************/ ISR(TWI_vect) { static uint8_t ptr; uint8_t stat = TWSR & TWSR_MASK; switch (stat){ case TWI_START: // состояние START сформировано case TWI_REP_START: // состояние повторный START сформировано ptr = 0; case TWI_MTX_ADR_ACK: // был передан пакет SLA+W и получено подтверждение case TWI_MTX_DATA_ACK: // был передан байт данных и получено подтверждение if (ptr < twiMsgSize){ TWDR = twiBuf[ptr]; //загружаем в регистр данных следующий байт TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); //сбрасываем флаг TWINT ptr++; } else{ twiState = TWI_SUCCESS; TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWSTO)|(0<<TWIE); //формируем состояние СТОП, сбрасываем флаг, запрещаем прерывания } break; case TWI_MRX_DATA_ACK: //байт данных принят и передано подтверждение twiBuf[ptr] = TWDR; ptr++; case TWI_MRX_ADR_ACK: //был передан пакет SLA+R и получено подтвеждение if (ptr < (twiMsgSize-1)){ TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); //если это не предпоследний принятый байт, формируем подтверждение } else { TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); //если приняли предпоследний байт, подтверждение не формируем } break; case TWI_MRX_DATA_NACK: //был принят байт данных без подтверждения twiBuf[ptr] = TWDR; twiState = TWI_SUCCESS; TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWSTO); //формируем состояние стоп break; case TWI_ARB_LOST: //был потерян приоритет TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA); // сбрасываем флаг TWINT, формируем повторный СТАРТ break; case TWI_MTX_ADR_NACK: // был передан пает SLA+W и не получено подтверждение case TWI_MRX_ADR_NACK: // был передан пакет SLA+R и не получено подтверждение case TWI_MTX_DATA_NACK: // был передан байт данных и не получено подтверждение case TWI_BUS_ERROR: // ошибка на шине из-за некоректных состояний СТАРТ или СТОП default: twiState = stat; TWCR = (1<<TWEN)|(0<<TWIE)|(0<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC); //запретить прерывание } } #define ADR 0x30 uint8_t buf[13]={0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA}; int main(void) { TWI_MasterInit(100); sei(); /*подготавливаем сообщение*/ buf[0] = (ADR<<1); //адресный пакет buf[1] = 0; //адрес регистра buf[2] = 0xfa; //значение секунд buf[3] = 0xfb; //значение минут /*отправляем его*/ TWI_SendData(buf, 13); ConfigLamp[0].ValuePWM=123; ConfigLamp[0].Flag.Bits.B0=1; while(1) { TWI_SendData(buf, 13); } return 0; } 
  • This is not done here. Add new data to the question , not to the answers to yourself. - AnT