Самопроизвольное изменение значения переменной

Кто любит RISC в жизни, заходим, не стесняемся.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Самопроизвольное изменение значения переменной

Сообщение mab72 »

Доброго всем времени!
Если у кого-то есть время, желание, помогите разобраться в чем проблема.

Дано: STM32G041J6M6, для управления WS2812B.
Проблема: в функции WS2812B_fill_buf при наступлении условия k=1, при заполнении G-составляющей, при i=1 происходит самопроизвольное присвоение переменной tim_stat значением 0x19. И естественно ничего не работает. В коде в данном месте, явно нет такого присвоения, как такое может быть?

ws2812.h
Спойлер#ifndef MAIN_H
#define MAIN_H

//------------------------Include
#include "stm32g0xx.h"
#include "it.h"
#include "ws2812.h"

//------------------------Define
#define NUMBER_OF_LED 1
#define BUF_LEN (NUMBER_OF_LED*24+1)

//------------------------Variable
typedef struct
{
uint8_t R;
uint8_t G;
uint8_t B;
} RGB_TypeDef;

typedef struct
{
uint16_t H;
uint8_t S;
uint8_t V;
} HSV_TypeDef;

static RGB_TypeDef RGB[BUF_LEN] = {0};

//------------------------Function
void RCC_Cfg(void);
void GPIO_test_cfg(void);

void WS2812_init(void);
void WS2812_send(uint8_t * buf, uint32_t len);
void WS2812_fill_buf(RGB_TypeDef * rgb, uint8_t * buf);

void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void TIM17_IRQHandler(void);
void Delay_ms(uint32_t del);

//------------------------
#endif //MAIN_H

ws2812.c
Спойлер#include "main.h"

//------------------------Include
//------------------------Define


#define DMA_STAT_FREE 0
#define DMA_STAT_BSY 1

#define TIM_STAT_FREE 0
#define TIM_STAT_BSY 1


//#define WS2812_ARR (80-1)
//#define WS2812_0 (WS2812_ARR/3)
//#define WS2812_1 ((WS2812_ARR/3)*2)
#define WS2812_ARR (80-1)
#define WS2812_0 25
#define WS2812_1 53


//------------------------Variable
static __IO uint32_t delay_ms = 0;
static __IO uint8_t dma_stat=0;
static __IO uint8_t tim_stat=0;

//static uint8_t led_buf_demo[8] = {WS2812_1,WS2812_0,WS2812_0,0,0,0,0,0};
static uint8_t led_buf[BUF_LEN]={0};



//------------------------Function

//======Main
int main(void)
{
RCC_Cfg();
//GPIO_test_cfg();
WS2812_init();



while(1)
{
//GPIOB->BSRR |= GPIO_BSRR_BS0;
RGB[0].R = 0x80;
RGB[0].G = 0x00;
RGB[0].B = 0x00;
WS2812_fill_buf(RGB, led_buf);
WS2812_send(led_buf, BUF_LEN);
//Delay_ms(15);

RGB[0].R = 0x00;
RGB[0].G = 0x80;
RGB[0].B = 0x00;
WS2812_fill_buf(RGB, led_buf);
WS2812_send(led_buf, BUF_LEN);
//Delay_ms(15);

RGB[0].R = 0x00;
RGB[0].G = 0x00;
RGB[0].B = 0x80;
WS2812_fill_buf(RGB, led_buf);
WS2812_send(led_buf, BUF_LEN);
//Delay_ms(15);
//for(__IO uint32_t i=0; i<100; i++)
//{
//}
//Delay_ms(100);

//GPIOB->BSRR |= GPIO_BSRR_BR0;
//WS2812_send();
//for(__IO uint32_t i=0; i<100; i++)
//{
//}
//Delay_ms(15);
}
}

