【国民技术N32G457评测】三、ADC及串口功能测试
本帖最后由 fxyc87 于 2022-1-21 16:47 编辑<p>我的相关历史贴子:</p>
<p> <a href="https://bbs.eeworld.com.cn/forum.php?mod=redirect&goto=findpost&ptid=1192408&pid=3117985" target="_blank">【国民技术N32G457评测】一、资料准备</a></p>
<p> <a href="https://bbs.eeworld.com.cn/thread-1192642-1-1.html" onclick="atarget(this)">【国民技术N32G457评测】二、开箱+点灯</a> </p>
<hr />
<p>测试ADC时,搞了半天,原因就是没有接VREF+,VREF-两个引脚,开发板上这两个引脚是悬空的,</p>
<p>怎么测试读取出的AD值都不对,直接接GND上读的是0,接VCC上是4095,接可变电阻上也是这两个值,</p>
<p>后来万用表测试AD参考电压才发现不对头</p>
<p>先上代码,再上照片</p>
<p>我是用的PC0引脚读取的一个可调电阻上的分压。</p>
<hr />
<p>主程序</p>
<pre>
<code class="language-cpp">static uint16_t adc_value=0;
static double adc_v=0;
int main(){
BspInit();
printf("app runing...\r\n");
printf("CPU clock=%d\r\n",SystemCoreClock);
//点亮指示灯
while(1){
Delay(100);
LED(1,Bit_SET);
LED(2,Bit_SET);
LED(3,Bit_SET);
Delay(100);
LED(1,Bit_RESET);
LED(2,Bit_RESET);
LED(3,Bit_RESET);
ADC_ClearFlag(ADC1,ADC_FLAG_ENDC);
ADC_EnableSoftwareStartConv(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_ENDC)==RESET);
adc_value=ADC_GetDat(ADC1);
adc_v=(double)adc_value/(double)4095*3.3;
printf("PC0 Volt=%0.2f\r\n",adc_v);
}
}</code></pre>
<p>BSP初始化程序</p>
<hr />
<pre>
<code class="language-cpp">#include <n32g45x.h>
#include <n32g45x_gpio.h>
#include <bsp.h>
#include <stdio.h>
static uint32_t Tick=0;
void BspInit(void){
//SystemInit(); .s中已调用,此处无需调用
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock/1000);
GpioInit();
USART1_Config();
AdcInit();
}
void GpioInit(void){ //GPIO初始化,包括LED
//开启IO时钟GPIOA,B,afio
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA|RCC_APB2_PERIPH_GPIOB|RCC_APB2_PERIPH_AFIO,ENABLE);
//PB4默认是JW-RESET 需要用该功能,见手册101页
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_NO_NJTRST,ENABLE);
//初始化IO
GPIO_InitType gpio;
gpio.Pin=GPIO_PIN_5|GPIO_PIN_4; //LED3,LED2
gpio.GPIO_Mode=GPIO_Mode_Out_PP;
gpio.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOB,&gpio);
gpio.Pin=GPIO_PIN_8; //LED1
gpio.GPIO_Mode=GPIO_Mode_Out_PP;
gpio.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOA,&gpio);
}
void AdcInit(void){
//adc pll=72mhz
RCC_ConfigAdcPllClk(RCC_ADCPLLCLK_DIV2,ENABLE);
//adc hclk/2=72mhz
RCC_ConfigAdcHclk(RCC_ADCHCLK_DIV2);
//adc 1m时钟
RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI,RCC_ADC1MCLK_DIV8);
//AD1时钟开启
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1,ENABLE);
//AD输入引脚配置
//GPIOC
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC,ENABLE);
//PC0 AD12-IN6
GPIO_InitType gpio;
gpio.Pin=GPIO_PIN_6;
gpio.GPIO_Mode=GPIO_Mode_AIN;
gpio.GPIO_Speed=GPIO_INPUT;
GPIO_InitPeripheral(GPIOC,&gpio);
//
ADC_InitType adc;
adc.WorkMode=ADC_WORKMODE_INDEPENDENT; //独立模式
adc.MultiChEn=DISABLE; //单一模式
adc.ContinueConvEn=DISABLE; //非连续
adc.ExtTrigSelect=ADC_EXT_TRIGCONV_NONE; //外部触发选择,软件手动触发
adc.DatAlign=ADC_DAT_ALIGN_R; //右对齐
adc.ChsNumber=1; //组合通道数
ADC_Init(ADC1,&adc); //初始化ADC1
ADC_Enable(ADC1,ENABLE); //开启并转换
ADC_StartCalibration(ADC1); //校准
while(ADC_GetCalibrationStatus(ADC1)==SET); //等待校准完成
//通道配置
ADC_ConfigRegularChannel(ADC1,ADC_CH_6,1,ADC_SAMP_TIME_1CYCLES5);
}
void LED(int number,Bit_OperateType val){ //点亮LED number:1-3val:Bit_SET/Bit_RESET
switch(number){
case 1:
GPIO_WriteBit(GPIOA,GPIO_PIN_8,val);
break;
case 2:
GPIO_WriteBit(GPIOB,GPIO_PIN_4,val);
break;
case 3:
GPIO_WriteBit(GPIOB,GPIO_PIN_5,val);
break;
}
}
void SysTick_Handler(void){
Tick++;
}
void Delay(uint32_t ms){
SysTick->VAL=0;
Tick=0;
while(Tick<ms);
}
void USART1_Config(void)
{
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
/* USART1时钟*/
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1 | RCC_APB2_PERIPH_GPIOA, ENABLE);
/* USART1 GPIO 配置 */
/* USART1 Tx (PA.09) 复用输出+上拉 */
GPIO_InitStructure.Pin = GPIO_PIN_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* USART1 Rx (PA.10)输入模式 */
GPIO_InitStructure.Pin = GPIO_PIN_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* USART1 工作模式*/
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO ;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(USART1, &USART_InitStructure);
USART_Enable(USART1, ENABLE);
}
/* printf要用 */
int fputc(int ch, FILE* f)
{
USART_SendData(USART1, (uint8_t)ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXDE) == RESET)
;
return (ch);
}
//end
</code></pre>
<p> </p>
<p>串口接收效果照片:</p>
<p></p>
<p> </p>
<p>开发板接线图:</p>
<p>把开发板上的VREFN接到GND,把VREFP接到3.3V</p>
<p>然后焊可20K的可调电阻,2端分别接VCC,GND,OUT接到PC0引脚,</p>
<p></p>
<p></p>
<p></p>
<p> </p>
<p>注意,开发板默认这两个VREF引脚 悬空,一定要接参考。我都翻车在这个位置上。</p>
<p>LED点灯相关我上个贴子已发过了,</p>
<p>ADC的难点就是时钟初始化</p>
<p>这款MCU用ADC竟然需要三路时钟,我第一次听说这么复杂的ADC,</p>
<p>其它的对着手册没啥问题,还有就是硬件了。</p>
页:
[1]