/
mapb14ator
/
k1921
Обзор
Документация
Войти
/
mapb14ator
/
k1921
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
main.c
318 строк
8 KB
mapb14ator
feat(mcu): начальная прошивка для контроллера K1921VG015
07 июл 2026, 14:34
Верифицирован
07 июл 2026, 14:34
55053b2
Код
Авторство
О чём код?
#include <K1921VG015.h> #include <stdint.h> #include <stdio.h> #include <system_k1921vg015.h> #include "retarget.h" #define PORT_A 1 #define PORT_B 2 #define PORT_C 3 #define HIGH 1 #define LOW 0 #define TOGGLE 2 #define UART3_BAUD 115200 uint8_t rx_data; uint8_t tx_data; void UART3_IRQHandler() { //tx_data = UART3->DR; //Сбрасываем флаг прерывания таймера //UART3 -> DR = tx_data; UART3->ICR = 0xFFF; } void ADC_init(){ PMUSYS->ADCPWRCFG_bit.LDOEN = 1; PMUSYS->ADCPWRCFG_bit.LVLDIS = 0; RCU->ADCSARCLKCFG_bit.CLKSEL = 1; RCU->ADCSARCLKCFG_bit.DIVEN = 0; RCU->ADCSARCLKCFG_bit.DIVEN = 1; RCU-> ADCSARCLKCFG_bit.CLKEN = 1; RCU-> ADCSARCLKCFG_bit.RSTDIS = 1; RCU->CGCFGAPB_bit.ADCSAREN = 1; RCU->RSTDISAPB_bit.ADCSAREN = 1; ADCSAR->ACTL_bit.SELRES = 3; //ADCSAR->ACTL_bit.CALEN = 1; ADCSAR->ACTL_bit.ADCEN = 1; //Настройка секвенсора 0 ADCSAR->EMUX_bit.EM0 = 0; ADCSAR->SEQ[0].SRQCTL_bit.RQMAX = 0x0; ADCSAR->SEQ[0].SRQSEL_bit.RQ0 = 0x0; ADCSAR->SEQEN_bit.SEQEN0 = 1; // Запуск while(!ADCSAR->ACTL_bit.ADCRDY){} ADCSAR->SEQSYNC_bit.SYNC0 = 1; ADCSAR->SEQSYNC_bit.GSYNC = 1; } int analogRead() { ADCSAR->SEQSYNC_bit.GSYNC = 1; while ((ADCSAR->BSTAT)){} while (!(ADCSAR->RIS_bit.SEQRIS0)){} return ADCSAR->SEQ[0].SFIFO; } void UART3_init() { uint32_t baud_icoef = HSECLK_VAL / (16 * UART3_BAUD); uint32_t baud_fcoef = ((HSECLK_VAL / (16.0f * RETARGET_UART_BAUD) - baud_icoef) * 64 + 0.5f); // Настраиваем GPIO RCU->CGCFGAHB_bit.GPIOAEN = 1; RCU->RSTDISAHB_bit.GPIOAEN = 1; RCU->CGCFGAPB_bit.UART3EN = 1; RCU->RSTDISAPB_bit.UART3EN = 1; GPIOA->ALTFUNCNUM_bit.PIN14 = 3; GPIOA->ALTFUNCNUM_bit.PIN15 = 3; GPIOA->ALTFUNCSET = GPIO_ALTFUNCSET_PIN14_Msk | GPIO_ALTFUNCSET_PIN15_Msk; // Настраиваем UART3 RCU->UARTCLKCFG[3].UARTCLKCFG_bit.CLKSEL = RCU_UARTCLKCFG_CLKSEL_HSE; RCU->UARTCLKCFG[3].UARTCLKCFG_bit.DIVEN = 0; RCU->UARTCLKCFG[3].UARTCLKCFG_bit.RSTDIS = 1; RCU->UARTCLKCFG[3].UARTCLKCFG_bit.CLKEN = 1; UART3->IBRD = baud_icoef; UART3->FBRD = baud_fcoef; UART3->LCRH = (3 << UART_LCRH_WLEN_Pos); UART3->IFLS = 0; UART3->IMSC = UART_IMSC_RXIM_Msk; //Receive interrupt mask UART3->CR = UART_CR_TXE_Msk | UART_CR_RXE_Msk | UART_CR_UARTEN_Msk; // Настраиваем обработчик прерывания для UART3 //PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_UART3, UART3_IRQHandler); //PLIC_SetPriority (IsrVect_IRQ_UART3, 0x1); //PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_UART3); } //включение порта void port_enable(uint8_t port){ if (port == PORT_A) { RCU->CGCFGAHB_bit.GPIOAEN = 1; RCU->RSTDISAHB_bit.GPIOAEN = 1; } if (port == PORT_B) { RCU->CGCFGAHB_bit.GPIOBEN = 1; RCU->RSTDISAHB_bit.GPIOBEN = 1; } if (port == PORT_C) { RCU->CGCFGAHB_bit.GPIOCEN = 1; RCU->RSTDISAHB_bit.GPIOCEN = 1; } } //настройка пина на режим выхода void pin_output_mode(uint8_t port, uint8_t pin) { if (port == PORT_C) { GPIOC->OUTENSET |= (1<<pin); } if (port == PORT_B) { GPIOB->OUTENSET |= (1<<pin); } if (port == PORT_A) { GPIOA->OUTENSET |= (1<<pin); } } void digitalWrite(uint8_t port, uint8_t pin, uint8_t status) { if (port == PORT_C) { if (status == HIGH) { GPIOC->DATAOUTSET |= (1<<pin); } if (status == LOW) { GPIOC->DATAOUTCLR |= (1<<pin); } if (status == TOGGLE) { GPIOC->DATAOUTTGL |= (1<<pin); } } if (port == PORT_B) { if (status == HIGH) { GPIOB->DATAOUTSET |= (1<<pin); } if (status == LOW) { GPIOB->DATAOUTCLR |= (1<<pin); } if (status == TOGGLE) { GPIOB->DATAOUTTGL |= (1<<pin); } } if (port == PORT_A) { if (status == HIGH) { GPIOA->DATAOUTSET |= (1<<pin); } if (status == LOW) { GPIOA->DATAOUTCLR |= (1<<pin); } if (status == TOGGLE) { GPIOA->DATAOUTTGL |= (1<<pin); } } } void enable_pullup(uint8_t port,uint8_t pin) { if (port == PORT_C) { GPIOC->PULLMODE |= (1<<pin); } if (port == PORT_B) { GPIOB->PULLMODE |= (1<<pin); } if (port == PORT_A) { GPIOA->PULLMODE |= (1<<pin); } } uint8_t digitalRead(uint8_t port,uint8_t pin) { uint8_t out; if (port == PORT_C) { out = GPIOC->DATA; } if (port == PORT_B) { out = GPIOB->DATA; } if (port == PORT_A) { out = GPIOA->DATA; } out &= (1<<pin); if (out == 0) { out = LOW; } else { out = HIGH; } return out; } void delay_cycles(uint32_t tick) { for (int32_t i = 0; i < tick; i++) { } } void uart3_send(uint8_t data) { UART3 -> CR_bit.TXE = 1; while (UART3 -> FR_bit.TXFF == 1) {} UART3->DR = data; } void TMR32_IRQHandler() { TMR32->IC = 3; } void servo_init(uint16_t period){ RCU->CGCFGAPB_bit.TMR1EN = 1; RCU->RSTDISAPB_bit.TMR1EN = 1; port_enable(PORT_A); GPIOA->ALTFUNCNUM_bit.PIN8 = 2; GPIOA->ALTFUNCSET = (1 << 8); TMR1->CAPCOM[0].VAL = period-1; //Настраиваем режим сравнения для CAPCOM[2] - управление выводом GPIOA.8 TMR1->CAPCOM[2].CTRL_bit.CAP = 0; // Режим сравнения TMR1->CAPCOM[2].CTRL_bit.OUTMODE = 7; /* Выходной сигнал сбрасывается, когда таймер отсчитывает значение CAPCOM[n].VAL. Он устанавливается, когда таймер отсчитывает значение CAPCOM[0].VAL.*/ TMR1->CAPCOM[2].VAL = 4000; TMR1->CTRL_bit.DIV = 3; // Делитель частоты на 8 //Выбираем режим счета от 0 до значения CAPCOM[0] TMR1->CTRL_bit.MODE = TMR_CTRL_MODE_Up; //Разрешаем прерывание по совпадению значения счетчика и CAPCOM[0] TMR1->IM = 2; // Настраиваем обработчик прерывания для TMR1 PLIC_SetIrqHandler (Plic_Mach_Target, IsrVect_IRQ_TMR32, TMR32_IRQHandler); PLIC_SetPriority (IsrVect_IRQ_TMR32, 0x1); PLIC_IntEnable (Plic_Mach_Target, IsrVect_IRQ_TMR32); } void servo_write(uint8_t angle) { uint16_t period = 2900+(uint16_t)angle*50; TMR1->CAPCOM[2].VAL = period-1; } void setup() { SystemInit(); SystemCoreClockUpdate(); retarget_init(); //FLASH->CTRL_bit.LAT = 3; //FLASH->CTRL_bit.CEN = 1; port_enable(PORT_C); pin_output_mode(PORT_C,0); enable_pullup(PORT_C,1); digitalWrite(PORT_C,0,HIGH); UART3_init(); ADC_init(); servo_init(58000); //PLIC_SetThreshold (Plic_Mach_Target, 0); //allow all interrupts in machine mode InterruptEnable(); printf("K1921VG015 SYSCLK = %d MHz\n",(int)(SystemCoreClock / 1E6)); printf(" UID[0] = 0x%X UID[1] = 0x%X UID[2] = 0x%X UID[3] = 0x%X\n", (unsigned int)PMUSYS->UID[0],(unsigned int)PMUSYS->UID[1],(unsigned int)PMUSYS->UID[2],(unsigned int)PMUSYS->UID[3]); } int analog_result; void loop(){ if (digitalRead(PORT_C,1)==HIGH) { digitalWrite(PORT_C,0,HIGH); } else { analog_result = analogRead(); //uart3_send( (uint8_t)(analog_result&0x0000000f)); printf("CH0 - 0x%03x\n", TMR1->COUNT); digitalWrite(PORT_C,0,LOW); servo_write(180); } delay_cycles(10000); } //-- Main ---------------------------------------------------------------------- int main(void) { setup(); while(1) { loop(); } return 0; }