//======EndMain
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------WS2812_fill_buf
void WS2812_fill_buf(RGB_TypeDef * rgb, uint8_t * buf)
{
for(__IO uint32_t k=0; k<(BUF_LEN-1); k++)
{
//G
for(__IO uint32_t i=0; i<8; i++)
{
if((rgb[k].G & (0x80>>i)) != 0)
buf[k*24+i] = WS2812_1;
else
buf[k*24+i] = WS2812_0;
}
//R
for(__IO uint32_t i=0; i<8; i++)
{
if((rgb[k].R & (0x80>>i)) != 0)
buf[k*24+8+i] = WS2812_1;
else
buf[k*24+8+i] = WS2812_0;
}
//B
for(__IO uint32_t i=0; i<8; i++)
{
if((rgb[k].B & (0x80>>i)) != 0)
buf[k*24+16+i] = WS2812_1;
else
buf[k*24+16+i] = WS2812_0;
}
}
buf[BUF_LEN-1] = 0;
}

//------------------------WS2812_send
void WS2812_send(uint8_t * buf, uint32_t len)
{
//while(((TIM17->CR1) & TIM_CR1_CEN) == TIM_CR1_CEN)
while(tim_stat != TIM_STAT_FREE)
//while(dma_stat == DMA_STAT_BSY)
{
}

//GPIOB->BSRR |= GPIO_BSRR_BR0;
//TIM_stat_set(TIM_STAT_BSY);
tim_stat = TIM_STAT_BSY;
dma_stat = DMA_STAT_BSY;

//DMA1_Channel1->CCR &= ~DMA_CCR_EN;
//TIM17->CR1 &= ~TIM_CR1_CEN;

DMA1_Channel1->CPAR = (uint32_t)(&TIM17->CCR1);
DMA1_Channel1->CMAR = (uint32_t)(buf);
DMA1_Channel1->CNDTR = len;

DMA1_Channel1->CCR |= DMA_CCR_EN;
TIM17->CR1 |= TIM_CR1_CEN;
}

//------------------------WS2812_init
void WS2812_init(void)
{
uint32_t tmp;

//PB9 AF_2 PP NPuNPd as TIM17_CH_1
RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
tmp = RCC->IOPENR;
(void)tmp;

MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE9, GPIO_MODER_MODE9_1);
CLEAR_BIT(GPIOB->OTYPER, GPIO_OTYPER_OT9);
SET_BIT(GPIOB->OSPEEDR, GPIO_OSPEEDR_OSPEED9);
CLEAR_BIT(GPIOB->PUPDR, GPIO_PUPDR_PUPD9);

MODIFY_REG(GPIOB->AFR[1], GPIO_AFRH_AFSEL9, GPIO_AFRH_AFSEL9_1);

//TIM17 PWM_1
RCC->APBENR2 |= RCC_APBENR2_TIM17EN;
tmp = RCC->APBENR2;
(void)tmp;

MODIFY_REG(TIM17->CCMR1, TIM_CCMR1_OC1M, TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2);
//MODIFY_REG(TIM17->CCMR1, TIM_CCMR1_OC1M, TIM_CCMR1_OC1PE | TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2);

TIM17->CR1 |= TIM_CR1_ARPE; //ARR Preload Enable
TIM17->CCMR1 |= TIM_CCMR1_OC1PE; //CCR1 Preload Enable

TIM17->BDTR |= TIM_BDTR_MOE; //Main Output Enable
TIM17->CCER |= TIM_CCER_CC1E; //CH_1 Output Enable
TIM17->DIER |= TIM_DIER_CC1DE; //Rqst for DMA Enable
TIM17->PSC = 0; //7;
TIM17->ARR = WS2812_ARR; //9;
TIM17->CCR1 = 0;

TIM17->DIER |= TIM_DIER_UIE; //Interrupt Enable
NVIC_EnableIRQ(TIM17_IRQn); //Global Interrupt Enable

tim_stat = TIM_STAT_FREE;
//TIM17->CR1 |= TIM_CR1_CEN;

//DMA1 is TIM17_CH_1
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
tmp = RCC->AHBENR;
(void)tmp;

DMA1_Channel1->CCR &= ~DMA_CCR_EN;

MODIFY_REG(DMA1_Channel1->CCR, (uint32_t)0xFFFF,
DMA_CCR_PSIZE_0 | //Peripheral size 16
DMA_CCR_MINC |
DMA_CCR_DIR | //From memory to Periph
DMA_CCR_TCIE //Transfer Complit Interrupt Enable
);

DMAMUX1_Channel0->CCR = (47 << DMAMUX_CxCR_DMAREQ_ID_Pos);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
dma_stat = DMA_STAT_FREE;
}

