瑞萨的官网上给了不少的例子,除了开发板自带的那个,还包括了ADC啊,串口通信等等。由于等灯等灯要用光敏电阻采集光照信号,所以AD是不可少的,今天就从利用官方例程和配套的硬件说明书来理解下寄存器设置和AD的初始化。
手头这个R7F0总共有4个模拟AD输入端口,分别在P0.1-P0.4,可以通过配置获得10位或者8位精度。在ADC初始化中,用到了以下代码
void ADC_Init(void)
{
ADCEN = 1U; /* supply AD clock */
ADM0 = _00_AD_ADM0_INITIALVALUE; /* disable AD conversion and clear ADM0 register */
ADMK = 1U; /* disable INTAD interrupt */
ADIF = 0U; /* clear INTAD interrupt flag */
/* Set INTAD low priority */
ADPR1 = 1U;
ADPR0 = 1U;
/* Set ANI0 pin */
PMC0 |= 0x02U;
PM0 |= 0x02U;
ADM0 = _18_AD_CONVERSION_CLOCK_1 | _02_AD_TIME_MODE_NORMAL_2;
ADM2 = _00_AD_RESOLUTION_10BIT;
ADS = _00_AD_INPUT_CHANNEL_0;
}
首先,ADCEN是PER0^5,使能AD时钟。文档说了,除了PMC0和PM0(这个和端口有关),其他和AD相关的寄存器,在ADCEN没有置1的时候,是不能操作的,切记。
然后是ADM0,用来启停AD和设置转换速度。程序开始先对ADM0清零,在操作完中断和端口后,再赋值,其中0x18是速度,主时钟不分频,0x02表示LV0选1,文档表格中有很多对应选项,但是为什么有很多禁止项呢?其实大概想想,应该是受AD转换速度影响的,所以时钟很高,也无法突破AD本身的速度。
ADM2用来控制转换精度。只有最后一位有用,默认0,10位分辨率,1表示8位
然后是通道寄存器,ADS,本身很简单,0-3.但是在使用AD通道前,必须要设另两个端口属性,一个是PMC,设定是数字口还是模拟口,这里PMC0=0x02就是选择CH0,有一点不好,AD的ch号和IO口的号刚好差1,感觉很容易弄错了。另一个是PM,值和PMC是一样的,有点迷糊这两个有什么区别。
转换结果存在ADCRH和ADCRL里面,8+2模式。
还有没涉及的,ADMK、ADIF、ADPR1、ADPR0想来是设置中断和优先级的。
初始化完成以后,则要启停AD,分别用注意,启动顺序ADCE、ADMK、ADIF、ADCS;而stop则顺序正好相反。在待机状态下(AD转换完成后),则只有ADCS=1,可以重启AD。
至此,AD设置完成,最后无非写个中断程序,读取AD值,并显示。在我做的等灯里面,基本以模拟量输出,所以测量结果,我们就以变量窗口来看吧。在开发板上,直接有电位器连到ch0上,看来这个程序直接可用啊。运行起来,测量结果如下(VDD=4.88V)还是蛮精确的。对于我的应用足够了。
AD | 万用表测量V | 用AD推算 | 误差 |
100 | 0.475 | 0.4765625 | 0.003289 |
552 | 2.63 | 2.630625 | 0.000238 |
757 | 3.6 | 3.60757813 | 0.002105 |
853 | 4.05 | 4.06507813 | 0.003723 |
顺手把AD精度改成8bit,读了一下ADCRH,表示没错,是这8位。后续的PWM调整就可以直接把AD结果写进去了,嘿嘿。就是现在还不知道PWM是几位的。今天的没什么图,因为基本就是代码,比较枯燥。等PWM出来,看到灯的效果,再上效果图啦。