ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
17 июля
578581 Топик полностью
SciFi (08.02.2015 16:32, просмотров: 149) ответил Лагунов на вот так и пошел, сначала на SPI увидал свои 16 бит, теперь прицепился к SysTick и то же самое - с дискретностью 1 мсек. А потом надо самое неприятное - формировать цифры сотен, десятков, единиц, знакогенератор. Как-то на Си это? Вероятно
Ага, щас. Это на Си просто: #include "control.h" #include "timer.h" #include "irq.h" #include "stm32f1regs.h" #include "myassert.h" #include <stdbool.h> #define HOLD_TIMEOUT (3 * TIMER_TPS / 4) #define REPEAT_TIMEOUT (TIMER_TPS / 10) #define SEG2DISP(a,b,c,d,e,f,g,d1) ((a<<5)|(b<<7)|(c<<2)|(d<<0)|(e<<4)|(f<<6)|(g<<3)|(d1<<1)) static const uint8_t chartab[][2] = { { ' ', SEG2DISP(0,0,0,0,0,0,0,0) }, { '-', SEG2DISP(0,0,0,0,0,0,1,0) }, { '0', SEG2DISP(1,1,1,1,1,1,0,0) }, { '1', SEG2DISP(0,1,1,0,0,0,0,0) }, { '2', SEG2DISP(1,1,0,1,1,0,1,0) }, { '3', SEG2DISP(1,1,1,1,0,0,1,0) }, { '4', SEG2DISP(0,1,1,0,0,1,1,0) }, { '5', SEG2DISP(1,0,1,1,0,1,1,0) }, { '6', SEG2DISP(1,0,1,1,1,1,1,0) }, { '7', SEG2DISP(1,1,1,0,0,0,0,0) }, { '8', SEG2DISP(1,1,1,1,1,1,1,0) }, { '9', SEG2DISP(1,1,1,1,0,1,1,0) }, { 'A', SEG2DISP(1,1,1,0,1,1,1,0) }, { 'b', SEG2DISP(0,0,1,1,1,1,1,0) }, { 'C', SEG2DISP(1,0,0,1,1,1,0,0) }, { 'c', SEG2DISP(0,0,0,1,1,0,1,0) }, { 'd', SEG2DISP(0,1,1,1,1,0,1,0) }, { 'E', SEG2DISP(1,0,0,1,1,1,1,0) }, { 'F', SEG2DISP(1,0,0,0,1,1,1,0) }, { 'G', SEG2DISP(1,0,1,1,1,1,0,0) }, { 'H', SEG2DISP(0,1,1,0,1,1,1,0) }, { 'h', SEG2DISP(0,0,1,0,1,1,1,0) }, { 'I', SEG2DISP(0,1,1,0,0,0,0,0) }, { 'J', SEG2DISP(0,1,1,1,1,0,0,0) }, { 'L', SEG2DISP(0,0,0,1,1,1,0,0) }, { 'n', SEG2DISP(0,0,1,0,1,0,1,0) }, { 'O', SEG2DISP(1,1,1,1,1,1,0,0) }, { 'o', SEG2DISP(0,0,1,1,1,0,1,0) }, { 'P', SEG2DISP(1,1,0,0,1,1,1,0) }, { 'q', SEG2DISP(1,1,1,0,0,1,1,0) }, { 'r', SEG2DISP(0,0,0,0,1,0,1,0) }, { 'S', SEG2DISP(1,0,1,1,0,1,1,0) }, { 't', SEG2DISP(0,0,0,1,1,1,1,0) }, { 'U', SEG2DISP(0,1,1,1,1,1,0,0) }, { 'u', SEG2DISP(0,0,1,1,1,0,0,0) }, { 'Y', SEG2DISP(0,1,1,1,0,1,1,0) } }; static uint8_t disp[3]; static int leds = 7; static int volatile pressed; static struct control_combo latest; static bool new_event; static void systick_handler(void) { static int i, keymask; int j, dout = disp[i] | (1 << (9 + i)) | (leds << 12) | 0xFFFF0000; /* configure DATA as output */ GPIOC_CRH = (GPIOC_CRH & 0xFFF0FFFF) | 0x00020000; /* P10=GP P-P 1 MHz */ for (j = 0; j < 16; j++) { GPIOC_BSRR = (dout & 0x10001) << 12; GPIOA_BSRR = (1 << 15); GPIOA_BSRR = (1 << 31); dout >>= 1; } /* configure DATA as input with pull-up */ GPIOC_BSRR = (1 << 12); timer_delay(TIMER_TPS / 500000); GPIOC_CRH = (GPIOC_CRH & 0xFFF0FFFF) | 0x00080000; /* PC12=IN with PU */ timer_delay(TIMER_TPS / 500000); if (!(GPIOC_IDR & (1 << 12))) { keymask |= (1 << i); } if (++i == 3) { i = 0; switch (keymask) { case 1: pressed = 1; break; case 2: pressed = 2; break; case 4: pressed = 3; break; default: pressed = 0; break; } keymask = 0; } } void control_init(int prio) { RCC_APB2ENR |= (1 << 2) /* enable clocking of port A */ | (1 << 3) /* enable clocking of port B */ | (1 << 4);/* enable clocking of port C */ /* configure LEDY */ GPIOA_CRL = (GPIOA_CRL & 0xFFFFFFF0) | 0x00000002; /* PA0=GP P-P 2 MHz */ /* configure SHCLK */ GPIOA_CRH = (GPIOA_CRH & 0x0FFFFFFF) | 0x20000000; /* PA15=GP P-P 2 MHz */ /* configure DATA */ GPIOC_CRH = (GPIOC_CRH & 0xFFF0FFFF) | 0x00020000; /* PC12=GP P-P 2 MHz */ /* configure SHRST */ GPIOB_CRL = (GPIOB_CRL & 0xFFFFF0FF) | 0x00000200; /* PB2=GP P-P 2 MHz */ /* deassert SHRST */ GPIOB_BSRR = (1 << 2); irq_install(15, 32, systick_handler); /* reloads 200 times per second @ 72 MHz */ SYSTICK_RVR = 72000000 / 8 / 200 - 1; SYSTICK_CVR = 0; SYSTICK_CSR = (1 << 1) /* enable SysTick exception */ | (1 << 0);/* start counter */ } static void trigger_event(enum control_event event) { latest.event = event; new_event = true; } void control_poll(void) { static int prev_pressed; static unsigned int prev, prev_event, timeout; unsigned int now = timer_get(); if (now - prev > TIMER_TPS / 20) { int p = pressed; prev = now; if (p != prev_pressed) { if (prev_pressed == 0) { static const enum control_key keys[3] = { // KEY_LEFT, KEY_CENTER, KEY_RIGHT KEY_LEFT, KEY_RIGHT, KEY_CENTER }; trigger_event(CTRL_PRESS); latest.key = keys[p - 1]; prev_event = now; timeout = HOLD_TIMEOUT; } else if (latest.event != CTRL_RELEASE) { trigger_event(CTRL_RELEASE); } prev_pressed = p; } else if (p != 0 && now - prev_event > timeout) { switch (latest.event) { case CTRL_PRESS: trigger_event(CTRL_HOLD); timeout = REPEAT_TIMEOUT; break; case CTRL_HOLD: case CTRL_REPEAT: trigger_event(CTRL_REPEAT); break; default: myassert(0); break; } prev_event = now; } } } void control_leds(int offmask, int onmask) { leds = (leds | offmask) & ~onmask; } void control_show(const char* str) { int i = 0; do { if (*str == '.') { const uint8_t dot = SEG2DISP(0,0,0,0,0,0,0,1); if (i == 0) { disp[i++] = dot; } else { disp[i - 1] |= dot; } } else { int j; for (j = sizeof(chartab) / sizeof(chartab[0]) - 2; j >= 0; j--) { if (chartab[j][0] == *str) { disp[i++] = chartab[j][1]; break; } } myassert(j >= 0); } str++; } while (i < ((*str == '.') ? 4 : 3)); } struct control_combo control_getevent(void) { if (new_event) { new_event = false; return latest; } else { const struct control_combo empty_event = { CTRL_NONE, KEY_NONE }; return empty_event; } }
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้