Загрузка данных


LAB 3 exp 2
main.c--------------------------------------------
#include "stm32f10x.h"
#include <stdint.h>

#define MAX 64

uint8_t lvl[MAX];
uint8_t dur[MAX];
uint8_t n = 0;

volatile uint8_t pos  = 0;
volatile uint8_t tick = 0;

#define LED_ON()   (GPIOC->BRR  = (1 << 13))
#define LED_OFF()  (GPIOC->BSRR = (1 << 13))

void add(uint8_t l, uint8_t d)
{
    lvl[n] = l;
    dur[n] = d;
    n++;
}

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);
}

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)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
    GPIOC->CRH &= ~(0xF << 20);
    GPIOC->CRH |=  (0x2 << 20);

    parse(".- -. - --- -./..---");

    pos  = 0;
    tick = dur[0];
		if (lvl[0]) LED_ON();
		else LED_OFF();

    SysTick_Config(4000000);
    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();
    }
}