ST17H36 蓝牙Soc开发(4)—— 外设应用1
一、PWM
1、说明
H36没有PWM外设,需要使用高级定时器配置输出PWM
2、PWM输出通道
芯片引脚与定时器输出通道对应
引脚 | 定时器通道 | 引脚 | 定时器通道 |
P0 | CH1 | P10 | CH1N |
P1 | CH2 | P11 | CH2N |
P2 | CH3 | P12 | CH1 |
P3 | CH4 | P13 | CH2 |
P4 | CH1N | P14 | CH3 |
P5 | CH2N | P15 | CH4 |
P6 | CH1 | P16 | CH1N |
P7 | CH2 | P17 | CH2N |
P8 | CH3 | P18 | CH1 |
P9 | CH4 | P19 | CH2 |
P20 | CH3 |
3、 SDK中PWM的使用
- 定时器时钟初始化
main.c中 添加__enable_irq();
int main(void)
{g_system_clk = SYS_CLK_XTAL_16M;//SYS_CLK_XTAL_16M;//SYS_CLK_DLL_48M;board_init();__enable_irq();#ifdef SBP_NRFJUMP_FUNCTION_SET(LL_HW_GO, (uint32_t)&ll_hw_go2);#endifpGlobal_config[LL_SLAVE_MAX_RXTO] = 10000;//usLOG_DEBUG("rfClk %d sysClk %d tpCap[%02x %02x] rcCal[%02x]\n",g_rfPhyClkSel,g_system_clk,g_rfPhyTpCal0,g_rfPhyTpCal1,aon_pm_pm_reg14_rc32k_c_trim_getf());LOG_DEBUG("[REST CAUSE] %d\n ",g_system_reset_cause);app_main(); }
- PWM初始化
void __ATTR_FUNC_RAM__(timx_irp_handler)(void){timx1_timx_sr_set(0);}void timx_pwm_sys_init(void){hal_timx_clock_init(TIM_CLK_XTAL_16M);JUMP_FUNCTION_SET(V24_IRQ_HANDLER, (uint32_t)timx_irp_handler);NVIC_EnableIRQ(timerx_IRQn);timx_pwm_init();}void timx_pwm_init(void){timx_init_t tim_initstruct;timx_oc_init_t tim_oc_initstruct;NVIC_EnableIRQ(timerx_IRQn);// 引脚初始化gpio_fmux_set(GPIO_MOTOR_A, FMUX_TIMX_TX);gpio_fmux_set(GPIO_MOTOR_B, FMUX_TIMX_TX);// 定时器时钟使能pcr_sw_clk1_clkg_timx1_setf(1);pcr_sw_clk1_clkg_timerx1_setf(1);// 定时器参数初始化(预分频数、计数方向、对齐模式、自动重装、时钟分频)tim_initstruct.prescaler = (320 - 1);tim_initstruct.dir = TIM_CAP_POLARITY_RISING; // upcounting modetim_initstruct.cms = 0; // edge-aligned modetim_initstruct.autoreload = (1000 - 1);tim_initstruct.clock_div = TIM_CLOCK_1CKINT;tim_initstruct.repetition_cnt = 0;timx_init(&tim_initstruct);// 使能自动重装timx1_timx_cr1_arpe_setf(1);// 定时器通道参数初始化(输出模式、空闲状态、比较值、极性)tim_oc_initstruct.mode = TIM_OCMODE_PWM1; // PWM1 Modetim_oc_initstruct.state = 0;tim_oc_initstruct.n_state = 0;tim_oc_initstruct.cmp_val = 0;tim_oc_initstruct.polarity = 0;tim_oc_initstruct.n_polarity = 0;tim_oc_initstruct.idle_state = 0;tim_oc_initstruct.n_idle_state = 0;timx_oc_init(BIT(2), &tim_oc_initstruct); // CH3 inittim_oc_initstruct.cmp_val = 0;timx_oc_init(BIT(3), &tim_oc_initstruct); // CH4 init// 使能通道预装载(通道1、2、3、4)// timx1_timx_ccmr1_oc1pe_setf(1); // enable preload register// timx1_timx_ccmr1_oc2pe_setf(1);timx1_timx_ccmr2_oc3pe_setf(1);timx1_timx_ccmr2_oc4pe_setf(1);// timx1_timx_dier_cc1ie_setf(1);// 选择开启通道输出// timx1_timx_ccer_cc1e_setf(1); // OC1 output// timx1_timx_ccer_cc2e_setf(1); // OC2 outputtimx1_timx_ccer_cc3e_setf(1); // OC3 outputtimx1_timx_ccer_cc4e_setf(1); // OC4 outputtimx1_timx_cr1_cen_setf(1); // enable CNTtimx1_timx_egr_ug_setf(1); // init countertimx1_timx_bdtr_moe_setf(1); // output enable}
- 修改通道占空比
timx1_timx_ccr3_set(500);timx1_timx_ccr4_set(500);
二、ADC
1、参考电压
参考电压软件可配置,在adc.c文件int hal_adc_config_channel(adc_cfg_t cfg)接口进行修改
pcrm_adc_ctrl_sar12b_ref_sel_setf(配置值1);
pcrm_adc_ctrl_sar12b_ref_res_tune_setf(配置值2);//0:120K:1:100K
计算公式:参考电压=(10 + 配置值1 * 1.25)* 配置值2
例如:配置值1=0x08,配置值2=1
参考电压 = (10 + 8 * 1.25)*100K = 2V
2、采样通道
引脚 | ADC通道 |
P4 | ADC_CH_1 |
P6 | ADC_CH_2 |
P10 | ADC_CH_3 |
P12 | ADC_CH_4 |
P14 | ADC_CH_5 |
P5 | ADC_CH_7 |
P9 | ADC_CH_8 |
P11 | ADC_CH_9 |
P13 | ADC_CH_10 |
P15 | ADC_CH_11 |
NONE | ADC_CH_VDD |
NONE | ADC_CH_VBAT |
除支持普通引脚通道外,支持VBAT和VCC采样。
需要注意的是,VBAT的采样进行了1/3分压,VCC采样进行了1/2分压。计算电压时需要分别乘以3和2倍。
以example/peripheral/adc工程,采样VCC电压为例,
static adc_cfg_t adc_cfg = {.channel = ADC_CH_VDD,.is_differential_mode = FALSE,.channel_negetive = 0x0,//only support CH1-5 in diff mode.irq_enable = FALSE,
};static void adcPoilling_MeasureTask( void )
{uint32_t adc_samp=0;/* test1: single sample */adc_samp = adc_sample(adc_cfg);adc_samp = adc_samp&0xfff;LOG("ADC1=%d \n",adc_samp);adc_samp = 2*3000*adc_samp/4096;LOG("ADC2=%d \n",adc_samp);}
三、VBAT供电
1、使能VBAT
在工程makefile中需要设置-DPMU_HIGH_LDO_DISABLE宏
1 | VBAT供电关闭,芯片从VDD引脚供电 |
0 | VBAT供电使能,内部LDO使能 |
四、GPIO
1、上下拉
强上拉 | 1.5K |
弱上拉 | 150K |
下拉 | 15K |
五、看门狗
1、看门狗使能
在工程makefile中需要设置 -DCFG_WDT_ENABLE宏
1 | 使能看门狗 |
0 | 关闭看门狗 |
2、喂狗
使能看门狗后,程序在低功耗状态会自行喂狗,但是退出低功耗后需要用户自定周期喂狗,否则会超时重启。