Перейти к содержанию
    

UAKIVSO

Участник
  • Постов

    9
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Посетители профиля

Блок последних пользователей отключён и не показывается другим пользователям.

  1. идея понятна, я по такой сути делаю ЕМ, как в S77 стандарте типа этого void EM_LED (int i,int EM_ORIG) { int D; ///-----------------------------------LOAD DATA----------------------------------------------------------// internal_EM=(EM_ORIG + (EM[i]&0xFFFFC000)); Temp_EM=(internal_EM>>16)&0x3FFF;///read present step number ///-----------------------------------UPDATE COMPLETE/STATUS----------------------------------------------// if (!((internal_EM&0x3FFF) == Temp_EM)) {internal_EM=(internal_EM&0x7FFFBFFF);/*NO BIR 14&31*/;} ///-----------------------------------SELECT JUMP CONDITION - STEP OR TRANSITION--------------------------// if (internal_EM&0x4000){goto TRANSITION;}goto STEP; ///-----------------------------------STEP SELECTOR------------------------------------------------------// STEP:Temp_EM=internal_EM&0x3FFF;///read requested step number if (Temp_EM==0){goto STEP_0;} if (Temp_EM==100){goto STEP_100;} if (Temp_EM==200){goto STEP_200;} if (Temp_EM==300){goto STEP_300;} if (Temp_EM==400){goto STEP_400;} goto STEP_0;/// IF WRONG STEP ORDERED ///-----------------------------------TRANSITION SELECTOR-------------------------------------------------// TRANSITION:Temp_EM=internal_EM&0x3FFF;///read requested step number if (Temp_EM==0){goto TRANS_0;} if (Temp_EM==100){goto TRANS_100;} if (Temp_EM==200){goto TRANS_200;} if (Temp_EM==300){goto TRANS_300;} if (Temp_EM==400){goto TRANS_400;} goto TRANS_0;/// IF WRONG STEP ORDERED ///-----------------------------------STEP 0-------------------------------------------------------------// STEP_0:GPIOD->ODR =0xF000; GPIOD->BSRRL =0xF000;internal_EM|=0x4000;goto STEP_UPDATE; ///-----------------------------------TRANSITION 0--------------------------------------------------------// TRANS_0: internal_EM|=0x80000000; internal_EM= internal_EM+100;goto END; ///-----------------------------------STEP 100-------------------------------------------------------------// STEP_100:GPIOD->BSRRH =0x1000; GPIOD->BSRRL =0x8000; T[0]|=0x40000000;///SWITCH ON TIMER T[0]=T[0]&0xFFFFC000;///SET TIMER TO "0" SETPOINT T[0]|=10;///SET TIMER TO "10" SECONDS SETPOINT internal_EM|=0x4000; ///jump to transition set lcd_clear(); lcd_put_cur(0,0); lcd_send_string("I2C1->CR1"); D=I2C1->CR1 |=0x00; lcd_put_cur(1,0); lcdSendHEX(D,15); goto STEP_UPDATE; ///-----------------------------------TRANSITION 100--------------------------------------------------------// TRANS_100: if (T[0]&0x80000000) {internal_EM|=0x80000000;internal_EM= internal_EM+100;} goto END; ///-----------------------------------STEP 200-------------------------------------------------------------// STEP_200:GPIOD->BSRRH =0x2000; GPIOD->BSRRL =0x1000; T[1]|=0x40000000;///SWITCH ON TIMER T[1]=T[1]&0xFFFFC000;///SET TIMER TO "0" SETPOINT T[1]|=10;///SET TIMER TO "10" SECONDS SETPOINT internal_EM|=0x4000; ///jump to transition set lcd_put_cur(0,0); lcd_send_string("What? "); D=RCC->CR |=0x00; lcd_put_cur(1,0); lcdSendHEX(D,15); goto STEP_UPDATE; ///-----------------------------------TRANSITION 200--------------------------------------------------------// TRANS_200:if (T[1]&0x80000000) {internal_EM|=0x80000000;internal_EM= internal_EM+100;} goto END; ///-----------------------------------STEP 300-------------------------------------------------------------// STEP_300:GPIOD->BSRRH =0x4000; GPIOD->BSRRL =0x2000; T[2]|=0x40000000;///SWITCH ON TIMER T[2]=T[2]&0xFFFFC000;///SET TIMER TO "0" SETPOINT T[2]|=10;///SET TIMER TO "10" SECONDS SETPOINT internal_EM|=0x4000; ///jump to transition set goto STEP_UPDATE; ///-----------------------------------TRANSITION 300--------------------------------------------------------// TRANS_300:if (T[2]&0x80000000) {internal_EM|=0x80000000;internal_EM= internal_EM+100;} goto END; ///-----------------------------------STEP 400-------------------------------------------------------------// STEP_400:GPIOD->BSRRH =0x8000; GPIOD->BSRRL =0x4000; T[3]|=0x40000000;///SWITCH ON TIMER T[3]=T[3]&0xFFFFC000;///SET TIMER TO "0" SETPOINT T[3]|=10;///SET TIMER TO "10" SECONDS SETPOINT internal_EM|=0x4000; ///jump to transition set goto STEP_UPDATE; ///-----------------------------------TRANSITION 400--------------------------------------------------------// TRANS_400:if (T[3]&0x80000000) {internal_EM|=0x80000000;internal_EM= internal_EM-300 ;} goto END; ///-----------------------------------STEP UPDATE-------------------------------------------------------// STEP_UPDATE:Temp_EM=internal_EM&0x3FFF;///read requested step number internal_EM=((internal_EM&0xC000FFFF)+ (Temp_EM<<16));///update step number ///-----------------------------------RETURN DATA-------------------------------------------------------// END:EM[i]=internal_EM; } где int T[10];///where [XX] (XX-1)=number of used timers in code /// bits[13-0] - set time (max 16383),bit [14] -spare ,bit [15] - pause if set /// bits[29-16] - actual time (max 16383),bit [30] -enable if set,bit [31] -complete if set ///-----------------------------------EM`s VARIABLES----------------------------------------------------// int internal_EM;/// bits[13-0] - requested step (max 16383),bit [14] - jump to transition if set/else to step,bit [15] -Auto mode if set/else Manual ///bits[29-16] - present step (max 16383),bit [30] -Forse to complete if set/else normal,bit [31] -status complete if set; И проход через ШАГ идет один раз, а через транзишн, может идти многократно.. Спасибо - буду "курить тему"..
  2. Использую EmBitz 1.11, так как халявный... возможно Вы правы, буду улыбаться со своих постов. Про магические числа понял, учту... Ну а если прерывания, то как с ними быть? К примеру делаю старт - пишу на дисплей что-то, отправляю в регистр адрес, далее на свой код перехожу... появляется прерывание по получению адреса.. в разных обработчиках разные куски тулить? туплю я чего-то, не складывается картинка.. :( Сори, что значит конечный автомат? Не совсем понимаю что это?
  3. Итак, благодаря "волшебным пендалям" в заданном направлении получил аппаратный I2C без прерываний, но по флагам... Инициализация тут RCC->AHB1ENR|=0x02; ///AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE) GPIOB->MODER |= (2<<12) | (2<<14); /// Alternate function mode for PB6/PB7 GPIOB->AFR[0] |= (4<<24) |(4<<28); ///I2C -AF4 RCC->APB1ENR = (RCC->APB1ENR)&0xFFDFFFFF; I2C1->CR1 = 0x00; I2C1->CR2 = 0x00; RCC->APB1ENR |=(1<<21); I2C1->CR2 |= 42; ///APB1 speed in Mhz I2C1->CCR = 50; ///42Mhz/(2*100 kHz) for normal mode, for fast mode need to activate I2C master mode selection I2C1->TRISE = 43;/// 1ms/(1/42MHz) + 1 I2C1->CR1 |= (1<<10); ///ACK I2C1->CR1 |= 0x01; ///PE: Peripheral enable Собственно функция передача данных тут.. void Write_I2C_cmd(uint8_t device_address, uint8_t data) { uint32_t temp; char data_u, data_l; uint8_t data_t[4]; data_u =(data&0xf0); data_l =((data<<4)&0xf0); data_t[0] = data_u|0x0c; //en=1, rs=0 data_t[1] = data_u|0x08; //en=0, rs=0 data_t[2] = data_l|0x0c; //en=1, rs=0 data_t[3] = data_l|0x08; //en=0, rs=0 I2C1->CR1 |= I2C_CR1_START; ///START I2C I2C_CR1_START while (!(I2C1->SR1 & I2C_SR1_SB)) ///start condition was send { temp++; } I2C1->DR = (device_address<<1); ///SEND ADDRESS to DATA register while (!(I2C1->SR1 & I2C_SR1_ADDR)) ///address in DATA { temp++; } temp=I2C1->SR2; /// clear flags I2C_SR1_ADDR by read SR1 and then SR2 - SR1 was read in While loop I2C1->DR = data_t[0]; ///SEND data to DATA register while (!(I2C1->SR1 & I2C_SR1_TXE)) ///transfer complete { temp++; } I2C1->DR = data_t[1]; ///SEND data to DATA register while (!(I2C1->SR1 & I2C_SR1_TXE)) ///transfer complete { temp++; } I2C1->DR = data_t[2]; ///SEND data to DATA register while (!(I2C1->SR1 & I2C_SR1_TXE)) ///transfer complete { temp++; } I2C1->DR = data_t[3]; ///SEND data to DATA register while (!(I2C1->SR1 & I2C_SR1_TXE)) ///transfer complete { temp++; } I2C1->CR1 |= I2C_CR1_STOP; ///START I2C I2C_CR1_STOP } И все бы хорошо, да только вот банальное затирание 16 на 02 дисплея + две надписи тянут времени уж ОЧЕНЬ много.. Собственно команда lcd_clear(); lcd_put_cur(0,0); lcd_send_string("I2C1->CR1"); D=I2C1->CR1 |=0x00; lcd_put_cur(1,0); lcdSendHEX(D,15); И ее время выполнения в режиме 400 кГц берется более 10 милисекунд Понимаю, что можно оптимизировать возможно в 2-4 раза код=меньше кратно будут отсылаться данные, но вот все одно это будут 2-3 милисекунды... А жто много. для контоллера, который ничего не делает и столько времени тратит на пересылку ТОЛЬКО.. Вот поэтому и хотелось ручной ногодрыг или что-то такое, когда время, между позитивными флагами SCL будет использоваться для проходов программы. Прерывания не сильно хотелось бы внедрять = нет веры в си компилятор, не понятно, все ли гладко в итоге будет.. Собственно требуется от ГУРУ еще какой нить пинок в нужном направлении.. Может дадите толчок !?
  4. Спасибо за комменты, буду "курить" указанное выше
  5. I2C лишь шаг к пониманию как дергать ножками - цель профинет касаемо ожидания - оптимизация будет позже, сначала нужно, дабы заработало Возможно весь код поможет (выложить?), но хотелось бы пинок в правильном направлении ;) где я не так что-то накрутил И да, программировать на стл в сименсе могу, но си как то тяжко заходит - многого не знаю. Стилистика написания конечно корявая и не оптимизированная, но как только начнёт фурычить, то потрачу пару неделек на «причесывание и оптимизацию» «школьного кода»
  6. Итак, причина, по которой я пытаюсь наваять что нить по I2C и не использовать библиотеки/встроенные регисты в том, что уж очень хочется понять как оно работает и научиться управлять на уровне "дергания ножек" + прога в которой я ковыряюсь - EmBitz 1.11 Есть дисплей 1602 на I2C доп плате и собственно стм32Ф407 платка дискавери. Просьба сильно не пинать, а возможно указать тупиковость моих мыслей или движений. На сейчас объявляю инициализациб порта В ножек 7и8 таким образом void SET_I2C(void) { ///-----------------------------------SETUP PORTB6/7-----------------------------------------------------// RCC->APB1ENR|=0x200000; ///APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE) RCC->AHB1ENR|=0x02; ///AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE) GPIOB->MODER =0x5000; //32 bit for 16 inputs for 16 input 0x40000000, for 15 input 0x10000000...for 1 input 0x01. Means 01 for ech two bits if input GPIOB->OTYPER |=0xC0; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use internal resistor GPIOB->OSPEEDR |=0xF000; //32 bit for 16 inputs. Means 00 for LOW speed or 01 for MEDIUM or 10 for HIGH or 11 for VERY HIGH speed GPIOB->PUPDR |=0x5000; //32 bit for 16 inputs. Means 00 for no pulup/puldown resistor or 01 for pulup or 10 for puldown or 11 RESERVED GPIOB->BSRRL |=0xC0; } Потом собственно бит старт и пресылка адреса (0х27) с частотой 400 Кгерц при частоте камня 168Мгерц void lcd_adr (uint8_t LCD_ADR) { ///-----------------------------------SEND ADDRESS--------------------------------------------------------// int n; n=0; ADDR_OK=0; while(!(GPIOB->IDR&0x40)){n++;if(n>500){break;}} GPIOB->BSRRH|=0x80;/// 0V onto PB7 while(GPIOB->IDR&0x80){n++;} n=0; GPIOB->BSRRH|=0x40;/// 0V onto PB6 while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x40){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x20){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x10){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x08){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x04){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x02){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (LCD_ADR&0x1){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(n<((168000000/4000000)*7)){n++;} GPIOB->MODER=(GPIOB->MODER)&0xFFFF3FFF; GPIOB->PUPDR=(GPIOB->PUPDR)&0xFFFF3FFF; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++;} if (!(GPIOB->IDR&0x80)) { ADDR_OK=1; } n=0; while(!(GPIOB->IDR&0x80)){n++; if(n>500){break;}} GPIOB->MODER |=0x5000; GPIOB->PUPDR |=0x5000; } Далее использую команду указатель на инструкцию (0х78)+(0х00), где последня 1я строка void lcd_cmd (uint8_t cmd) { ///-----------------------------------SEND COMMAND--------------------------------------------------------// int n; n=0; DATA_OK=0; while(!(GPIOB->IDR&0x40)){n++;if(n>500){break;}} n=0; GPIOB->BSRRH|=0x40;/// 0V onto PB6 while(n<((168000000/4000000)*7)){n++;} if (cmd&0x80){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x40){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x20){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x10){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x08){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x04){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x02){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(!(GPIOB->IDR&0xFF3F)){n++;} while(n<((168000000/4000000)*7)){n++;} if (cmd&0x01){GPIOB->BSRRL|=0x80;}/// 3V onto PB7; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++; } GPIOB->BSRRH|=0xC0;/// 0V onto PB6/PB7 n=0; while(n<((168000000/4000000)*7)){n++;} GPIOB->MODER=(GPIOB->MODER)&0xFFFF3FFF; GPIOB->PUPDR=(GPIOB->PUPDR)&0xFFFF3FFF; GPIOB->BSRRL|=0x40;/// 3V onto PB6; while(n<(168000000/400000)){n++;} if (!(GPIOB->IDR&0x80)) { DATA_OK=1; } n=0; while(!(GPIOB->IDR&0x80)){n++; if(n>500){break;}} GPIOB->MODER |=0x5000; GPIOB->PUPDR |=0x5000; } И вроде акнолоджмент приходит, но засветить ченить на дисплее не выходит.. в Маине такой алгоритм lcd_adr (0x27); if (ADDR_OK==1){ lcd_cmd (0x78); } if (DATA_OK==1){ lcd_cmd (0x00); } if (DATA_OK==1){ lcd_data (0x01); } Понимаю, что многие скажут, что бред, но может это возможно заставить работать?
  7. Правильно Вы пишите, только вот проблема изначально была в проверке на изменение этого бита - прерывание срабатывало даже при "SYSCFG->EXTICR[0] |= 0x01;" Спасибо за помощь
  8. Это "SYSCFG->EXTICR[0] |= 0x00;" подключает PA0 к EXTI0 С "Она разрешает прерывания RTC, FLASH и EXTI0 (по случайному совпадению). 0x58" согласен на 100%! Должно быть 0х40 или //__IO uint32_t * register_address = (uint32_t *) 0xE000E100U; // Address of SYSCFG into microchip //*(__IO uint32_t *)register_address |= 0x40; // шестой бит в "1" для EXTI0 Ответ найден... не было включено тактирования конфигсис RCC->APB2ENR |= 0x4000; Как только подтянул тактирование к конфигу , то "SYSCFG->EXTICR[0] |= 0x00;" начала работать
  9. Доброго времени суток. Есть отладочная плата stm32 fiscovery kit с процом f407vg Проблема в понимании причины срабатывания прерывания по нажатию кнопки PA0, даже если на нее не указываю или указываю другое для прерывания EXTI0 (SYSCFG->EXTICR[0] |= 0x00; изменить, скажем, на SYSCFG->EXTICR[0] |= 0x01)!? Может єто как-то связано с NVIC->ISER[0] |= 0x58;// EXTI0-> EXTI Line0 interrupt-> 0x0000 0058 (from datasheet), так как по логике там должен быть 0x01, но тогда вообще ничего не работает... #include "stm32f4xx.h" // Device header //#include "Main.h" // Device header int n; static unsigned D; // TEMP for read value //********************************************************************************************// //-----------------------------------CUSTOMER FUNCTIONS---------------------------------------// void delay(int n) { while(n>0) n--; } //-----------------------------------ACTIVATE PORTS AS INPUT/OUTPUT--------------------------// void PORTA (void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;// switch on tackting PORTA GPIOA->MODER |=0x00; GPIOA->OTYPER |=0x00; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use internal resistor GPIOA->OSPEEDR |=0x00; //32 bit for 16 inputs. Means 00 for LOW speed or 01 for MEDIUM or 10 for HIGH or 11 for VERY HIGH speed GPIOA->PUPDR |=0x00; //32 bit for 16 inputs. Means 00 for no pulup/puldown resistor or 01 for pulup or 10 for puldown or 11 RESERVED } void PORTC (void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;// switch on tackting PORTC } void PORTD (void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;// switch on tackting PORTA GPIOD->MODER |=0x55000000; //32 bit for 16 inputs for 16 input 0x40000000, for 15 input 0x10000000...for 1 input 0x01. Means 01 for ech two bits if input GPIOD->OTYPER |=0x00; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use internal resistor GPIOD->OSPEEDR |=0x00; //32 bit for 16 inputs. Means 00 for LOW speed or 01 for MEDIUM or 10 for HIGH or 11 for VERY HIGH speed GPIOD->PUPDR |=0x00000000; //32 bit for 16 inputs. Means 00 for no pulup/puldown resistor or 01 for pulup or 10 for puldown or 11 RESERVED D=GPIOD->IDR; //16 bit for 16 inputs. USED ONLY for READ STATUS, which is set as INPUT GPIOD->ODR |=0x8000; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use as output GPIOD->BSRRL |=0x00; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use SET as OUTPUT GPIOD->BSRRH |=0x8000; //16 bit for 16 inputs for 16 input. Means 0 OR 1 for ech bits if use OR not use RESET as OUTPUT GPIOD->LCKR |=0x00; //Lock or NOT lock configuration of the port bits. IMPORTANTE: Access: 32-bit word only, read/write register //LOCK key write sequence: // WR LCKR[16] = ‘1’ + LCKR[15:0] // WR LCKR[16] = ‘0’ + LCKR[15:0] // WR LCKR[16] = ‘1’ + LCKR[15:0] // RD LCKR // RD LCKR[16] = ‘1’ (this read operation is optional but it confirms that the lock is active) // Note: During the LOCK key write sequence, the value of LCK[15:0] must not change. // Any error in the lock sequence aborts the lock. // After the first lock sequence on any bit of the port, any read access on the LCKK bit // returns ‘1’ until the next CPU reset. GPIOD->AFR[0] |=0x00;// AFRL GPIOD->AFR[1] |=0x00;// AFRH } //********************************************************************************************// //-----------------------------------System configuration controller--------------------------// void SYSCFG_INITIAL (void) { SYSCFG->MEMRMP |= 0x00;// Main Flash memory mapped at 0x0000 0000 SYSCFG->PMC |= 0x00; //For 0x00 - MII interface is selected. Foir 0x01 - RMII PHY interface is selected. } //-----------------------------------ACTIVATE EXTERNAL INTERRUPT BELONG TO ACTION-------------// void SYSCFG_INTERRUPT (void) { SYSCFG->EXTICR[0] |= 0x00;//These bits are written by software to select the source input for the EXTIx (from EXTI0-EXTI3) EXAMPLE 0000: PA[x] pin or 0001: PB[x] pin } //-----------------------------------LOGIC FOR INTERRUPT ------------------------------------// void EXTI0_IRQHandler (void) { /*----------------------------------------------*/ GPIOD->BSRRH =0xF000; EXTI->PR |= 0x01; //Reset (for Event and Interrupt) for input line } //-----------------------------------SIGN UP EXTERNAL INTERRUPT TO BITS----------------------// void SET_INTERRUPT (void) { EXTI->IMR |= 0x01; // Interrupt request from line EXTI_IMR0 is not masked EXTI->EMR |= 0x01; // Event request from line EXTI_EMR0 is not masked EXTI->RTSR |= 0x01; //Rising trigger enabled (for Event and Interrupt) for input line EXTI->FTSR |= 0x01; //Falling trigger enabled (for Event and Interrupt) for input line NVIC->ISER[0] |= 0x58;// EXTI0-> EXTI Line0 interrupt-> 0x0000 0058 (from datasheet) } //-----------------------------------MAIN PROGRAMM--------------------------// int main (void) { n=4500000; PORTA(); PORTC(); PORTD(); SYSCFG_INITIAL(); SYSCFG_INTERRUPT(); SET_INTERRUPT (); while(1) { GPIOD->ODR =0xF000; GPIOD->BSRRL =0xF000; LOOP: GPIOD->BSRRH =0x1000; GPIOD->BSRRL =0x8000; delay(n); GPIOD->BSRRH =0x2000; GPIOD->BSRRL =0x1000; delay(n); GPIOD->BSRRH =0x4000; GPIOD->BSRRL =0x2000; delay(n); GPIOD->BSRRH =0x8000; GPIOD->BSRRL =0x4000; delay(n); goto LOOP; } }
×
×
  • Создать...