STM32 новичку в ARM что к чему
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
инвертирование всех битов выполнить инвертивананием передаваемого байта перед передачей.
Единицу на выходе можно получить деактивацией модуля и подтяжкой линии к всс
Единицу на выходе можно получить деактивацией модуля и подтяжкой линии к всс
Подпись убрал вместе с автором. aen
- Реклама
Re: STM32 новичку в ARM что к чему
Как-то криво все это... Я думал, там аппаратно предусмотрена инверсия, но значит я правильно понял, что такой возможности там нет.
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
Я не совсем понимаю, для чего вам инвертировать сигнал? Выход с OD работает так же как обычный, только P-мосфет выхода не задействован. Роль лог.единицы будет выполнять внешняя подтяжка к всс.
Аппаратно инвертируется сигнал только в таймерах. Инвертирован аппаратно может быть сигнал клока в интерфейсах. Но сигнал данных не инвертируется.
Аппаратно инвертируется сигнал только в таймерах. Инвертирован аппаратно может быть сигнал клока в интерфейсах. Но сигнал данных не инвертируется.
Подпись убрал вместе с автором. aen
Re: STM32 новичку в ARM что к чему
Надо согласовать 3,3В выход МК с другой микросхемой, питающейся от 5В (у неё миниммально допустимый уровень лог. 1 - 3,6В). Вот и хотел обойтись одним транзистором вместо двух. Но вопрос уже отпал. Подумав, я от этой идеи отказался и решил поискать нормальный преобразователь уровня в виде микросхемы с выходом пуш-пулл, т. к. с 1 транзистором и подтягивающим резистором завалю фронты при работе на кабель длиной около метра и получу глюки.
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
А разве встроенный режим выхода Open Drain самого микроконтроллера не подходит??? Регистр OTYPER, бит с номеров выхода = 1. Выход микроконтроллера может держать довольно высокий входной ток даже в десяток миллиампер, и даже спокойно принимать пятивольтовый сигнал при выборе FT-вывода. FT - Five-tolerant, подключение к пятивольтовой логике. Согласование уровней получается без каких-либо внешних транзисторов или преобразователей. Только резистор до 5 В питания.
А передача синхронных сигналов по метровому кабелю не подразумевает высоких частот.
А передача синхронных сигналов по метровому кабелю не подразумевает высоких частот.
Подпись убрал вместе с автором. aen
- Реклама
Re: STM32 новичку в ARM что к чему
Делаю крайне тривиальную вещь, но не могу понять что за грабли я давлю. Вещь простая TIM15 400 раз в секунду дергает триггер, который запускает ADC, тот в свою очередь, последовательно считывает 8 входов и результат через DMA1_Channel1 переносится в ОЗУ, а по окончании должно вызваться прерывание. Вот с обработкой прерывания у меня и проблема. Поставил маску на прерывание - всё работает. Стоит разрешить прерывание по окончании трансфера (TCIE) как всё "виснет". Что именно не работает пока не понимаю, но похоже, что нет даже прерывания от TIM15 (там у меня должен "мигать" светодиод).
Тут инициализация. Использую еще DMA1_Channel5 для работы через SPI 7-сегментного дисплея, тоже инициируется от TIM15.
В обработчике прерывания от DMA пробовал даже устанавливать все 5 DMA_IFCR_CGIFx - ничего не помогает. Но если убрать DMA_CCR_TCIE - всё работает - прерывания от TIM15 есть, данные в ОЗУ вижу.
Кристалл stm32F051Проблему решил... Ошибка в названии функции обработчика прерывания.
Разрешаю DMA1_Channel1_IRQn, а обработчик написал DMA1_IRQHandler. (idioto!) Надо было
Спойлер
Вот обработчики.Код: Выделить всё
void TIM15_IRQHandler(void) {
TIM15->SR &= (uint32_t) (~TIM_SR_UIF);
flag.tick = 1;
if (kbddelay) kbddelay--;
GPIOC->ODR ^= (1<<3);
}
void DMA1_IRQHandler(void) {
if (DMA1->ISR & DMA_ISR_TCIF1) {
DMA1->IFCR = DMA_IFCR_CTCIF1;
flag.photo_data_ready = 1;
}
}Код: Выделить всё
// Êàíàë ÏÄÏ äëÿ äèíàìè÷åñêîé èíäèêàöèè (èç ÎÇÓ â SPI)
DMA1_Channel5->CPAR = (uint32_t) (&(SPI1->DR)); // (3)
DMA1_Channel5->CMAR = (uint32_t)(vframe.videobyte); // (4)
DMA1_Channel5->CNDTR = 4; // (5)
DMA1_Channel5->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC | DMA_CCR_DIR; // (6)
DMA1_Channel5->CCR |= DMA_CCR_EN; // (7)
// Êàíàë ÏÄÏ äëÿ ÀÖÏ:
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; /* (2) */
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */
DMA1_Channel1->CMAR = (uint32_t)(photo_sensor); /* (4) */
DMA1_Channel1->CNDTR = 8; // NUMBER_OF_ADC_CHANNEL; /* (5) */
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE; /* (6) */
DMA1_Channel1->CCR |= DMA_CCR_EN; /* (7) */
// TIM15 - timebase À òàê æå îòîáðàæåíèå íà 7-ñåãìåíòíûé èíäèêàòîð
TIM15->CR1 &= ~TIM_CR1_CEN ; // disable timer
TIM15->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1NE | TIM_CCER_CC2E | TIM_CCER_CC2NE) ; // CCP output disable
TIM15->PSC = 0;
TIM15->ARR = 20000-1; // 8MHz / 20000 = 400Hz
TIM15->CCR1 = 19991; // ñòðîá çàïèñè 1 ìêñ (20000-1-19991)/8 = 1
TIM15->CR1 |= TIM_CR1_URS | TIM_CR1_ARPE ; // only overfow generate UEV
TIM15->DIER |= TIM_DIER_UIE; // Update interrupt 1 for enable.
TIM15->DIER |= TIM_DIER_CC1DE; /* (2) */
TIM15->CCMR1 |= TIM_CCMR1_OC1M | TIM_CCMR1_OC1PE ; // ñòðîá load
TIM15->CCMR1 |= TIM_CCMR1_OC2M | TIM_CCMR1_OC2PE ; // ýòî äëÿ ñèãíàëà blank - åùå íàäî óòî÷íèòü ðåæèì
TIM15->BDTR |= TIM_BDTR_MOE ; // main output enable
TIM15->CCER |= (TIM_CCER_CC1E) ; // CCP output enable (load)
TIM15->CCER |= (TIM_CCER_CC2E) ; // blank
TIM15->CR1 |= TIM_CR1_CEN ; //enable timer
// ADC calibration
if ((ADC1->CR & ADC_CR_ADEN) != 0) {
ADC1->CR &= (uint32_t)(~ADC_CR_ADEN);
}
ADC1->CR |= ADC_CR_ADCAL;
while ((ADC1->CR & ADC_CR_ADCAL) != 0);
ADC1->CFGR2 |= ADC_CFGR2_CKMODE_0; // pclk/2
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL3| \
ADC_CHSELR_CHSEL4 | ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL6 | ADC_CHSELR_CHSEL7;
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG;
ADC1->CFGR1 |= ADC_CFGR1_CONT | ADC_CFGR1_EXTEN_0 | ADC_CFGR1_EXTSEL_2 ; // TIM15_TRG0 and Rising edge. Continious
ADC1->CFGR1 |= ADC_CFGR1_RES_1 ; // 8 bit resolution right alighned
ADC1->CR |= ADC_CR_ADEN;
while ((ADC1->ISR & ADC_ISR_ADRDY) == 0)
ADC1->CR |= ADC_CR_ADSTART ;
TIM15->CR2 |= TIM_CR2_MMS_1 ; // trigger update event
NVIC_EnableIRQ(TIM15_IRQn);
NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* (1) */
__enable_irq();
Кристалл stm32F051
Разрешаю DMA1_Channel1_IRQn, а обработчик написал DMA1_IRQHandler. (idioto!) Надо было
Код: Выделить всё
void DMA1_Channel1_IRQHandler(void) А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Jman
- Мучитель микросхем
- Сообщения: 414
- Зарегистрирован: Ср янв 26, 2011 13:43:30
- Откуда: С того берега моря
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Всем привет. Ребят помогите пожалуйста реализовать бегущий огонь на STM32. Я недавно начал изучать, у меня есть VlDiscovery, хочу поиграться с GPIO, для начала. Почитав различные блоги, решил использовать Keil, программировать без использования SPL пока, на голом CMSIS. Набросал небольшой код, где включаю тактирование и выставляю порты и по нажатии кнопки включаю четыре светодиода(два на плате, два отдельно). А вот как сделать битовые сдвиги ума не приложу. Так же хотелось бы в дальнейшем привязать все к прерыванию, без цикличной функции задержки... Мне нужен пример, что бы я смог понять, потому что самому очень трудно разобраться. Вот мой код, сильно не ругайтесь...
Код: Выделить всё
/****************************gpio.c*********************************/
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#define PC8_ON GPIOC->BSRR = GPIO_BSRR_BS8
#define PC8_OFF GPIOC->BSRR = GPIO_BSRR_BR8
#define PC9_ON GPIOC->BSRR = GPIO_BSRR_BS9
#define PC9_OFF GPIOC->BSRR = GPIO_BSRR_BR9
#define PC10_ON GPIOC->BSRR = GPIO_BSRR_BS10
#define PC10_OFF GPIOC->BSRR = GPIO_BSRR_BR10
#define PC11_ON GPIOC->BSRR = GPIO_BSRR_BS11
#define PC11_OFF GPIOC->BSRR = GPIO_BSRR_BR11
//!*******************************************************************/
// GPIOC->BSRR=(GPIO_BSRR_BS8|GPIO_BSRR_BS9); Set two bits in PORT;
// GPIOC->BSRR=(GPIO_BSRR_BR8|GPIO_BSRR_BR9); Reset two bits in PORT;
//
void GpioInit(void);
void Delay(void);
void TIM2_IRQHandler(void);
void TIM2_init(void);
uint8_t i=0;
int main(int argc, char* argv[])
{
GpioInit();
for(;;)
{
if ((GPIOA->IDR & GPIO_IDR_IDR0))
{
PC8_ON; // Set PC8 bit
}else PC8_OFF;
Delay();
//GPIOC->BSRR = GPIO_BSRR_BR9; // Reset PC9 bit
PC9_ON; // Set PC9 bit
Delay();
//GPIOC->BSRR = GPIO_BSRR_BR8; // Reset PC8 bit
PC10_ON; // Set PC10 bit
Delay();
PC11_ON; // Set PC11 bit
}
}
void GpioInit(void)
{
RCC->APB2ENR = (RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPAEN); // Enable PORTC Periph clock
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Enable TIM2 Periph clock
//RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //разрешаем тактирование порта A
//вход с подтяжкой к -, в Discovery кнопка на плюсе.
GPIOA->CRL &= ~GPIO_CRL_CNF1;
GPIOA->CRL |= GPIO_CRL_CNF1_1;
GPIOA->ODR &= ~GPIO_ODR_ODR1;
// Clear PC8 and PC9 control register bits
GPIOC->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8 |
GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
// Configure PC8 and PC9 as Push Pull output at max 10Mhz
GPIOC->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE9_0;
// Clear PC10 and PC11 control register bits
GPIOC->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10 |
GPIO_CRH_MODE11 | GPIO_CRH_CNF11);
// Configure PC11 and PC11 as Push Pull output at max 10Mhz
GPIOC->CRH |= GPIO_CRH_MODE10_0 | GPIO_CRH_MODE11_0;
}
void Delay(void)
{
volatile uint32_t i;
for (i=0; i != 0x400000; i++); // Delay;
}
void TIM2_init(void)
{
TIM2->PSC = SystemCoreClock / 1000 - 1; // 1000 tick/sec
TIM2->ARR = 1000; // 1 Interrupt/sec (1000/100)
TIM2->DIER |= TIM_DIER_UIE; // Enable tim2 interrupt
TIM2->CR1 |= TIM_CR1_CEN; // Start count
NVIC_EnableIRQ(TIM2_IRQn); // Enable IRQ
}
void TIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_SR_UIF; //Clean UIF Flag
if (1 == (i++ & 0x1)) {
GPIOC->BSRR = GPIO_BSRR_BS8; // Set PC8 bit
GPIOC->BSRR = GPIO_BSRR_BR9; // Reset PC9 bit
} else {
GPIOC->BSRR = GPIO_BSRR_BS9; // Set PC9 bit
GPIOC->BSRR = GPIO_BSRR_BR8; // Reset PC8 bit
}
}
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
Используйте не регистр побитового доступа BSSR, а напрямую пишите в порт через регистр ODR.
for (int i=0; i<16; i++)
{
GPIOA->ODR = 0x0001<<i
}
это получится цикл со сдвигами единицы на i шагов влево. Причем, порт каждый раз будет полностью перезаписываться, благодаря чему получим бегущую единицу
for (int i=0; i<16; i++)
{
GPIOA->ODR = 0x0001<<i
}
это получится цикл со сдвигами единицы на i шагов влево. Причем, порт каждый раз будет полностью перезаписываться, благодаря чему получим бегущую единицу
Последний раз редактировалось Мурато Мяуконни Пн дек 26, 2016 20:46:42, всего редактировалось 1 раз.
Подпись убрал вместе с автором. aen
- Jman
- Мучитель микросхем
- Сообщения: 414
- Зарегистрирован: Ср янв 26, 2011 13:43:30
- Откуда: С того берега моря
- Контактная информация:
Re: STM32 новичку в ARM что к чему
О! Круто! Спасибо! Но например если мне нужно будет сделать мигалку после бегущего огня, снова переходить к старой песни. уходя от ODR? Или можно использовать маску по & или | для ODR?
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
ODR перезаписывает целиком весь порт, а BSRR влияет только на один бит порта.
Запись вида GPIOA->ODR |= 0x0001 выполняет операцию ИЛИ с предыдущим содержимым ODR порта. То есть, можно добавить "1" в указанных позициях.
Запись вида GPIOA->ODR &= 0x0001 выполняет операцию И с ODR - оставляет единицу только в указанных позициях.
А GPIOA->ODR &= ~0x0001 наоборот, обнуляет бит в указанных позициях.
В отличие от ODR, BSRR или BRR влияет только на один бит и независимо от предыдущего состояния порта. То есть, нельзя выполнить операции ИЛИ, И с предыдущим содержимым
Запись вида GPIOA->ODR |= 0x0001 выполняет операцию ИЛИ с предыдущим содержимым ODR порта. То есть, можно добавить "1" в указанных позициях.
Запись вида GPIOA->ODR &= 0x0001 выполняет операцию И с ODR - оставляет единицу только в указанных позициях.
А GPIOA->ODR &= ~0x0001 наоборот, обнуляет бит в указанных позициях.
В отличие от ODR, BSRR или BRR влияет только на один бит и независимо от предыдущего состояния порта. То есть, нельзя выполнить операции ИЛИ, И с предыдущим содержимым
Подпись убрал вместе с автором. aen
Re: STM32 новичку в ARM что к чему
Ничто не мешает пользоваться групповыми операциями через маску, т.к. установка бита(ов) в BSRR имеет приоритет перед сбросом бита(ов). В большинстве случаев пользоваться BSRR более предпочтительно.Мурато Мяуконни писал(а):ODR перезаписывает целиком весь порт, а BSRR влияет только на один бит порта.
- Jman
- Мучитель микросхем
- Сообщения: 414
- Зарегистрирован: Ср янв 26, 2011 13:43:30
- Откуда: С того берега моря
- Контактная информация:
Re: STM32 новичку в ARM что к чему
Можете привести пример, например на PORTC подать на пины PC1, PC2, PC5, PC11 лог 1, на остальных лог 0. Я теорию понимаю, но не знаю как правильно реализовать. На примере было более понятнее.scorpi_0n писал(а):Ничто не мешает пользоваться групповыми операциями через маску, т.к. установка бита(ов) в BSRR имеет приоритет перед сбросом бита(ов). В большинстве случаев пользоваться BSRR более предпочтительно.Мурато Мяуконни писал(а):ODR перезаписывает целиком весь порт, а BSRR влияет только на один бит порта.
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
-
Мурато Мяуконни
- Прорезались зубы
- Сообщения: 203
- Зарегистрирован: Сб ноя 19, 2016 21:05:48
Re: STM32 новичку в ARM что к чему
Можем.
GPIOC->BSRR = 0xFFFF0000 | GPIO_BSRR_BS_1 | GPIO_BSRR_BS_2 | GPIO_BSRR_BS_5 | GPIO_BSRR_BS_11;
Как правильно написал scorpion, приоритет имеет установка битов. 0xFFFF0000 сбрасывает биты во всех позициях, кроме тех, где указано GPIO_BSRR_BS_хх
Добавлено after 29 minutes 44 seconds:
И еще пару моментов, по вашему коду.
Поскольку вы только начинаете изучать, и до операционных систем вам еще как до Китая, то в функции main вам нет необходимости использовать какие-бы то ни было параметры (текст в скобках). Запись void main (void) вполне подходит.
GPIOC->BSRR = 0xFFFF0000 | GPIO_BSRR_BS_1 | GPIO_BSRR_BS_2 | GPIO_BSRR_BS_5 | GPIO_BSRR_BS_11;
Как правильно написал scorpion, приоритет имеет установка битов. 0xFFFF0000 сбрасывает биты во всех позициях, кроме тех, где указано GPIO_BSRR_BS_хх
Добавлено after 29 minutes 44 seconds:
И еще пару моментов, по вашему коду.
Поскольку вы только начинаете изучать, и до операционных систем вам еще как до Китая, то в функции main вам нет необходимости использовать какие-бы то ни было параметры (текст в скобках). Запись void main (void) вполне подходит.
Подпись убрал вместе с автором. aen
Re: STM32 новичку в ARM что к чему
С новым годом коты!
Такой вопрос: в F0 довольно странно оговорено питание аналоговой части - AVCC может быть больше или равно питанию и при этом должно подаваться первым!
Но ведь обычно аналоговую часть питают через фильтр (резистор или дроссель в разрыв цепи между VCC и AVCC) и питание там появляется какраз после цифровой части, т. к. заряжается блокировочный конденсатор через фильтрующий резистор или сопротивление дросселя. И как тут быть? Неужели диод ставить параллельно резистору?
Еще как-то совсем мутно в даташите сказано про ИОН. Написано только что он может быть или внутренний, или AVCC. А если я включаю внутренний, то какому напряжению будет соответствовать код 0xFFF ?
В итоге нашел такую замечательную микросхему: SN74LVC1T45. Маленькая, в корпусе SOT23-6, при желании может быть двунаправленной, имеет 2 питания и решает проблему порядка подачи питания (при отдельном питании каждого из устройств), можно купить, стоит всего 15 руб.aam писал(а):Надо согласовать 3,3В выход МК с другой микросхемой, питающейся от 5В
Такой вопрос: в F0 довольно странно оговорено питание аналоговой части - AVCC может быть больше или равно питанию и при этом должно подаваться первым!
Еще как-то совсем мутно в даташите сказано про ИОН. Написано только что он может быть или внутренний, или AVCC. А если я включаю внутренний, то какому напряжению будет соответствовать код 0xFFF ?
Насколько помню, в даташите даже написано, что только такой вариант гарантирует атомарность операции изменения состояния вывода порта.scorpi_0n писал(а): В большинстве случаев пользоваться BSRR более предпочтительно.
Re: STM32 новичку в ARM что к чему
Напряжению AVCC.aam писал(а):А если я включаю внутренний, то какому напряжению будет соответствовать код 0xFFF ?
Внутренний ИОН подключается в одному из входов мультиплексора АЦП, а не к Vref.
Re: STM32 новичку в ARM что к чему
А зачем этот ИОН тогда вообще нужен если он, оказывается не ИОН даже? Каким образом он влияет на показания АЦП?
Re: STM32 новичку в ARM что к чему
Измерив напряжение ИОН можно вычислить напряжение AVCC, зная которое несложно вычислить напряжения на входах АЦП.
Re: STM32 новичку в ARM что к чему
Во бред! Это получается, перед каждым элементарным преобразованием я должен сначала измерить Vref, а потом уже то, что мне надо, после сравнить все это дело, внести поправку и тогда я могу считать, что то, что я померял - не чушь!
Непонимаю, неужели нельзя было сделать по-человечески как в АВР?
Есть отдельная нога - и что хочешь, то и подавай на неё в зависимости от степени серьезности решаемой задачи. А тут производитель вставил 12-разрядный АЦП и не реализовал такую простую вещь, как возможность использования нормальной опоры.
Re: STM32 новичку в ARM что к чему
В 100+ выводных корпусах Vref выведен наружу.
Re: STM32 новичку в ARM что к чему
Да я знаю, но только иногда бывает нужно 20 выводов и юзабельный АЦП. Классический пример - измерительные головки - там сочетаются высокие требования к точности с малым числом ног и ценой МК. Да любой простой измерительный прибор если взять - нужна очень высокая точность и немного ног для индикатора и кнопок.
А у АВР даже в Меге 8 внешняя нога VREF есть (как у Тинек - не помню уже).
А у АВР даже в Меге 8 внешняя нога VREF есть (как у Тинек - не помню уже).