//------------------------Delay_ms
void Delay_ms(uint32_t del)
{
uint32_t cur_del;

cur_del = delay_ms;

while((delay_ms - cur_del) < del)
{
}
}

//------------------------GPIO_test_cfg
void GPIO_test_cfg(void)
{
uint32_t tmp;

//GPIO for Test PB0 OUT PP PD RST
RCC->IOPENR |= RCC_IOPENR_GPIOBEN; //GPIOC Clock Enable
tmp = (RCC->IOPENR);
(void)tmp;

MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE0, GPIO_MODER_MODE0_0);
CLEAR_BIT(GPIOB->OTYPER, GPIO_OTYPER_OT0);
SET_BIT(GPIOB->OSPEEDR, GPIO_OSPEEDR_OSPEED0);
MODIFY_REG(GPIOB->PUPDR, GPIO_PUPDR_PUPD0, GPIO_PUPDR_PUPD0_1);

GPIOB->BSRR |= GPIO_BSRR_BR0;
}

//------------------------Cfg_RCC
void RCC_Cfg(void)
{
__IO uint32_t tmpreg;
SET_BIT(RCC->APBENR2, RCC_APBENR2_SYSCFGEN);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->APBENR2, RCC_APBENR2_SYSCFGEN);
(void)tmpreg;

SET_BIT(RCC->APBENR1, RCC_APBENR1_PWREN);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->APBENR1, RCC_APBENR1_PWREN);
(void)tmpreg;

//NVIC_SetPriority(SysTick_IRQn, 3);

MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1);
//CLEAR_BIT(FLASH->ACR, FLASH_ACR_LATENCY);
while(((FLASH->ACR) & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_1)
{
}

SET_BIT(RCC->CR, RCC_CR_HSION);
while(((RCC->CR) & RCC_CR_HSIRDY) != RCC_CR_HSIRDY)
{
}

MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLR,
RCC_PLLCFGR_PLLSRC_HSI | (8 << RCC_PLLCFGR_PLLN_Pos) | RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLP_0 | RCC_PLLCFGR_PLLQ_0);

SET_BIT(RCC->CR, RCC_CR_PLLON);
SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLREN);
while(((RCC->CR) & RCC_CR_PLLRDY) != RCC_CR_PLLRDY)
{
}

CLEAR_BIT(RCC->CFGR, RCC_CFGR_HPRE);

MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_1);
while(((RCC->CFGR)& RCC_CFGR_SWS) != RCC_CFGR_SWS_1)
{
}

CLEAR_BIT(RCC->CFGR, RCC_CFGR_PPRE);

SystemCoreClock = 64000000;

SysTick_Config(SystemCoreClock/1000);
}

//======INTERRUP
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------
//------------------------TIM17_IRQHandler
void TIM17_IRQHandler(void)
{
if(((TIM17->SR) & TIM_SR_UIF) == TIM_SR_UIF)
{
TIM17->SR &= ~TIM_SR_UIF;
if(dma_stat == DMA_STAT_FREE)
{
TIM17->CR1 &= ~TIM_CR1_CEN;
//GPIOB->BSRR |= GPIO_BSRR_BS0;
//TIM_stat_set(TIM_STAT_FREE);
tim_stat = TIM_STAT_FREE;
}
}
}

//------------------------DMA1_Channel1_IRQHandler
void DMA1_Channel1_IRQHandler(void)
{
if(((DMA1->ISR) & DMA_ISR_TCIF1) == DMA_ISR_TCIF1)
{
DMA1->IFCR |= DMA_IFCR_CTCIF1;
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
dma_stat = DMA_STAT_FREE;
}
}

//------------------------Systick_Handler
void SysTick_Handler(void)
{
//if(delay_ms>0)
//delay_ms--;
delay_ms++;
}

//------------------------
Добавлено after 2 minutes 5 seconds:
Прошу прощения за дубликат, что-то пошло не так
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Самопроизвольное изменение значения переменной

Сообщение VladislavS »

Разаер uint8_t led_buf[BUF_LEN] равен 25 элементов(байт). Что будет тут buf[k*24+i] = WS2812_0; при k=1 и i=1?

