286 lines
6.4 KiB
C
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();
|
|
}
|
|
|
|
|