Загрузка данных
LAB 3 exp 2
main.c--------------------------------------------
#include "stm32f10x.h"
#include <stdint.h>
#define MAX 64
static uint8_t lvl[MAX];
static uint8_t dur[MAX];
static uint8_t n = 0;
static volatile uint8_t pos = 0;
static volatile uint8_t tick = 0;
#define LED_ON() (GPIOC->BSRR = (1 << 13))
#define LED_OFF() (GPIOC->BSRR = (1 << 29))
static void add(uint8_t l, uint8_t d)
{
if (n < MAX) {
lvl[n] = l;
dur[n] = d;
n++;
}
}
static void parse(char* s)
{
n = 0;
for (uint8_t i = 0; s[i]; i++) {
if (s[i] == '.') { add(1, 1); add(0, 1); }
if (s[i] == '-') { add(1, 3); add(0, 1); }
if (s[i] == ' ') dur[n-1] += 2;
if (s[i] == '/') dur[n-1] += 6;
}
if (n > 0 && lvl[n-1] == 0) n--;
add(0, 7);
}
static void setup_clock(void)
{
RCC->CR |= RCC_CR_HSION;
while(!(RCC->CR & RCC_CR_HSIRDY));
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI;
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);
RCC->CFGR &= ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2);
RCC->CR &= ~RCC_CR_PLLON;
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2;
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL | RCC_CFGR_PLLXTPRE);
RCC->CFGR |= RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL7;
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_HPRE) | RCC_CFGR_HPRE_DIV4;
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}
static void setup_systick(void)
{
/* HCLK = 14 МГц, CLKSOURCE = 0 → 14/8 = 1.75 МГц
0.5 с → LOAD = 1 750 000 / 2 = 875 000 */
SysTick->LOAD = 875000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = 3;
}
void SysTick_Handler(void)
{
if (--tick) return;
pos++;
if (pos >= n) pos = 0;
tick = dur[pos];
if (lvl[pos]) LED_ON();
else LED_OFF();
}
int main(void)
{
setup_clock();
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
GPIOC->CRH |= GPIO_CRH_MODE13_1;
parse(".- -. - --- -./..---");
pos = 0;
tick = dur[0];
if (lvl[0]) LED_ON(); else LED_OFF();
setup_systick();
while (1) __WFI();
}
startup.s-----------------------------------------------------
PRESERVE8
THUMB
STACK_TOP EQU 0x20001000
IMPORT main
IMPORT SysTick_Handler
IMPORT |Load$$RW_IRAM1$$Base|
IMPORT |Image$$RW_IRAM1$$Base|
IMPORT |Image$$RW_IRAM1$$Length|
IMPORT |Image$$RW_IRAM1$$ZI$$Base|
IMPORT |Image$$RW_IRAM1$$ZI$$Length|
EXPORT Reset_Handler
EXPORT __main
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD STACK_TOP
DCD Reset_Handler
SPACE 13*4
DCD SysTick_Handler
AREA LAB3, CODE, READONLY
Reset_Handler PROC
B __main
ENDP
__main PROC
LDR R0, =|Load$$RW_IRAM1$$Base|
LDR R1, =|Image$$RW_IRAM1$$Base|
LDR R2, =|Image$$RW_IRAM1$$Length|
copy_data
CMP R2, #0
BEQ zero_bss
LDRB R3, [R0], #1
STRB R3, [R1], #1
SUBS R2, R2, #1
BNE copy_data
zero_bss
LDR R1, =|Image$$RW_IRAM1$$ZI$$Base|
LDR R2, =|Image$$RW_IRAM1$$ZI$$Length|
MOVS R3, #0
clear_bss
CMP R2, #0
BEQ go_to_main
STRB R3, [R1], #1
SUBS R2, R2, #1
BNE clear_bss
go_to_main
LDR R0, =main
BX R0
ENDP
END
-------------------------------------------
lab 3 exp 3
----------------------------
startup.s
PRESERVE8
THUMB
STACK_TOP EQU 0x20001000
IMPORT main
IMPORT SysTick_Handler
IMPORT TIM1_CC_IRQHandler
IMPORT |Load$$RW_IRAM1$$Base|
IMPORT |Image$$RW_IRAM1$$Base|
IMPORT |Image$$RW_IRAM1$$Length|
IMPORT |Image$$RW_IRAM1$$ZI$$Base|
IMPORT |Image$$RW_IRAM1$$ZI$$Length|
EXPORT Reset_Handler
EXPORT __main
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD STACK_TOP
DCD Reset_Handler
SPACE 13*4
DCD SysTick_Handler
SPACE 27*4
DCD TIM1_CC_IRQHandler
AREA LAB3, CODE, READONLY
Reset_Handler PROC
B __main
ENDP
__main PROC
LDR R0, =|Load$$RW_IRAM1$$Base|
LDR R1, =|Image$$RW_IRAM1$$Base|
LDR R2, =|Image$$RW_IRAM1$$Length|
copy_data
CMP R2, #0
BEQ zero_bss
LDRB R3, [R0], #1
STRB R3, [R1], #1
SUBS R2, R2, #1
BNE copy_data
zero_bss
LDR R1, =|Image$$RW_IRAM1$$ZI$$Base|
LDR R2, =|Image$$RW_IRAM1$$ZI$$Length|
MOVS R3, #0
clear_bss
CMP R2, #0
BEQ go_to_main
STRB R3, [R1], #1
SUBS R2, R2, #1
BNE clear_bss
go_to_main
LDR R0, =main
BX R0
ENDP
END
main.c---------------------------------------
#include "stm32f10x.h"
#include <stdint.h>
#define PSC_TIM1 3000
#define TIM_HZ (8000000 / (PSC_TIM1 + 1)) // ≈ 2665
#define THRESHOLD (TIM_HZ) // 1 s
#define MIN_PRESS (TIM_HZ / 10) // 100 ms
static volatile uint8_t led_countdown = 0;
static volatile uint8_t pattern = 0;
static volatile uint8_t press_count = 0;
static const uint8_t digits[10] = {
0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x10, 0x18, 0x1C, 0x1E
};
#define LED_ON() (GPIOC->BSRR = (1 << 13))
#define LED_OFF() (GPIOC->BRR = (1 << 13))
static uint8_t decode(uint8_t p)
{
for (uint8_t d = 0; d < 10; d++)
if (digits[d] == p) return d;
return 0xFF;
}
static void gpio_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
/* PA8: input with pull-down (CNF=10, MODE=00) */
GPIOA->CRH &= ~(0xF << 0);
GPIOA->CRH |= (0x8 << 0);
GPIOA->ODR &= ~(1 << 8);
/* PC13: output push-pull 2 MHz */
GPIOC->CRH &= ~(0xF << 20);
GPIOC->CRH |= (0x2 << 20);
LED_OFF();
}
static void tim1_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
TIM1->PSC = PSC_TIM1;
TIM1->ARR = 0xFFFF;
TIM1->EGR = TIM_EGR_UG;
TIM1->SR = 0;
/* CC1: input from TI1; CC2: input from TI1 (indirect) */
TIM1->CCMR1 = (2 << 8) | (1 << 0);
/* CC1 rising, CC2 falling, both enabled */
TIM1->CCER = (1 << 4) | (1 << 5) | (1 << 0);
/* TS = TI1FP1, SMS = Reset mode */
TIM1->SMCR = (5 << 4) | 4;
/* CC1IE + CC2IE */
TIM1->DIER = (1 << 1) | (1 << 2);
/* MOE (safety for advanced timer) */
TIM1->BDTR = TIM_BDTR_MOE;
NVIC_EnableIRQ(TIM1_CC_IRQn);
TIM1->CR1 = TIM_CR1_CEN;
}
void SysTick_Handler(void)
{
if (led_countdown > 0) {
led_countdown--;
if (led_countdown == 0) LED_OFF();
}
}
void TIM1_CC_IRQHandler(void)
{
if (TIM1->SR & TIM_SR_CC2IF) {
TIM1->SR = ~TIM_SR_CC2IF;
uint16_t t = TIM1->CCR2;
if (t > MIN_PRESS) {
uint8_t bit = (t > THRESHOLD) ? 1 : 0;
pattern = (pattern << 1) | bit;
press_count++;
if (press_count == 5) {
uint8_t digit = decode(pattern);
if (digit != 0xFF) {
led_countdown = digit * 10;
LED_OFF();
if (digit > 0) LED_ON();
}
pattern = 0;
press_count = 0;
}
}
}
if (TIM1->SR & TIM_SR_CC1IF) {
TIM1->SR = ~TIM_SR_CC1IF;
}
}
int main(void)
{
gpio_init();
tim1_init();
SysTick_Config(800000);
while (1) {
__WFI();
}
}