Счётчики циклов не надо делать __IO. Да и вообще, грязненько написано ещё много где.

Добавлено after 4 minutes 18 seconds:
TIM17->SR &= ~TIM_SR_UIF; - анафема.
GPIOB->BSRR |= GPIO_BSRR_BR0; - вечное проклятие.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Re: Самопроизвольное изменение значения переменной

Сообщение mab72 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4390226#p4390226"]Разаер uint8_t led_buf[BUF_LEN] равен 25 элементов(байт). Что...[/uquote]

спасибо за ответ, но так как я не профи(не занимаюсь коммерческой деятельностью в области микроконтроллеров, это мое хобби) возникло еще большее недопонимание:TIM17->SR &= ~TIM_SR_UIF; - анафема за что? в данной строчке я подразумевал простое снятие флага (было прерывание, выставлен флаг, его надо снять) разве не так? если можете поясните в чем не прав.
GPIOB->BSRR |= GPIO_BSRR_BR0; и за что ту вечное проклятие, подскажите более интересный способ сбросить бит.

"Разаер uint8_t led_buf[BUF_LEN] равен 25 элементов(байт). Что будет тут buf[k*24+i] = WS2812_0; при k=1 и i=1?" ага... переполнение (надеюсь правильно понял) тут пошел думать. А почему счетчик циклов не надо делать __IO ?
Ну если есть возможность обЪяснить эту конструкцию __IO, я то так понял шо это команда компилятору, мол компилируй и не оптимизируй эту штуку, ну как-то так.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Самопроизвольное изменение значения переменной

Сообщение VladislavS »

[uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]- анафема за что?[/uquote][uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]и за что ту вечное проклятие[/uquote]За непрочтение RM на предмет того как работать с битами регистров TIMx->SR и GPIOx->BSRR и соответственно неправильное применения операторов &= и |= к ним. В первом регистре флаги сбрасываются записью ноля, а втрой вообще только для записи.
[uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]А почему счетчик циклов не надо делать __IO ?
Ну если есть возможность обЪяснить эту конструкцию __IO, я то так понял шо это команда компилятору, мол компилируй и не оптимизируй эту штуку, ну как-то так.[/uquote]Ну и откуда взялось желание сказать компилятору "не оптимизируй счётчик циклов"? Бывают случаи, когда это действительно нужно, но тут то зачем? Хотелось бы услышать ваши рассуждения по этому поводу.

Добавлено after 28 minutes 32 seconds:
Ещё интересно было бы узнать, что по вашему замыслу делает команда (void)tmp; ? Почему она где-то __IO, а где-то нет? И кто вам рассказал, что нужно делать /* Delay after an RCC peripheral clock enabling */?
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

Re: Самопроизвольное изменение значения переменной

Сообщение AVI-crak »

VladislavS писал(а):Ну если есть возможность обЪяснить эту конструкцию __IO, я то так понял шо это команда компилятору, мол компилируй и не оптимизируй эту штуку, ну как-то так.
Компилятор в праве удалить любые переменные и операции с ними - если они ограничиваются областью видимости функции.
Область видимости функции ограничена скобками самой функции, буквально. По этому любая запись во внешнюю переменную будет безусловной, и на неё необязательно вешать __IO.
По поводу кода.
Постарайся раскидать функции по уровням и типу действия. Например RCC_Cfg() и GPIO_test_cfg() относятся к предварительным настройкам МК, этим функциям самое место в SystemInit() или что-то подобное - то вызывается до main.c. WS2812_init() и всё связанное с WS2812 - должно иметь свой файл, без лишних торчащих ушей. Делать буфер для WS2812 глобальным - очень плохая идея, он должен быть виден там где используется, и больше нигде. Тогда станет доступной возможность оперативно менять количество светодиодов, без смены алгоритма и переписывания части кода.

И кстати, WS2812 длинная пауза в единице - автоматически применяет полученные данные, даже если они были неполные.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Самопроизвольное изменение значения переменной

Сообщение Martian »

чем же глобальный буфер плох? плоха лишь реализация работы с ним - если он глобален и фиксированного размера и один - нет никакого смысла передавать указатель на него и его размер в параметрах функций.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Re: Самопроизвольное изменение значения переменной

