国产芯片
声明:本文旨在帮助自己记录芯片的常用配置过程。同时希望分享出自己的使用经验,让更多的人加入国产芯片的开发中。
新的技术往往都来自于模仿。从模仿到超越。芯片国产化的过程需要模仿已经比较成熟的产品,让使用者好入手,增加自己的用户量。
HHD32F107 AD采集,模拟量采集
1. AD模块简介
2. ADC相关的引脚
ADC模块属于HHD32F107的一个集成外设。
当我们要使用 MCU 外设时,需找到相应的管脚并通过 IOCONFIG 寄存器设置管脚的功能。
系统复位时,主 SWD 调试端口和 RESET 复位功能是默认设置,所有其他的管脚被设定为数字 GPIO。
2.1 与ADC直接关联的引脚
如下图所示,这些引脚是直接标有ADC功能的引脚。根据官方数据手册,ADC功能为 功能7。
值得注意的是,图中PB1的默认功能是PA4。
(1)我们在使用PB1引脚进行ADC测量时,需要将PA4设置为功能7。而PB1本身不需要配置。
(2)PA4本身并不具备ADC功能,通过配置PA4成为功能7,才可以让PB1成功功能7。(这是非常特殊与难以理解的)
(3)拓展说明,在希望将PA4引脚配置成SPI1_NSS功能时,需要配置PG11。(实际使用的是PA4 , 但是却需要配置PG11) 。由此可知,官方手册里,要使用某个引脚,需要配置其默认功能的引脚。
(4)上述问题,暂无官方解释,只能靠用户自己猜想原因。
2.2 软件中的引脚配置和ADC初始化
(1)引脚配置表,进行引脚配置
实话是活,这里存在一个很讨厌的问题,文档中的通道定义是从通道0到通道15,而代码中的底层定义则是通道1到通道16。文档和代码底层冲突。
同时,我们会发现,PB1的通道,合并到了PA4上。导致少了一个ADC采集通道。
//下面的第三个参数 7 ,表示配置引脚为功能7
ST_PINS pins_table[] = {
//未使用//__HHD_PIN(A, 0, 7, INPUT, GPIO_Mode_DEF),//ADC IN0 (对应代码中通道IN1)
//未使用//__HHD_PIN(A, 1, 7, INPUT, GPIO_Mode_DEF),//ADC IN1 (对应代码中通道IN2)
//未使用//__HHD_PIN(A, 2, 7, INPUT, GPIO_Mode_DEF),//ADC IN2 (对应代码中通道IN3)
//未使用// __HHD_PIN(A, 3, 7, INPUT, GPIO_Mode_DEF),//ADC IN3 (对应代码中通道IN4)
//这里配置的PA4,实际是PB1引脚变成ADC功能。PA4引脚没有ADC功能。
__HHD_PIN(A, 4, 7, INPUT, GPIO_Mode_DEF),//ADC PB1 IN4 (对应代码中通道IN5)
__HHD_PIN(A, 5, 7, INPUT, GPIO_Mode_DEF),//ADC IN5 (对应代码中通道IN6)
__HHD_PIN(A, 6, 7, INPUT, GPIO_Mode_DEF),//ADC IN6 (对应代码中通道IN7)
__HHD_PIN(A, 7, 7, INPUT, GPIO_Mode_DEF),//ADC IN7 (对应代码中通道IN8)
__HHD_PIN(B, 0, 7, INPUT, GPIO_Mode_DEF),//ADC PB0 IN8 (对应代码中通道IN9)
//缺少一个通道定义 理论上是PB1的配置,对应PB1(实际PB1跑到了PA4所在的ADC通道位置)
__HHD_PIN(C, 0, 7, INPUT, GPIO_Mode_DEF),//ADC PC0 IN10 (对应代码中通道IN11)
//未使用//__HHD_PIN(C, 1, 7, INPUT, GPIO_Mode_DEF),//ADC PC1 IN11 (对应代码中通道IN12)
//未使用//__HHD_PIN(C, 2, 7, INPUT, GPIO_Mode_DEF),//ADC PC2 IN12 (对应代码中通道IN13)
//未使用//__HHD_PIN(C, 3, 7, INPUT, GPIO_Mode_DEF),//ADC PC3 IN13 (对应代码中通道IN14)
__HHD_PIN(C, 4, 7, INPUT, GPIO_Mode_DEF),//ADC PC4 IN14 (对应代码中通道IN15)
__HHD_PIN(C, 5, 7, INPUT, GPIO_Mode_DEF),//ADC PC5 IN15 (对应代码中通道IN16)
}
//调用并初始化上述 ADC引脚
void IO_init(void)
{
int i = 0;
int pins_table_len = sizeof(pins_table)/sizeof(ST_PINS);
for(i = 0; i < pins_table_len; i++)
{
init_pin(pins_table+i);//设置引脚方向,打开该引脚到外设时钟APB2
}
}
//ADC模块初始化
void init_ADC(void)
{
ENABLEADC2CLK;
RESETADC2;
ADC_Init(ADC2, 100000); //转换速率为1000000Hz
ADC_SetupChannels(ADC2,
DR0EN | DR1EN | DR2EN | DR3EN | DR4EN | DR5EN | DR6EN | DR7EN , //8路数据结果都开启
CHN5_DR0 | //PB1 ADC12_IN4 1V (配置PA4)
CHN6_DR1 | //PA5 ADC12_IN5 12V (1/5.99) 2.003V
CHN7_DR2 | //PA6 ADC12_IN6 5V (1/2) 2.5V
CHN8_DR3 | //PA7 ADC12_IN7 电路图中未使用
CHN9_DR4 | //PB0 ADC12_IN8 1.4V
CHN11_DR5| //PC0 ADC123_IN10 1.8V
CHN15_DR6| //PC4 ADC123_IN14 EPHY 2.5V(1/1.249)2.002V
CHN16_DR7, //PC5 ADC123_IN15 1.2V
TRIGGERMODE); //TRIGGERMODE (触发模式) BURSTMODE(突发模式)
ADC_SetTrigger(ADC2,ADC_START_BY_SOFTWAER,0);//采取软件触发,上升沿有效
}
一个ADC模块最多只能有8路数据输出,所以要想开启更多的ADC通道,需要使用ADC1和ADC2。
(2)补充:上述中,虽然对PA4进行直接配置,但PA4引脚本身不具备ADC功能。
PA4可以 配置成 SPI1 NSS。但也需要通过配置其他引脚PG11的方式,使PA4具有该功能。
//如果需要将 PA4 配置成 SPI1 NSS (功能1) ,需要配置PG11
__HHD_PIN(G, 11, 1, OUTPUT, GPIO_Mode_DEF), // 实际使用的是PA4
2.3 软件中的ADC数据采集
#define ADC_Channel_num 8 //共采集8路
#define sample_num 3 //每路采集3次,得到一个结果
uint16_t AdcValue[sample_num][ADC_Channel_num]; //ADC采样数据
void delaysoft(int DelayData)
{
int i = 0;
while(i <= DelayData)i++;
}
void GetADCVoltage(uint8_t num)
{
uint8_t i;
//OS_CPU_SR cpu_sr;
if(num>=sample_num) //采样次数不能超过sample_num
num=2;
ADC2_IssueSoftTrigger; //(1) 0x040 SSCR 软件触发转换控制
delaysoft(100); //延迟确保数据刷新
//OS_ENTER_CRITICAL();
for(i=0;i<ADC_Channel_num;i++)
{
AdcValue[num][i]=ADC_GetConversionData(ADC2, i);//(2) 读取指定通道的数据
}
//OS_EXIT_CRITICAL();
}