AC951常用说明
📎 原始文档:https://www.kdocs.cn/l/ceEUn8sCie40 AC951常用说明
- 代码启动流程 _start->_startup->main->loop:__die_here
2. IO口操作(以p06为例)
#define p0_dir 0x92 //IO方向
#define p0_out 0x93 //IO电平
#define p0_pu 0x94 //IO上拉
#define p0_pd 0x95 //IO下拉
#define p0_hd 0x96 //IO强驱
#define p0_die 0x97 //IO数字或模拟
#define p0_in 0x98 //IO输入电平检测
[p0_dir].6 = 0 //p06配置为输出
[p0_dir].6 = 1 //p06配置为输入
[p0_out].6 = 0 //p06配置为输出低
[p0_out].6 = 1 //p06配置为输出高
[p0_pu].6 = 0 //p06配置为上拉关闭
[p0_pu].6 = 1 //p06配置为上拉打开
[p0_pd].6 = 0 //p06配置为下拉关闭
[p0_pd].6 = 1 //p06配置为下拉打开
[p0_hd].6 = 0 //p06配置为强驱关闭
[p0_hd].6 = 1 //p06配置为强驱打开
[p0_die].6 = 0 //p06配置为模拟
[p0_die].6 = 1 //p06配置为数字
[p0_in].6 == 0 //判断p06输入电平是否为低
[p0_in].6 == 1 //判断p06输入电平是否为高
3. ad检测
adc_read_phy(ch,ana_ch)
ch:根据实际IO选择对应的AD通道,ADC_CH_ANA表示要测量内部电源
#define ADC_CH_P01 0
#define ADC_CH_P03 1
#define ADC_CH_P05 2
#define ADC_CH_P06 3
#define ADC_CH_P13 4
#define ADC_CH_P14 5
#define ADC_CH_P15 6
#define ADC_CH_ANA 7
ana_ch:普通IO的AD通道直接填写0,测量内部电源通道根据要测量的电源选择,例如测量电池电压(Vbat脚)选择ANA_VBAT
#define ANA_VBG 0
#define ANA_VCC 1
#define ANA_VEB 2
#define ANA_Vsense_OUT1 3
#define ANA_Vsense_OUT0 4
#define ANA_LINE_PROGI 5
#define ANA_BUCK_PROGI 6
#define ANA_VBAT 7
采集到的结果为左对齐的0~1023,存放在TR0(H)和TR1(L)中
4. PWM输出
PWM输出的两种状态:高阻态和IO输出态,有效时为输出态
初始化:
.global pwm_led_init
pwm_led_init:
[iomc3].7 = 1
w = D_PWM_PRD %% [pwm_prd] = w
[pwm_con0].5 = 1
[pwm_con0].4 = 0
[pwm_con0].3 = 1
[pwm_con0].2 = 0
[pwm_con0].1 = 0
[pwm_con0].0 = 1
寄存器说明:
[pwm_con0].7 ---PND
[pwm_con0].6 ---CLR_PND
[pwm_con0].5 ---SSEL PWM模块时钟源: 0-->wclk;1-->src_clk
[pwm_con0].4 ---PSET PWM模块时钟分频系数
[pwm_con0].3 ---PSET PWM模块时钟分频系数
[pwm_con0].2 ---PSET PWM模块时钟分频系数
[pwm_con0].1 ---PSET PWM模块时钟分频系数
[pwm_con0].0 ---EN
PWM模块时钟分频系数:[2:1]: 00-->div1 01-->div4 10-->div16 11-->div64
[3]: 0-->x1 1-->x2
[4]: 0-->x1 1-->x256
占空比:
w = duty %% call set_pwmx
duty为需要输出的占空比,set_pwmx可选为set_pwm0、set_pwm1、set_pwm2
duty的占空比是反向设置,0xFF对应0%,0x00对应100%
IO配置(以pwm0为例):
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 1 //有效状态输出高,非有效高阻
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 1 %% [p1_pd].3 = 1 //有效状态输出高,非有效为低电平(因为有下拉)
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 0 //有效状态输出低,非有效高阻
#define set_pwm0_io [p1_dir].3 = 0 %% [p1_out].3 = 0 %% [p1_pu].3 = 1 //有效状态输出低,非有效为高电平(因为有上拉)
5. 睡眠和唤醒
可参看芯片介绍的寄存器配置
睡眠:
注意:
1、睡眠前可能需要关闭一些IO(具体看外围),否则可能耗电
睡眠前需要关闭内部电源分压,否则会耗电
vcc_div_en = 0
vbat_div_en = 0
vout_div_en = 0
唤醒后需要重新打开(测量电源电压时需要)
vout_div_en = 1
vcc_div_en = 1
vbat_div_en = 1
2、将vout_discharge配置为0:vout_discharge = 0
唤醒:
两路普通IO口唤醒(IO可选任意普通IO)
#define io_wkup_rise(ch,port,n) \ //普通IO上升沿唤醒;例如p07:io_wkup_rise(ch0, p0, 7)
input_map(ch,port,n) %% \
bs port ## _pd,n %% \ //如有外部下拉,不要开内部下拉(bc port ## _pd,n)
bc port ## _pu,n %% \
bs port ## _die,n %% \
wkup_##ch(0)
#define io_wkup_fall(ch,port,n) \ //普通IO下降沿唤醒;例如p14:io_wkup_fall(ch1, p1, 4)
input_map(ch,port,n) %% \
bc port ## _pd,n %% \
bs port ## _pu,n %% \ //如有外部上拉,不要开内部上拉(bc port ## _pu,n)
bs port ## _die,n %% \
wkup_##ch(1)
以上:ch:只有两个,ch0和ch1
两路固定IO唤醒,p10和p11(不使用内部充电时可用)
#define voutx_wkup_set_rise(ch,n) \
bs p1_dir,n %% \
bs p1_pd,n %% \
bc p1_pu,n %% \
bs p1_die,n %% \
wkup_##ch(0)
#define voutx_wkup_set_fall(ch,n) \
bs p1_dir,n %% \
bc p1_pd,n %% \
bs p1_pu,n %% \
bs p1_die,n %% \
wkup_##ch(1)
p10 例:
wkup9_cpnd = 1
wkup9_vout0_sleep
wkup9_en = 1
voutx_wkup_set_rise(ch2, 0) //p10只能选ch2
p11 例:
wkup10_cpnd = 1
wkup10_vout1_sleep
wkup10_en = 1
voutx_wkup_set_rise(ch3, 1) //p11只能选ch3
注意:[wkup_flt]的低4位为4个ch的唤醒滤波使能(详见芯片介绍文档),没有开启唤醒功能的ch不能使能其对应的滤波使能,否则会耗电!
vcc唤醒(不使用内部充电时可用),两种唤醒方式:
1、比较唤醒,vcc接入电压大于电池电压唤醒
wkup6_cpnd = 1 %% wkup6_eie = 1 %% wkup6_sel1 = 1 %% wkup6_sel0 = 0
wkup6_inv = 0 //只能为0
2、跳变沿唤醒,出现指定的跳变沿时唤醒
wkup6_cpnd = 1 %% wkup6_eie = 1 %% wkup6_sel1 = 0 %% wkup6_sel0 = 1
wkup6_inv = 1 //下降沿唤醒
wkup6_inv = 0 //上升沿唤醒
6. vcc状态检测
不使用内部充电时可用
初始化检测:
bs 0x8f, 6 //clr wtd
sfr_rd_sel2 = 0 //bc 0xfc, 7
sfr_rd_sel1 = 1 //bs 0xda, 7
sfr_rd_sel0 = 1 //bs 0xda, 6
两种检测判断方式:
第一种,判断电平:
if(vcc_det_pg3 == 1) skip //btbn 0xe4, 2, 判断vcc的电平是否为高电平
第二种,判断vcc是否比电池电压大:
if(vcc_vbat_comp_pg3 == 1) skip //btbn 0xe4, 3, 判断vcc是否比电池电压大
例:
.global vcc_detect_read
vcc_detect_read:
bs 0x8f, 6 //clr wtd
sfr_rd_sel2 = 0 //bc 0xfc, 7
sfr_rd_sel1 = 1 //bs 0xda, 7
sfr_rd_sel0 = 1 //bs 0xda, 6
if(vcc_det_pg3 == 1) skip //btbn 0xe4, 2, 判断vcc的电平是否为高电平
// if(vcc_vbat_comp_pg3 == 1) skip //btbn 0xe4, 3, 判断vcc是否比电池电压大
goto __vcc_detect_offline
__vcc_detect_online:
ret
__vcc_detect_offline:
ret
7. 注意事项
①P06上电之前不能拉低,否则会不开机
②配置唤醒功能,唤醒前的电平必须与唤醒后的相反,否则会耗电,也就是sleep之前是高电平,需要配置为下降沿唤醒(不能是上升沿唤醒),sleep之前是低电平,需要配置为上升沿唤醒(不能是下降沿唤醒)。
③[wkup_flt]的低4位为4个ch的唤醒滤波使能(详见芯片介绍文档),没有开启唤醒功能的ch不能使能其对应的滤波使能,否则会耗电!
④不用到的IO口,sleep之前建议配置为输入模拟关上下拉,否则可能耗电(例如输入数字关上下拉,会有几十ua的耗电)