Сообщение mab72 »

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]Компилятор в праве удалить...
Постарайся раскидать функции...
И кстати, WS2812 длинная пауза в единице...[/uquote]

Спасибо, этого я не знал,
Раскидать по разным модулям это для меня еще сложно, есть непонимание в обмене данными между этими модулями(static, extern) где как обьявлять переменные, с этим буду позже разбираться, да и програмки у меня пока не большие.
WS2812 в DS написано RET Code 0 более 50us, а про единичку не знал, попробую.

Добавлено after 26 minutes 12 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=4390313#p4390313"][uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]- анафема за что?[/uquote][uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]и за что ту вечное проклятие[/uquote]За непрочтение RM на предмет того как работать с битами регистров TIMx->SR и GPIOx->BSRR и соответственно неправильное применения операторов &= и |= к ним. В первом регистре флаги сбрасываются записью ноля, а втрой вообще только для записи.
[uquote="mab72",url="/forum/viewtopic.php?p=4390309#p4390309"]А почему счетчик циклов не надо делать __IO ?
Ну если есть возможность обЪяснить эту конструкцию __IO, я то так понял шо это команда компилятору, мол компилируй и не оптимизируй эту штуку, ну как-то так.[/uquote]Ну и откуда взялось желание сказать компилятору "не оптимизируй счётчик циклов"? Бывают случаи, когда это действительно нужно, но тут то зачем? Хотелось бы услышать ваши рассуждения по этому поводу.

Добавлено after 28 minutes 32 seconds:
Ещё интересно было бы узнать, что по вашему замыслу делает команда (void)tmp; ? Почему она где-то __IO, а где-то нет? И кто вам рассказал, что нужно делать /* Delay after an RCC peripheral clock enabling */?[/uquote]

Про BSRR я знаю, что только для записи 1 (биты 0-15 для установки, а 16-31 для сброса) , так и в коде у меня только запись единички в этот регистр или про BSRR я опять не правильно понимаю?
По поводу SR записью 0, а логическое & инвертированного TIM_SR_UIF разве не есть запись нолика?
Про счетчик циклов, как-то столкнулся с проблемкой, по поводу переменной счетчика. Пока не нарисовал ей __IO не работало, ну с тех пор так и привык. Сейчас проверил конкретно в данной программе , убрал __IO работает. Спасибо, записал на память, при случае буду изучать этот вопрос до полного понимания
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Самопроизвольное изменение значения переменной

Сообщение VladislavS »

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]Компилятор в праве удалить любые переменные и операции с ними - если они ограничиваются областью видимости функции.
Область видимости функции ограничена скобками самой функции, буквально. По этому любая запись во внешнюю переменную будет безусловной, и на неё необязательно вешать __IO.[/uquote]Я немного понимаю в программировании. Но из этого вообще ничего не понял.

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]Постарайся раскидать функции по уровням и типу действия. Например RCC_Cfg() и GPIO_test_cfg() относятся к предварительным настройкам МК, этим функциям самое место в SystemInit() или что-то подобное - то вызывается до main.c.[/uquote]Тут, пожалуй, соглашучь. Но для любителя это не обязательно. Считать что "жизнь начинается с main" для С-программиста вполне нормальная практика. Качество кода это как-то заметно не ухудшает.

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]WS2812_init() и всё связанное с WS2812 - должно иметь свой файл, без лишних торчащих ушей.[/uquote]Иметь файл, торчащие уши... Вы о чём вообще? Человек и так не профи, да ещё жаргон какой-то понять надо.

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]Делать буфер для WS2812 глобальным - очень плохая идея, он должен быть виден там где используется, и больше нигде.[/uquote]А каки же как не глобальным он должен быть? Вы, наверное, глобальность с областью видимости путаете? Так тут одна единица трансляции, куда что прятать?

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390331#p4390331"]Тогда станет доступной возможность оперативно менять количество светодиодов, без смены алгоритма и переписывания части кода.[/uquote]Это зависит от алгоритма, а не от глобальности или области видимости буфера.

По мне, так только запутали бедного ТС. Дайте ему с алгоритмом для начала разобраться.

