31.08.2011, 08:58
|
|
Вид на жительство
Регистрация: 05.07.2006
Адрес: Tashkent
Сообщений: 454
Сказал спасибо: 24
Сказали Спасибо 67 раз(а) в 44 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от BolshoyK
|
Вопросом озадачился, где определяется, какой стартап использовать ? Желательно поточнее место укажите, плиз...
|
1. Когда создаете проект, Кейл вежливо спрашивает копировать ли стартап(свой кейловский) в папку проекта.
2. Меня не всегда устраивает его стартап, поэтому удаляем его из проекта и заново подключаем новый нужный нам стартап.
3. В свойствах проекта(Project-›Options for Target"ваш проект") выбираем вкладку С/С++ и Asm. Тыкаем на кнопку Include Paths и вводим пути для подключенных файлов.
|
|
|
|
31.08.2011, 09:22
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2009
Сообщений: 609
Сказал спасибо: 37
Сказали Спасибо 140 раз(а) в 72 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
uk8amk, Про с нуля и про руками добавить - я в курсе. Я спрашиваю как выбрать нужный, если их уже подкючено в примере много. Где признак того, какой из стартапов будет использоваться ?
|
|
|
|
31.08.2011, 10:58
|
|
Прохожий
Регистрация: 15.10.2010
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Друзья, пытаюсь разобраться с ШИМ.
Пишу такой код инициализации:
Код:
|
DBGMCU-›CR |= DBGMCU_CR_DBG_TIM17_STOP;
// init clock
RCC-›CFGR =RCC_CFGR_SW_PLL|RCC_CFGR_PLLSRC_PREDIV1|RCC_CFGR_ PLLMULL_0; //PLL 3x from HSE, no divided, sysclk from PLL
RCC-›CFGR2 =0x0000;
RCC-›CR =RCC_CR_PLLON|RCC_CR_HSEON;
while ((RCC-›CR&RCC_CR_HSERDY)==0); //whait for HSE ready
#define GEN_TMR TIM17
#define CH_REG CCR1
#define GEN_PORT GPIOB
#define GEN_PIN 9
#define GEN_CR CRH
RCC-›APB2ENR |= RCC_APB2ENR_TIM17EN; //setup clock to tim17
RCC-›APB2ENR |= RCC_APB2ENR_IOPBEN;; //setup clock to portB
GEN_PORT-›ODR = 0x0;
GEN_PORT-›GEN_CR &= ~(0xF‹‹((GEN_PIN&0x7)*4));
GEN_PORT-›GEN_CR |= 0xB‹‹((GEN_PIN&0x7)*4); // setup alternate output
GEN_TMR-›CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
GEN_TMR-›CCER |=(TIM_CCER_CC1E); //Capture/Compare 1 output enable
GEN_TMR-›BDTR |=(TIM_BDTR_OSSR|TIM_BDTR_MOE); //main output enable
GEN_TMR-›PSC = 24-1; // 1tic = 24 Mhz/24 -› 1us;
GEN_TMR-›ARR = 1000-1; // period = 64 us
GEN_TMR-›CH_REG = 200; //duration
GEN_TMR-›RCR = 0x0; //repetition counter
GEN_TMR-›SR = 0x0; //clear all status |
После прохождения этого кода, до включения таймера (бит EN в CR1), на выходе CCR1 (PB9) устанавливается высокий уровень. (Смотрю на stm32 VL discovery). По всем докам должен быть низкий уровень в idle режиме.
Причем если выставить бит CC1P в CCER, то после инициализации уровень низкий, но в рабочем режиме инвертируется выход, но меня это не устраивает.
В чем может быть проблема?
|
|
|
|
31.08.2011, 18:11
|
|
Гражданин KAZUS.RU
Регистрация: 25.11.2009
Сообщений: 609
Сказал спасибо: 37
Сказали Спасибо 140 раз(а) в 72 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Итак, продолжаю мучить виртуальный ком порт. Почти все победил. Вывод на комп работает: эхо терминала и по нажатию кнопки отправляется строка "Test !!!".
Осталось корректно оформить процедурку приема с компа данных, типа как это сделано для USART. Есть у кого идеи ?
Во текущее состояние проекта: ftp://serg22.sibgtu.ru/radio/VirtualCOMPort_v1.rar
Вот функция в файле usb_endp.c которая принимает данные, и тут же отправляет их обратно, типа терминал.
void EP3_OUT_Callback(void)
{
uint16_t USB_Rx_Cnt;
// Get the received data buffer and update the counter
USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);
// USB data will be immediately processed, this allow next USB traffic being
//NAKed till the end of the USART Xfer
USB_To_USART_Send_Data(USB_Rx_Buffer, USB_Rx_Cnt);
// Enable the receive of data on EP3
SetEPRxValid(ENDP3);
}
Надо ее заменить на что-то, что будет возвращать данные получаемые с компа, но не могу придумать как лучше. Кольцевой буфер... функция которая будет разрешать приет когда прога готова принимать... или что-то еще ? Короче застрял на идее. Жду толковых советов или иной помощи.
|
|
|
|
31.08.2011, 23:10
|
|
Гражданин KAZUS.RU
Регистрация: 12.10.2009
Сообщений: 576
Сказал спасибо: 30
Сказали Спасибо 138 раз(а) в 110 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
BolshoyK,
Все очень просто. Буфер делать обычный. После поступления данных вычитывать в него endpoint и обрабатывать данные. В USB не бывает переполнения буфера. Если хост высылает пакет, а endpoint buffer еще не вычитан, то микроконтроллер должен послать nack и хост повторит отсылку пакета позднее. То же с чтением: попытка чтения пустого endpoint выдаст хосту nack и хост повторит попытку чтения позже. Со сторны софта на компе
это будет выглядет как задержка в отсылке/приеме данных.
|
|
|
|
31.08.2011, 23:15
|
|
Гражданин KAZUS.RU
Регистрация: 12.10.2009
Сообщений: 576
Сказал спасибо: 30
Сказали Спасибо 138 раз(а) в 110 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от SasaVitebsk
|
- убей, не пойму. memcpy и есть простое копирование. Библиотечное вылизанное.
|
У тупых компиляторов оно будет "библиотечно вылизанное". А GCC проверяет размер блока данных и если блок короткий, то вместо memcpy вставляются несколько ассемблерных инструкций пересылки данных. У него под это даже специальная опция есть .
|
|
|
|
04.09.2011, 18:53
|
|
Временная регистрация
Регистрация: 09.02.2007
Сообщений: 91
Сказал спасибо: 0
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Кто-нибудь пробовал фиксировать факт пропадания питания в Backup-регистре ? Это вообще возможно?
|
|
|
|
04.09.2011, 23:05
|
|
Гражданин KAZUS.RU
Регистрация: 12.10.2009
Сообщений: 576
Сказал спасибо: 30
Сказали Спасибо 138 раз(а) в 110 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
А в чем проблемы? Прерывание на brown-out и фиксируем...
|
|
|
|
05.09.2011, 07:11
|
|
Временная регистрация
Регистрация: 09.02.2007
Сообщений: 91
Сказал спасибо: 0
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от tanq
|
А в чем проблемы? Прерывание на brown-out и фиксируем...
|
А успеет процессор сделать это? Питание-то на всем устройстве пропадает. Если можно, то примерчик кода.
|
|
|
|
05.09.2011, 11:39
|
|
Частый гость
Регистрация: 18.01.2011
Сообщений: 21
Сказал спасибо: 5
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Изучаем STM32 Cortex M3
Задумка такая- он по TRGO от таймера3 начинает обрабатывать АЦП, которое передается в дма , которое передает значение в буфер с которым я потом могу работать и обрабатывать значения. По окончанию передачи дма рождает прерывание в которое можно сунуть либо сам обработчик либо лучше флаги для оного. Надо сделать два канала - так как делаю сейчас не получается и с одним.
Если смотреть в память, то пишет какую-то муть. В Watch в буфере нули. В прерывание не уходит вовсе.
Цитата:
|
/************************************************** ************
STM32VLDiscovery (STM32F100RB)
PA0-кнопка пользовательская
PС4-вход АЦП (CH14)
PC5-вход АЦП (CH15)
PC8-светодиод синий
PC9-светодиод зеленый
PB5- резистор 400Ом open-drain
PD2- выход 5 кОм или 300Ом(снизу)
PB14- выход 300 Ом (снизу)
PA2-PWM выход
LCD: (5кОм open-drain 5В)
- DB4 = PC3
- DB5 = PC2
- DB6 = PC1
- DB7 = PC0
- E = PC12
- RW = PC11
- RS = PC10 */
/************************************************** *************/
#include "stm32F10x.h"
#include "LCD.h"
#define DMA_BUF_LEN 256
/*Глобальные переменные*/
u32 tmp;
u32 statement; // Состояние программы.
u32 i;//Счетчик
u32 first;//Первый раз
unsigned int adc_buf[DMA_BUF_LEN];
/***********************Функции инициализации********************/
uint32_t RCC_Init(void) //Инициализация системы тактирования
{
uint32_t StartUpCounter = 0, HSEStatus = 0;
/* Конфигурацяи SYSCLK, HCLK, PCLK2 и PCLK1 */
/* Включаем HSE */
RCC-›CR |= ((uint32_t)RCC_CR_HSEON);
/* Ждем пока HSE не выставит бит готовности либо не выйдет таймаут*/
do
{
HSEStatus = RCC-›CR & RCC_CR_HSERDY;
StartUpCounter++;
}
while( (HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
if ( (RCC-›CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
/* Если HSE запустился нормально */
if ( HSEStatus == (uint32_t)0x01)
{
/* Включаем буфер предвыборки FLASH */
FLASH-›ACR |= FLASH_ACR_PRFTBE;
/* Конфигурируем Flash на 2 цикла ожидания */
/* Это нужно потому, что Flash не может работать на высокой частоте */
/* если это не сделать, то будет странный глюк. Проц может запуститься, но через пару */
/* секунд повисает без "видимых причин". Вот такие вот неочевидные вилы. */
FLASH-›ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH-›ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
/* AHB Prescaler = 1 */
RCC-›CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
/* APB2 Prescaler = 1 */
RCC-›CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
/* APB1 Prescaler = 2 */
RCC-›CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* Конфигурируем множитель PLL configuration: PLLCLK = HSE * 2 = 16 MHz */
/* При условии, что кварц на 8МГц! */
/* RCC_CFGR_PLLMULL2 - множитель на 2. Если нужна другая частота, не 16МГц */
/* то выбираем другой множитель. */
/* Сбрасываем в нули прежнее значение*/
RCC-›CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
/* А теперь накатываем новое */
/* RCC_CFGR_PLLSRC_HSE -- выбираем HSE на вход */
/* RCC_CFGR_PLLMULL2 -- множитель 2 */
RCC-›CFGR |= (uint32_t)(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL5);
/* Все настроили? Включаем PLL */
RCC-›CR |= RCC_CR_PLLON;
/* Ожидаем, пока PLL выставит бит готовности */
while((RCC-›CR & RCC_CR_PLLRDY) == 0)
{
// Ждем
}
/* Работает? Можно переключать! Выбираем PLL как источник системной частоты */
RCC-›CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC-›CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Ожидаем, пока PLL выберется как источник системной частоты */
while ((RCC-›CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x0
{
// Ждем
}
}
else
{
/* Все плохо... HSE не завелся... Чего-то с кварцем или еще что...
Надо бы както обработать эту ошибку... Если мы здесь, то мы работаем
от HSI! */
lcd_clear();
lcd_print (" HSE down ");
}
return HSEStatus;
}
void Port_Init(void)//Инициализация портов
{
/* Подаем тактовые импульсы на PA,PC,PB,PD*/
RCC-›APB2ENR |= RCC_APB2ENR_IOPAEN|RCC_APB2ENR_IOPCEN|RCC_APB2ENR_ IOPBEN|RCC_APB2ENR_IOPDEN;
/*Настраиваем РА0 на вход*/
GPIOA-›CRL&=~GPIO_CRL_MODE0;
/*Пул-ап резисторы на РА0-можно не ставить на плате уже стоит*/
//GPIOA-CRL|=GPIO_CRL_CNF0;
/*PC8,PC9 на выход */
GPIOC-›CRH|= GPIO_CRH_MODE8|GPIO_CRH_MODE9;
/*PC8,PC9 -двухтактный выход общего назначения*/
GPIOC-›CRH &=~GPIO_CRH_CNF8;
GPIOC-›CRH &=~GPIO_CRH_CNF9;
/*PC0,PC1,PC2,PC3,PC10,PC11,PC12-на выход*/
GPIOC-›CRL|= GPIO_CRL_MODE0|GPIO_CRL_MODE1|GPIO_CRL_MODE2|GPIO_ CRL_MODE3;
GPIOC-›CRH|= GPIO_CRH_MODE10|GPIO_CRH_MODE11|GPIO_CRH_MODE12;
/*PC0,PC1,PC2,PC3,PC10,PC11,PC12-open drain*/
/*?*/ GPIOC-›CRL|= GPIO_CRL_CNF0_0|GPIO_CRL_CNF1_0|GPIO_CRL_CNF2_0|GP IO_CRL_CNF3_0;
/*?*/ GPIOC-›CRL&=~(GPIO_CRL_CNF0_1|GPIO_CRL_CNF1_1|GPIO_CRL_C NF2_1 |GPIO_CRL_CNF3_1);
/*?*/ GPIOC-›CRH|= GPIO_CRH_CNF10_0|GPIO_CRH_CNF11_0|GPIO_CRH_CNF12_0 ;
/*?*/ GPIOC-›CRH&=~(GPIO_CRH_CNF10_1|GPIO_CRH_CNF11_1|GPIO_CRH _CNF1 2_1);
/*Настраиваем РC4 на вход*/
GPIOC-›CRL&=~GPIO_CRL_MODE4;
GPIOC-›CRL&=~GPIO_CRL_CNF4;
/*Настраиваем РC5 на вход*/
GPIOC-›CRL&=~GPIO_CRL_MODE5;
GPIOC-›CRL&=~GPIO_CRL_CNF5;
/*Настраиваем PB5 на выход */
GPIOB-›CRL|= GPIO_CRL_MODE5;
/*PB5-open drain*/
GPIOB-›CRL|= GPIO_CRL_CNF5_0;
GPIOB-›CRL&=~GPIO_CRL_CNF5_1;
/*PD2 на выход*/
GPIOD-›CRL|= GPIO_CRL_MODE2|GPIO_CRL_MODE1;
/*PD2 -двухтактный выход общего назначения*/
GPIOD-›CRL&=~GPIO_CRL_CNF2;
GPIOD-›CRL&=~GPIO_CRL_CNF1;
/*PB14 на выход*/
GPIOB-›CRH|= GPIO_CRH_MODE14;
/*PB14 -двухтактный выход общего назначения*/
GPIOB-›CRH&=~GPIO_CRH_CNF14;
/*PA2 на выход*/
GPIOA-›CRL|= GPIO_CRL_MODE2;
/*PA2 -двухтактный выход c альтернативной функцией*/
GPIOA-›CRL&=~GPIO_CRL_CNF2;
GPIOA-›CRL|=GPIO_CRL_CNF2_1;
}
void TIM3_Init(void) // Инициализация 1-го таймера
{
RCC-›APB1ENR |= RCC_APB1ENR_TIM3EN;//Разрешить прохождение сигнала к таймеру Т17
TIM3-›PSC = 999; //Настроить предделитель
TIM3-›ARR =10000; //Максимальное значение до которого будет считать таймер
// TIM3-›DIER |= TIM_DIER_UIE; //Разрешить генерацию события по достижению макс. значения
TIM3-›CR1 = TIM_CR1_CEN | TIM_CR1_ARPE;//разрешить работу таймера и его сброс по достижению макс. значения
TIM3-›CR2 |= TIM_CR2_MMS_1;//Генереировать TRGO по обновлению
NVIC_SetPriority(TIM3_IRQn, 13);//установить приоритет и разрешить прерывания
}
void ADC_Init(void) // Инициализация ацп
{
RCC-›APB2ENR |= RCC_APB2ENR_ADC1EN; // подаем такты на АЦП
ADC1-›CR2 |= ADC_CR2_ADON; // подаем питание на АЦП
ADC1-›CR2 |= ADC_CR2_EXTTRIG; // включаем запуск от внешнего события
ADC1-›CR2 |= ADC_CR2_EXTSEL_2; // Запуск по TRGO Timer 3
ADC1-›CR2 |= ADC_CR2_DMA; // включаю DMA
ADC1-›SQR1&=~ ADC_SQR1_L;
//ADC1-›SQR1|= ADC_SQR1_L_0; // Выставили колличество преобразований равным 2
ADC1-›CR1 |= ADC_CR1_SCAN; // Режим сканирования
ADC1-›SQR3 |= ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_2|ADC_SQR3_SQ1_3;//На 14 канал 1-е преобр
//ADC1-›SQR3 |=ADC_SQR3_SQ2_0| ADC_SQR3_SQ2_1 | ADC_SQR3_SQ2_2|ADC_SQR3_SQ2_3; //На 15 канал 2-е преобр
for (i=0; i‹20; i++) __NOP(); //wait 1 us
ADC1-›CR2 |= ADC_CR2_CAL; //start calibration
while(ADC1-›CR2 & ADC_CR2_CAL); //wait
NVIC_SetPriority(ADC1_IRQn, 10);
}
void DMA_Init(void)
{
RCC-›AHBENR |= RCC_AHBENR_DMA1EN; // подаю такты на DMA1
DMA1_Channel1-›CPAR= (uint32_t) &ADC1-›DR; //адрес периферийного устройства
DMA1_Channel1-›CMAR = (unsigned int) adc_buf;//адрес памяти
DMA1_Channel1-›CNDTR |= DMA_BUF_LEN;; //колличество регистров 256
DMA1_Channel1-›CCR |= DMA_CCR1_MSIZE_1; //размер памяти 32 bit
DMA1_Channel1-›CCR |=DMA_CCR1_PSIZE_1 ; //размер периферии 32 bit
DMA1_Channel1-›CCR |=DMA_CCR1_MINC ; //memory increment mode ( не уверен что надо)
DMA1_Channel1-›CCR |= DMA_CCR1_TCIE ; // прерывание по окончанию передачи
DMA1_Channel1-›CCR |=DMA_CCR1_EN; // разрешаем работу
NVIC_SetPriority(DMA1_Channel1_IRQn, 10);
}
void InitAll(void)//Общая инициализация
{
RCC_Init();
Port_Init();
ADC_Init();
TIM3_Init();
DMA_Init();
}
/***********************Функции дополнительные********************/
char* itoa(int val, int base) // число в строку
{
static char buf[32] = {0};
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
/***********************Функция главная********************/
int main(void)
{
InitAll();
lcd_init();
lcd_clear();
lcd_print (" What's up? ");
set_cursor (0, 1);
lcd_print (" ????????");
ADC1-›DR=0;
while(statement‹3) // Мигание светодиодами .
{
tmp=500000; while (tmp) {tmp--;} // Задержка.
GPIOC-›BSRR=GPIO_BSRR_BS8|GPIO_BSRR_BR9; // Зажечь LED4, потушить LED3.
tmp=500000; while (tmp) {tmp--;} // Задержка.
GPIOC-›BSRR=GPIO_BSRR_BS9|GPIO_BSRR_BR8; // Зажечь LED3, потушить LED4.
statement++;
}
if (statement==3) // Отмигали- делаем что-нить
{ /*Разрешаем генерацию в NVIC*/
NVIC_EnableIRQ(EXTI0_IRQn);
NVIC_EnableIRQ(ADC1_IRQn);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
while(1)
{
/*ОСНОВНОЙ ЦИКЛ*/
__NOP();
}
} }
/***********************Прерывания***************** ***/
void DMAChannel1_IRQHandler(void)
{ lcd_clear();
set_cursor(0,0);
lcd_print ("ADC:");
set_cursor(0,1);
lcd_print(itoa(adc_buf[1],10));
ADC1-›CR2 &= (~ADC_CR2_ADON); //power-off ADC
DMA1-›IFCR = DMA_IFCR_CGIF1 | DMA_IFCR_CTCIF1;//clear DMA interrupt flags
}
|
В приложении полный проект.
ПОМОГИТЕ!
Последний раз редактировалось ^smbd^; 05.09.2011 в 11:52.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:40.
|
|