Загрузка данных
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();
}
}