Добавлено after 4 minutes 29 seconds:
[uquote="mab72",url="/forum/viewtopic.php?p=4390336#p4390336"]Про BSRR я знаю, что только для записи 1 (биты 0-15 для установки, а 16-31 для сброса) , так и в коде у меня только запись единички в этот регистр или про BSRR я опять не правильно понимаю?
По поводу SR записью 0, а логическое & инвертированного TIM_SR_UIF разве не есть запись нолика?[/uquote]Ну тогда всё ещё хуже. Стоит открыть учебник по С раздел про операторы |= и &= - удивитесь.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Re: Самопроизвольное изменение значения переменной

Сообщение mab72 »

Ой... ваще поплыл.
Для начала:
запись GPIOC->BSRR |= GPIO_BSRR_BR0 сбросит нулевой бит в регистре, а GPIOC->BSRR |= GPIO_BSRR_BS0 установит нулевой бит в регистре. Это я правильно понимаю?

Добавлено after 5 minutes 10 seconds:
Ида по поводу (void)tmp это когда я переписывал инициализацию с автоматически сгенерированного CubeMX файла там используется библиотека LL, а мне нравится CMSIS. Так там и была эта конструкция, задержка после включения.

Добавлено after 9 minutes 35 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=4390226#p4390226"]Разаер uint8_t led_buf[BUF_LEN] равен 25 элементов(байт). Что будет тут buf[k*24+i] = WS2812_0; при k=1 и i=1?[/uquote]

Разобрался, заработало!
Осталось избавиться от анафемы и снять вечное проклятие.

Огромное спасибо!
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Самопроизвольное изменение значения переменной

Сообщение КРАМ »

[uquote="mab72",url="/forum/viewtopic.php?p=4390343#p4390343"]Ой... ваще поплыл.
Для начала:
запись GPIOC->BSRR |= GPIO_BSRR_BR0 сбросит нулевой бит в регистре, а GPIOC->BSRR |= GPIO_BSRR_BS0 установит нулевой бит в регистре. Это я правильно понимаю?[/uquote]
Нет, не правильно понимаете.
Написанное вами выражение означает не запись единицы, а последовательное выполнение: ЧТЕНИЕ РЕГИСТРА (который возвращает только нули, ибо не подлежит чтению,), логическая функция результата чтения с маской и запись обратно в регистр.
НАМЕКАЮ. Запись в такие регистры должна иметь ТОЛЬКО ПРИСВОЕНИЕ ЗНАЧЕНИЯ. Без какой либо математики с содержимым этого регистра.
Последний раз редактировалось КРАМ Пт мар 24, 2023 08:44:05, всего редактировалось 2 раза.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Самопроизвольное изменение значения переменной

Сообщение VladislavS »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4390346#p4390346"](который возвращает только нули, ибо не подлежит чтению,)[/uquote]Это где-то написано/гарантировано? Я бы на месте разработчиков контроллера возвращал рандомное значение. Чисто поприкалываться над "любителями CMSIS".
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Самопроизвольное изменение значения переменной

Сообщение КРАМ »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4390348#p4390348"]Чисто поприкалываться над "любителями CMSIS".[/uquote]
Согласен. Не гарантировано. Но возвращает. Итальянцы с французами не понимают таких приколов.
Однако, я один из "любителей CMSIS". Это никак не мешает читать RM и не делать таких ошибок.
А если точнее, то мне, как радиоинженеру, не близки ваши предпочтения как программиста. И это тоже не мешает мне успешно делать проекты.
ЗЫ. В догон. Я нынче предпочитаю Artery европейским МК. По известным причинам.
А там регистры объявлены как битовые структуры. То есть не надо писать с масками.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Re: Самопроизвольное изменение значения переменной

Сообщение mab72 »

То есть правильно будет GPIOB->BSRR = GPIO_BSRR_BS0 для установки, а для сброса GPIOB->BSRR = GPIO_BSRR_BR0. Ну и по SR TIM17->SR = ~TIM_SR_UIF.
Мне кажется я смог избавиться от анафемы и вечного проклятия. Спасибо.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Самопроизвольное изменение значения переменной

Сообщение VladislavS »

[uquote="mab72",url="/forum/viewtopic.php?p=4390353#p4390353"]То есть правильно будет GPIOB->BSRR = GPIO_BSRR_BS0 для установки, а для сброса GPIOB->BSRR = GPIO_BSRR_BR0.[/uquote]Конечно. Для закрепления результата посмотрите ассемблерный листинг с |= и с =.

