完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
小生最近想调试一下STM32的内部温度传感器,用于对比内外温度相差多少 。可是开启ADC后,发现读到的数据不对,想请问下是否有人遇到过类似问题,望指点一二。下面为ADC的程序。
void Adc_init(void) { //先初始化IO口 RCC->APB2ENR|=1<<9; //ADC1时钟使能 RCC->APB2RSTR|=1<<9; //ADC1复位 RCC->APB2RSTR&=~(1<<9);//复位结束 RCC->CFGR&=~(3<<14); //分频因子清零 RCC->CFGR|=2<<14; ADC1->CR1&=0XF0FFFF; //工作模式清零 ADC1->CR1|=0<<16; //独立工作模式 ADC1->CR1&=~(1<<8); //非扫描模式 ADC1->CR2&=~(1<<1); //单次转换模式 ADC1->CR2&=~(7<<17); ADC1->CR2|=7<<17; //软件控制转换 ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发 ADC1->CR2&=~(1<<11); //右对齐 ADC1->SQR1&=~(0XF<<20); ADC1->SQR1&=0<<20; //1个转换在规则序列中 也就是只转换规则序列1 ADC1->SMPR1&=~(7<<18); //清除通道16原来的设置 ADC1->SMPR1|=7<<18; //通道16 239.5周期,提高采样时间可以提高精确度 ADC1->SMPR2&=0XFFFFFF0F;//通道1采样时间清空 ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度 ADC1->CR2|=1<<23; //使能温度传感器 ADC1->CR2|=1<<0; //开启AD转换器 ADC1->CR2|=1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。 ADC1->CR2|=1<<2; //开启AD校准 while(ADC1->CR2&1<<2); //等待校准结束 } //获得ADC值 //ch:通道值 0~3 //ADC规则序列寄存器 3(ADC_SQR3) u16 Get_Adc(u8 ch) { u16 re; //设置转换序列 ADC1->SQR3&=0xfffffff0;//规则序列1 通道ch ADC1->SQR3|=ch; ADC1->CR2|=1<<22; //启动规则转换通 while(!(ADC1->SR&1<<1));//等待转换结束 re= ADC1->DR; ADC1->SR|=~(1<<1); return re; //返回adc值 } u16 Get_Temperature(void) { u16 temp=0; u8 t; for(t=0;t<10;t++) { temp+=Get_Adc(16); delay_ms(5); } return temp=temp/10; } void show_ADC_TEMP(void) { u16 tem; u8 g,bai,shi,ge,c,d,e; float a,b; tem=Get_Temperature(); delay_ms(50); tem&=0X00ff; //不加这一句,只显示0,加之后,个位及小数位才有变化,可是数据也不对 a=(float)tem*(3.3/4096); b=a; b=(1.43-b)/0.0043+25; b=b*10000; bai=(u16)b/1000000; shi= (u16)b%1000000/100000; ge= (u16)b%100000/10000; g= (u16)b%10000/1000; c=(u16)b%1000/100; d=(u16)b%100/10; e=(u16)b%10; lcd_wcmd(0x80);//这些为LCD显示部分 lcd_wdat(bai+0x30); lcd_wdat(shi+0x30); lcd_wdat(ge+0x30); lcd_wdat('.'); lcd_wdat(g+0x30); lcd_wdat(c+0x30); lcd_wdat(d+0x30); lcd_wdat(e+0x30); } |
|
相关推荐
4个回答
|
|
Get_Adc 倒数第二句
ADC1->SR|=~(1<<1); 应为 ADC1->SR &= ~(1<<1); 你的程序主要是数值精度丢失的问题: Get_Temperature 返回的ADC读数最大为4095,最小为1 a=(float)tem*(3.3/4096); 这句里面的常数(3.3/4096)是个很小的数值,用浮点数表示这个常数表示这么小的数值,本身就没多少精度可言;运算后a的数值在1/4096到3.3之间,对于浮点数来说,已经丢失了很多数值精度; 建议你不要用浮点数,直接用读取的温度值转成u32或u64类型×1000000来计算,这样肯定不会丢失精度; 祝你好运 |
|
|
|
谢谢,我会参考此方法再验证一下,看看能否得到正确的结果,那再问一下:
tem&=0X00ff; //不加这一句,只显示0,加之后,个位及小数位才有变化,可是数据也不对 要加上这一句的原因也是精度问题导致的吗? |
|
|
|
【电子产品研发交流】:(323764552) 欢迎来群里共同探讨!
|
|
|
|
楼主这个只是读取ADC->DR寄存器的值,并没有将这个数值与温度关联起来,所以,你得到的数据并不是温度,所以你的数据显示个十百千是没有什么意义的 ,将DR寄存器的值和温度关联还需要一些步骤,具体的步骤手册上有,在A.7.16 Temperature computation code example。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
飞凌嵌入式ElfBoard ELF 1板卡-CAN编程示例之开发板测试
654 浏览 0 评论
该问题是用APP给芯海科技的CST92F25芯片发指令是出现的
2242 浏览 1 评论
771 浏览 0 评论
1530 浏览 1 评论
2276 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 11:15 , Processed in 0.838314 second(s), Total 80, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号