【AT32F421测评】+ ADC采样及SPI_OLED显示
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">这篇文章将来测评</font>AT32F421的硬件SPI和12位的ADC,首先,硬件SPI将以SPI_OLED的形式来呈现,ADC通过测试实际的电压来测试。</span></span></span></span></p><p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">我选用的</font>OLED是市面上常见的0.96寸OLED,它支持I2C和SPI接口,我将用AT32的硬件SPI将其驱动,同时作为ADC测到的电压值的显示屏。</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">首先,因为市面上用</font>0.96寸的OLED的人很多,所以一些开发者或商家就编写其的通用驱动,为了提高开发效率,避免重复造轮子,我选用某园的驱动,它提供了非常多的例程,我就在其基础上修改。</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">首先,在</font>HARDWARE文件夹中新建SPI.c、SPI_OLED.c 、ADC.c等三个C文件及其对应的h头文件。然后在FWLIB中添加at32f4xx_spi.c、at32f4xx_adc.c和at32f4xx_dma.c如下图所示</span></span></span></span></p>
<p style="text-align:justify"></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">第二步,将某园的模拟</font>SPI驱动复制到SPI_OLED.c,同时将</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体">OLED_WR_Byte</span></span><span style="font-size:16.0000pt"><span style="font-family:黑体">,也就是写入一个字节的函数修改为下图所示,将软件模拟的传输过程用硬件SPI的发送函数SPI_I2S_TxData来代替发送.</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">因为</font>SPI_OLED上还有DC和RST引脚,这里我分别用PA6和PA4来代替,如下图所示,</span></span></span></span></p>
<p style="text-align:justify"></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">其他的驱动函数不用修改。</font></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">第三步,配置</font>AT32F421的硬件SPI,首先在SPI.c中的添加如下函数,以便在主函数中调用(参考官方提供的BSP中AT_START_F421中的Simplex_Interrupt示例).这里需要注意的是,第一,我们要用SPI,要进行GPIO配置,SPI对应时钟和GPIO对应时钟配置,还有就是SPI参数配置;第二,根据0.96寸OLED所使用的SSD1306驱动芯片的SPI接口的时序图,时钟初始电平可高可低,然后在上升沿的时候传输数据,所以我这里通过</span></span><i><u><span style="font-size:14.0000pt"><span style="font-family:黑体"><span style="font-weight:normal"><span style="text-decoration:underline"><span style="text-underline:single"><span style="font-style:italic">SPI_InitStructure.SPI_CPOL = SPI_CPOL_LOW;</span></span></span></span></span></span></u></i><span style="font-size:16.0000pt"><span style="font-family:黑体"><span style="font-weight:normal"><span style="font-style:normal"><font face="黑体">将</font></span></span></span></span><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">初始电平配置为低电平</font>;然后通过</span></span><i><u><span style="font-size:14.0000pt"><span style="font-family:黑体"><span style="font-weight:normal"><span style="text-decoration:underline"><span style="text-underline:single"><span style="font-style:italic">SPI_InitStructure.SPI_CPHA = SPI_CPHA_1EDGE;</span></span></span></span></span></span></u></i><span style="font-size:16.0000pt"><span style="font-family:黑体"><span style="font-weight:normal"><span style="font-style:normal"><font face="黑体">将其配置为第一个边沿变化传输</font>,也就是上升沿.(这里补充一点,可能是个人对时序图的理解有误,在CPOL和CPHA不是配置为上面的配置时,在进行实验后似乎也是可以驱动的,但我的建议是最好配置为上述的配置),具体配置如下图所示</span></span></span></span></span></span></p>
<p style="text-align:justify"></p>
<p style="text-align:left"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">第四步</font>,配置ADC,这里参考官方提供的BSP中AT_START_F421中的ADC1_DMA示例,这里我只讲重点,具体配置见附件,这里的测出来ADC数据是通过DMA搬运到某变量数组里的,通过</span></span><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)ADC_RegularConvertedValueTab;</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">DMA_InitStructure.DMA_BufferSize = 1;</span></span></span></span></span></p>
<p style="text-align:justify"> </p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">将测出来的电压搬运到</font>ADC_RegularConvertedValueTab这个数组里面,</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">然后</font>,我将依次测试ADC测量外部电压和内部参考电压.</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">下面这么写是测量</font>ADC1的通道1的外部电压值,也就是PA1的外部值</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239_5);</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">//测试通道1</span></span></span><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0"> PA1</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">下面这么写是可以测量内部参考电压</font></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,1,ADC_SampleTime_239_5);//测试内部参考电压</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0"><font face="黑体">记得添加上下面这句</font>,这个是使能ADC测量内部温度传感器和参照电压的函数</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">/* Enables Temperature Sensor and Vrefint Channel */</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">ADC_TempSensorVrefintCtrl(ENABLE);</span></span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">最后</font>,在主程序中写入如下函数,单片机将1s的刷新速度更新采集到的实际电压值,这里需要进行一个转化,</span></span><span style="font-size:12.0000pt"><span style="font-family:黑体"><span style="color:#00b0f0">ADC_RegularConvertedValueTab*3282/4096.0;</span></span></span><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">这条语句中的</font>3282就是代表我用万用表测到的单片机的工作电压为3282mv,不同情况下该电压值可能会不同,这个是需要修改的.</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">最后展示一下实际测量结果</font>,先测量一下单片机内部的参考电压,根据数据手册,此参照电压应该在1.20V附近</span></span></span></span></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">实际测量为</font>1.206V,符合标准</span></span></span></span></p>
<p style="text-align:justify"></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">接下来测试不同电压值</font>,经过和四位半的已校准的万用表进行对比,AT32F421的ADC还是非常可靠的 ,精度很高</span></span></span></span></p>
<p style="text-align:justify"></p>
<p style="text-align:justify"><span style="font-size:10.5pt"><span style="font-family:Calibri"><span style="font-size:16.0000pt"><span style="font-family:黑体"><font face="黑体">本次对</font>AT32F421的ADC和SPI测试完毕</span></span></span></span></p>
<p>能和四位半的已校准的万用表进行对比精度,测试成功</p>
<p>看来这芯片ADC模拟部分做的挺好的。响应速度呢?</p>
<p>写的很详细啊,谢谢楼主的分享。</p>
freebsder 发表于 2021-5-6 16:23
看来这芯片ADC模拟部分做的挺好的。响应速度呢?
<p>这个倒是还没测</p>
<p>为什么下载不了</p>
<p> </p>
<p>怎么下载不了呢</p>
dongdejun1989 发表于 2021-6-10 10:59
怎么下载不了呢
<p>说的是帖子里的附件吗,我刚下载正常,你再试试?</p>
<p>有阅读权限 10</p>
<p>写的很好</p> <p>怎么不好下载了??</p> <p>下载不了附件</p>
下载不了呀
页:
[1]