[uquote="mab72",url="/forum/viewtopic.php?p=4390353#p4390353"]Ну и по SR TIM17->SR = ~TIM_SR_UIF.[/uquote]Так можно, но так ведь проще SR TIM17->SR = 0; Опять же, загляните в листинг.

[uquote="mab72",url="/forum/viewtopic.php?p=4390353#p4390353"]Мне кажется я смог избавиться от анафемы и вечного проклятия.[/uquote]Тут только трёхкратное прочтение K&R спасёт.
mab72
Открыл глаза
Сообщения: 49
Зарегистрирован: Сб мар 26, 2016 01:01:31

Re: Самопроизвольное изменение значения переменной

Сообщение mab72 »

Что? Опять? Как так-то?
SR TIM17->SR = 0 я понимаю это обнулит весь регистр (сбросит все флаги), а если мне надо обнулить определенный флаг?
SR TIM17->SR = ~TIM_SR_UIF Это не сработает?
a797945
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

Re: Самопроизвольное изменение значения переменной

Сообщение a797945 »

зачем хранить прошлогодние флаги?
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Самопроизвольное изменение значения переменной

Сообщение КРАМ »

Маска на сброс флага это нормально. Не путайте человека.
Учитывая, что вектора прерываний таймеров не избирательны на флаги, на входе в обработчик ставят семафор, который эти флаги и проверяет.
Немаскируемый сброс флагов приведет к потере событий.
a797945
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

Re: Самопроизвольное изменение значения переменной

Сообщение a797945 »

дык, обычно то, берешь SR проверяешь нужный флаг, проверяешь дополнительный (типа "не произошло ли еще что-то", что нужно учитывать). и зачем оставлять SR у таймера?

у более сложной периферии, вероятно, так огульно не следует, но (честно говоря) я о ней сразу не подумал - перед глазами был TIM.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25122
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Самопроизвольное изменение значения переменной

Сообщение КРАМ »

[uquote="a797945",url="/forum/viewtopic.php?p=4390374#p4390374"]дык, обычно то, берешь SR проверяешь нужный флаг, проверяешь дополнительный[/uquote]
А не проще и удобнее в начале каждой секции семафора проверять и сбрасывать единственный флаг?
В чем проблема? Что малочитабельного в маске? Дело ведь не в маске, а в месте ее применения. Не стоит же всех считать идиотами не способными сообразить, что в семафоре проверяется и сбрасывается флаг сгенерировавший прерывание. Тем более, что маска при проверке флага и при его сбросе идентична.
Ну и немаловажна латентность между проверкой флага и его сбросом, если сброс выполняется "оптом". Так и пропустить событие несложно.
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

Re: Самопроизвольное изменение значения переменной

Сообщение AVI-crak »

VladislavS писал(а): Я немного понимаю в программировании. Но из этого вообще ничего не понял.
Не ожидал :shock: .
Функцию придумали для выполнения полезной работы над внешними данными. Любая бурная псевдо-деятельность без полезного выхлопа - полностью удаляется компилятором, потому как не влияет на внешнюю память.

Добавлено after 7 minutes 51 second:
[uquote="КРАМ",url="/forum/viewtopic.php?p=4390370#p4390370"]Маска на сброс флага это нормально. Не путайте человека.
Учитывая, что вектора прерываний таймеров не избирательны на флаги, на входе в обработчик ставят семафор, который эти флаги и проверяет.
Немаскируемый сброс флагов приведет к потере событий.[/uquote]
Нет, в таких случаях нужно явно читать весь пакет флагов в переменную, сразу сбрасывать все флаги, и уже потом разбираться с флагами из сохранения. Потому как периферия в большинстве случаев живёт своей жизнью, и тактируется автономно. Пока чего-то там делаешь с одним флагом - срабатывают ещё несколько, после чего всё падает. Не надо гонятся за хвостом, это бесполезно.
Это прерывание, ничего страшного - оно просто сработает ещё раз, но теперь обработка будет чётко по алгоритму, сверху вниз.
Ответить

Вернуться в «ARM»