一、基础知识
1.1位操作
对寄存器的bit5写0:
寄存器&=~(1<<5);
现在运用你的C语言知识分析一下,把十进制的1写成二进制32位数就是:
00000000000000000000000000000001
(1<<5)就是把1右移5下,左面补零,执行完这句话以后数就变成:
00000000000000000000000000100000
~(1<<5)就是再把这个数反相:
11111111111111111111111111011111
最后呢!再把这个数&给寄存器,所以执行完以后,除了bit5被改成了0,其它的位都没有变。
对寄存器的bit5写1:
寄存器|=(1<<5);
现在运用你的C语言知识分析一下,把十进制的1写成二进制32位数就是:
00000000000000000000000000000001
(1<<5)就是把1右移5下,左面补零,执行完这句话以后数就变成:
00000000000000000000000000100000
最后呢!再把这个数| 给寄存器,所以执行完,除了bit5被改成了1,其它的位为0。
二、代码分析
/*****************************************/
/* 函数名称:初始化ADC口(AD7) */
/*****************************************/
void ADC_Init(void)
{
SYSCON->PDRUNCFG &= ~(0x1<<4); // ADC模块上电
SYSCON->SYSAHBCLKCTRL |= (1<<13); // 使能ADC时钟
SYSCON->SYSAHBCLKCTRL |= (1<<16); // 使能IOCON时钟
IOCON->PIO1_11 &= ~0x9F; // 把P1.11引脚选择模拟输入方式
IOCON->PIO1_11 |= 0x01; // 把P1.11引脚设置为AD7功能
SYSCON->SYSAHBCLKCTRL &= ~(1<<16); // 关闭IOCON时钟
ADC->CR = (1<<7)| /* bit7:bit0 选择通道7作为ADC输入,即P1.11引脚 */
(23<<8 )| /* bit15:bit8 把采样时钟频率设置为2MHz 48/(23+1)*/
(1<<16 )| /* bit16 硬件扫描模式 */
(0<<17 )| /* bit19:bit17 10位模式 */
(0<<24 ); /* bit26:bit24 硬件扫描模式下这些位置0 */
}
SYSCON->PDRUNCFG &= ~(0x1<<4); // ADC模块上电
#define SYSCON ((SYSCON_TypeDef *) SYSCON_BASE) //系统配置
RW_en PDRUNCFG; /掉电配置 寄存器,地址偏移: 0x238 (R/W) */
第8-31位为保留位
SYSCON->SYSAHBCLKCTRL |= (1<<13); // 使能ADC时钟
系统AHB时钟控制寄存器SYSAHBCLKCTRL全部位结构,其字节地址为0x400480080
SYSCON->SYSAHBCLKCTRL |= (1<<16); // 使能IOCON时钟
IO配置模块时钟控制位
IOCON->PIO1_11 &= ~0x9F; // 把P1.11引脚选择模拟输入方式
0x9F:1001 1111
~0x9F:0110 0000
IOCON寄存器:0000 0000 0000 0000 0000 0000 0000 0000
IOCON->PIO1_11 |= 0x01; // 把P1.11引脚设置为AD7功能
SYSCON->SYSAHBCLKCTRL &= ~(1<<16); // 关闭IOCON时钟
之前开时钟,现在又关闭,没理解。
IOCON模块的作用是什么?
是改变IO的功能,改变了IO的功能以后,程序运行过程中就不需要改变IO的功能了,所以就关了时钟省电
比如某个引脚,本来是GPIO,我在项目中,要用这个引脚的ADC功能,那么把这个引脚初始化为ADC功能以后,就不需要改变IO的功能了,所以关了IOCON时钟省电
ADC->CR = (1<<7)| /* bit7:bit0 选择通道7作为ADC输入,即P1.11引脚 */
(23<<8 )| /* bit15:bit8 把采样时钟频率设置为2MHz 48/(23+1)*/
(1<<16 )| /* bit16 硬件扫描模式 */
(0<<17 )| /* bit19:bit17 10位模式 */
(0<<24 ); /* bit26:bit24 硬件扫描模式下这些位置0
(1)第0-7位(SEL)引脚选择位,置1有效。当第16位(BURST)置0,只能选择一个通道,当第16位(BURST)置1,允许多位置1;
(2)APB 时钟 (PCLK) 被 CLKDIV +1 分频,产生 ADC 时钟。
/********************************************/
/* 函数功能:读取电压值(AD7) */
/* 出口参数:adc_value, 读到的电压值 */
/********************************************/
uint32 ADC_Read(void)
{
uint32 adc_value=0;
uint8 i;
adc_value = ADC->DR[7]; //读取第一次的值
adc_value = 0; // 丢弃
for(i=0;i<10;i++) // 再连续读取10个电压值
{
delay_us(6);
adc_value += ((ADC->DR[7]>>6)&0x3FF);
}
adc_value = adc_value/10; // 把读到的10个电压值取平均值
adc_value = (adc_value*Vref)/1024; // 转换为真正的电压值
return adc_value; // 返回结果
}
adc_value += ((ADC->DR[7]>>6)&0x3FF); /* 提取 10 位的 A/D 转换结果 */
adc_value =adc_value+(ADC->DR[7]>>6)&0x3FF);
ADC->DR[7]:A/D 通道 7 数据寄存器。该通道包含在通道 7 上完成。
读取通道7的AD值
0x3FF:
0011 1111 1111
0000 0000 0000 0000 0000 0000 0000 0000
右移6位的原因是ADC对应的DR寄存器中0-5位是保留(数据手册有说明可以查的到),如果要用的话需要先移位再使用,后面的3FF是因为ADC处理的数据都是10位的精度所以要“&”一下。
三、PT100
T100电阻是指铂热电阻,其中PT是指“铂”元素;100是指铂热电阻的特性在0℃时,电阻值刚好是100Ω,在100℃时它的阻值约为138.5Ω。