#include "xc6xxx.h" #include "xc_hal.h" #include "uart.h" uint8_t chipuid[12]; uint8_t deviceaddr[4]; volatile uint32_t tick_count = 0; extern void app_tick_handler(void); //系统时钟初始化 void hal_clock_init(void) { CLOCK_InitCfg_t clock_cfg; clock_cfg.hfclk_src = CLOCK_HFCLK_SRC_XTAL; clock_cfg.hfclk_in = CLOCK_HFCLK_IN_32M; clock_cfg.lfclk_src = CLOCK_LFCLK_SRC_RC; if (clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_XTAL) { clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32768; } else if (clock_cfg.lfclk_src == CLOCK_LFCLK_SRC_RC) { clock_cfg.lfclk_in = CLOCK_LFCLK_IN_32K; } xc_clock_init_cfg(&clock_cfg); } //看门狗初始化 static void hal_wdt_init(void) { #if defined(ENABLE_WDT) WDT_InitCfg_t wdt_cfg ; //wdt_cfg.WorkMode = WDT_WORK_MODE0; //模式0:超时复位 wdt_cfg.WorkMode = WDT_WORK_MODE1; //模式1:超时中断喂狗,两次未中断复位 wdt_cfg.ReloadValue = WDT_ReloadValue_0xFFFF; //约2秒 wdt_cfg.PclkSel = WDT_WORK_32K; xc_wdt_init(&wdt_cfg); xc_wdt_start(); //启动看门狗 NVIC_EnableIRQ(WDT_IRQn); //使能看门狗中断 #endif } //定时器初始化 static void hal_timer_init(void) { Timer_InitCfg_t timer_cfg; timer_cfg.timer_src_clk = TIMER_CLK_SRC_32M_DIV; //定时器时钟源 timer_cfg.timer_div_clk = TIMER_DIV_CLK_16MHzOr16K; //分频系数 timer_cfg.timer_mode = TIMER_MODE_CYCLE; //运行模式 xc_timer_init(TIMER0_IDX, &timer_cfg); xc_timer_set_value(TIMER0_IDX, 1000); //设置定时时间 xc_timer_start(TIMER0_IDX); //启动定时器 } //定时器中断 void timer0_callback(void *context) { tick_count++; uart_tick(); app_tick_handler(); } //串口初始化 static void hal_uart_init(void) { GPIO_InitCfg_t gpio_cfg = {0}; //UART0_TXD引脚 gpio_cfg.Pin = GPIO_18; gpio_cfg.Dir = GPIO_DIR_OUTPUT; gpio_cfg.Pull = GPIO_PULLUP; gpio_cfg.Mux = GPIO_Mux0; gpio_cfg.FunSel = UART0_TX; gpio_cfg.Int = NOT_INT; xc_gpio_init(&gpio_cfg); //UART0_RXD引脚 gpio_cfg.Pin = GPIO_19; gpio_cfg.Dir = GPIO_DIR_INPUT; gpio_cfg.FunSel = UART0_RX; xc_gpio_init(&gpio_cfg); UART_InitCfg_t uart_cfg = {0}; uart_cfg.BaudRate = UART_BAUDRATE_115200; uart_cfg.Parity = UART_PARITY_DISABLE; uart_cfg.StopBits = UART_STOP_1_BITS; uart_cfg.WordLength = UART_DATA_8_BITS; uart_cfg.HardwareFlowControl = UART_HWFC_DISABLE; xc_uart_init(UART0_IDX, &uart_cfg); xc_uart_enable_rx_it(UART0_IDX); NVIC_EnableIRQ(UART0_IRQn); } //串口接收中断 void uart_receive_cb(uint8_t reg_idx, uint8_t val) { if(reg_idx == UART0_IDX) { uart_rxbyte(val); } } //PWM初始化 static void hal_pwm_init(void) { PWM_InitCfg_t pwm_cfg; pwm_cfg.DutyCycleAcc = 8000; //调整占空比精度 pwm_cfg.DutyCycle = 4000; //调整占空比 pwm_cfg.Period = 0; //调整时钟周期参数:0-255 pwm_cfg.OutputPin = GPIO_2; //输出引脚 pwm_cfg.OutputInvertPin = GPIO_3; //互补输出引脚 pwm_cfg.InvertEnable = false; //互补输出使能 pwm_cfg.InvertDelay = 0x17; //互补死区时间 pwm_cfg.Mode = PWM_EN_MODE_EDGE_ALIGNED; pwm_cfg.SrcClk = PWM_CLK_SRC_32M_DIV; //时钟源 pwm_cfg.SrcEnable = PWM_EN_SEL_ALL; //使能源选择 xc_pwm_init(PWM0_IDX, &pwm_cfg); //xc_pwm_start(PWM0_IDX); //使能指定PWM xc_pwm_start_all(); //使能所有PWM } //ADC初始化 static void hal_adc_init(void) { GPIO_InitCfg_t GPIO_InitCfg; GPIO_InitCfg.Pin = GPIO_1; GPIO_InitCfg.Dir = GPIO_DIR_INPUT; GPIO_InitCfg.Pull = GPIO_NOPULL; GPIO_InitCfg.Mux = GPIO_Mux0; GPIO_InitCfg.FunSel = GPIO_Dx; GPIO_InitCfg.Int = NOT_INT; xc_gpio_init(&GPIO_InitCfg); ADC_InitCfg_t adc_cfg; adc_cfg.Freq = ADC_FREQ_500K; //采样频率,最高采样率1M adc_cfg.RefVol = ADC_REF_VOL_3_3V; //参考电压 adc_cfg.SampEdge = ADC_SAMPEDGE_RISE; //内部采样触发沿 adc_cfg.ExtDataMode = ADC_EXT_DATA_MODE_32BIT; //采集数据模式 adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER; //数据采样触发源:内部自动采样 adc_cfg.ExtSampleNum = ADC_EXT_SAMPLE_NUM_8; //外部触发采集数目 adc_cfg.ExtTriggerSel = ADC_EXT_TRIGGER_SEL_PWM0; //外部触发信号源 xc_adc_init(&adc_cfg); } uint8_t configdata[4096]; //获取设备地址 static void hal_addr_init(void) { uint8_t ruid[16]; xc_fmc_spi_init_oprt(); xc_fmc_spi_flash_wake_up(); xc_fmc_spi_flash_ruid(ruid); for(uint8_t i = 0; i < 12; i++) { chipuid[i] = ruid[0]; } xc_fmc_spi_flash_read(0x0001E000, deviceaddr, 4); //读取设备地址 if((deviceaddr[0]==0xFF && deviceaddr[1]==0xFF && deviceaddr[2]==0xFF && deviceaddr[3]==0xFF)) { //FLASH中没有写入设备地址时,使用chipuid前字节 for(uint8_t i = 0; i < 4; i++) { deviceaddr[i] = chipuid[i]; } } xc_fmc_spi_flash_read(0x00010000, configdata, 4096); //这里存储的是应用程序配置 } //GPIO初始化 static void hal_gpio_init(void) { GPIO_InitCfg_t GPIO_InitCfg = {0}; //LED->GPIO0 GPIO_InitCfg.Pin = GPIO_0; GPIO_InitCfg.Dir = GPIO_DIR_OUTPUT;//端口方向控制 GPIO_InitCfg.Pull = GPIO_PULLUP;//上下拉控制 GPIO_InitCfg.Mux = GPIO_Mux0; //一级复用 GPIO_InitCfg.FunSel = GPIO_Dx; //二级复用 GPIO_InitCfg.Int = NOT_INT; //中断控制 xc_gpio_init(&GPIO_InitCfg); xc_gpio_write_pin(GPIO_0, GPIO_PIN_SET); //RAD->GPIO5 GPIO_InitCfg.Pin = GPIO_5; GPIO_InitCfg.Dir = GPIO_DIR_INPUT;//端口方向控制 GPIO_InitCfg.Pull = GPIO_PULLDOWN;//上下拉控制 GPIO_InitCfg.Mux = GPIO_Mux0; //一级复用 GPIO_InitCfg.FunSel = GPIO_Dx; //二级复用 GPIO_InitCfg.Int = NOT_INT; //中断控制 xc_gpio_init(&GPIO_InitCfg); } //MCU初始化 void hal_mcu_init(void) { hal_clock_init(); hal_wdt_init(); hal_timer_init(); hal_uart_init(); hal_pwm_init(); hal_adc_init(); hal_addr_init(); hal_gpio_init(); } //喂狗 void hal_wdt_feed(void) { #if defined(ENABLE_WDT) //xc_wdt_reload(); #endif } //延时 void hal_delayms(uint32_t ms) { delay_ms(ms); } void hal_led_set(uint8_t val) { xc_gpio_write_pin(GPIO_0, val?GPIO_PIN_SET:GPIO_PIN_RESET); } uint8_t hal_rad_get(void) { return xc_gpio_read_pin(GPIO_5); } //设置PWM输出 void hal_pwm_set(uint8_t pwm_idx, uint16_t duty) { uint16_t freq = 2000; uint32_t acc = 16000000 / freq; xc_pwm_dutycycle_set(pwm_idx,acc, ((acc * duty) / 65535)); } //读取ADC值 uint16_t hal_adc_get(void) { uint16_t value = 0; xc_adc_start_get_value(ADC_CH5_PIN1, &value); //获取采样值 return value; } //串口发送 void hal_uart_send(uint8_t *data, uint16_t length) { xc_uart_send_data(UART0_IDX, data, length); } //串口发送 void hal_uart_sendbyte(uint8_t byte) { xc_uart_send_byte(UART0_IDX, byte); } uint32_t hal_tickcount(void) { return tick_count; } //获取8位随机数 uint32_t hal_random(void) { srand(tick_count); return rand(); }