Files
hpw421/project/example/2.4g/RF24_ADV/app/driver/xc_hal.c
T
2026-06-06 16:49:48 +08:00

286 lines
6.4 KiB
C

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