STM32
直播中

江左盟

9年用户 1507经验值
擅长:电源/新能源
私信 关注
[问答]

STM8S105K4T6使用ADC转换结果异常的原因?如何解决?

单片机:STM8S105K4T6
编程环境:STVD+COSMIC
使用引脚:PB0
实际现象:外接0v,转换结果0x0000 (好像小于1.6v都是0);外接1.6V,转换结果0x03ff ;外接3.3v,转换结果0x037f (好像大于2v都是0x03ff) ;
问题代码如下:
main.c文件
/*----------------------------------------------------------------------------*/
/* @Name  : main.c                             */
/* @Brief :                                 */
/* @Include: stm8s105k.h                           */
/*      stm8s105k_led.h                         */
/*----------------------------------------------------------------------------*/
//============================================================================//
/* include-------------------------------------------------------------------*/
#include "stm8s105k.h"
#include "stm8s105k_led.h"
/* define--------------------------------------------------------------------*/
/* extern--------------------------------------------------------------------*/
extern uint8_t ADC1_CONVER_FLAG;
/* main()--------------------------------------------------------------------*/
void main()
{
/* $ 局部变量定义------------------------------------------------------------*/
uint8_t i;
//open global interrupt
enableInterrupts();
//direction runing is ok
LED_Init;LED_ON;

/* $ ADC1初始化部分----------------------------------------------------------*/
//1.引脚模式:浮空输入
PB_DDR  = (uint8_t)~(1<<0);
PB_CR1  = (uint8_t)~(1<<0);
PB_CR2  = (uint8_t)~(1<<0);
//2.打开ADC时钟
CLK_PCKENR2 |= (uint8_t)(1<<3);
//3.选择ADC转换通道
ADC_CSR  = 0xF0;//通道0
ADC_CSR |= 0x00;
//4.关闭使用通道的斯密特触发器
ADC_TDRL |= (uint8_t)(1<<0);
//5.设置转换模式:带缓存的连续模式
ADC_CR1 |= (uint8_t)(1<<1);//使能连续转换
//(缓存满时,置位EOC,然后自动开始下一轮转换,所以进中断的第一件事是清CONT)
ADC_CR3 |= (uint8_t)(1<<7);//使用缓存
//6.关闭使用通道的模拟看门狗功能
ADC_AWCRL  = (uint8_t)~(1<<0);
//7.禁止模拟看门狗中断
ADC_CSR  = (uint8_t)~(1<<4);//写“0”禁止
//8.清除模拟看门狗中断标志
ADC_CSR  = (uint8_t)~(1<<6);
//9.禁止外部信号触发转换
ADC_CR2  = (uint8_t)~(1<<6);
//10.设置F_ADC频率:F_master/8
ADC_CR1  = 0x8F;
ADC_CR1 |= (uint8_t)0x40;
//11.使能转换结束中断
ADC_CSR |= (uint8_t)(1<<5);
//12.清除转换结束标志
ADC_CSR  = (uint8_t)~(1<<7);
//13.设置转换结果数据对齐方式:右对齐
ADC_CR2 |= (1<<3);//先读低,再读高
//14.将ADC从低功耗模式中唤醒
ADC_CR1 |= (uint8_t)(1<<0);
//15.等待ADC供电稳定(最小7us)
for(i=0;i<10;i++);//大概20us
//16.开始转换
ADC_CR1 |= (uint8_t)(1<<0);
LED_OFF;

while(1)
{
  if(ADC1_CONVER_FLAG==1)
   LED_ON;
}
}

stm8_interrupt_vector.c文件
/*----------------------------------------------------------------------------*/
/* @Name  : stm8_interrupt_vector.c                     */
/* @Brief :                                 */
/* @Include: stm8s105k.h                           */
/*      stm8s105k_led.h                         */
/*----------------------------------------------------------------------------*/
//============================================================================//
/* include-------------------------------------------------------------------*/
#include "stm8s105k.h"
#include "stm8s105k_led.h"
/* $ 别名定义----------------------------------------------------------------*/
typedef void @far (*interrupt_handler_t)(void);
/* $ 结构体定义--------------------------------------------------------------*/
struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};
/* $ 全局变量----------------------------------------------------------------*/
uint16_t adc1_valtage[10]={'�'};
/* $ 运行标志----------------------------------------------------------------*/
uint8_t ADC1_CONVER_FLAG = 0;
/* $ 中断函数----------------------------------------------------------------*/
@far @interrupt void NonHandledInterrupt (void)
{
/* in order to detect unexpected events during development,
    it is recommended to set a breakpoint on the following instruction
*/
return;
}
@far @interrupt void ISP_ADC1 (void)
{
uint8_t i;
uint8_t *pDBx =  ADC_DB0RH;
uint8_t temp_low,temp_high;
uint16_t temp;
ADC_CR1  = (uint8_t)~(1<<1);//关闭连续转换
if(!(ADC_CR3   (uint8_t)(1<<6)))//数据没有溢出,则将结果读出
{//数据右对齐,先读低,后读高
  for(i=0;i<10;i++)
  {
   temp_low = *(pDBx + 1) ;
   temp_high = *pDBx ;
   temp = ((uint16_t)temp_high<<8)+(uint16_t)temp_low;
   adc1_valtage[i] = temp;
   pDBx += 2;
  }
  adc1_valtage[10] = '�';
  ADC1_CONVER_FLAG = 1;
}
else //数据溢出,则从新转换一次
{
  ADC_CR3  = (uint8_t)~(1<<6);//清溢出标志
  ADC_CR1 |= (uint8_t) (1<<1);//使能连续转换
  ADC_CR1 |= (uint8_t) (1<<0);//开始转换
  LED_OFF;
}
ADC_CSR  = (uint8_t)~(1<<7);//清转换结束标志
return;
}
extern void _stext();     /* startup routine */
struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap  */
{0x82, NonHandledInterrupt}, /* irq0  */
{0x82, NonHandledInterrupt}, /* irq1  */
{0x82, NonHandledInterrupt}, /* irq2  */
{0x82, NonHandledInterrupt}, /* irq3  */
{0x82, NonHandledInterrupt}, /* irq4  */
{0x82, NonHandledInterrupt}, /* irq5  */
{0x82, NonHandledInterrupt}, /* irq6  */
{0x82, NonHandledInterrupt}, /* irq7  */
{0x82, NonHandledInterrupt}, /* irq8  */
{0x82, NonHandledInterrupt}, /* irq9  */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, NonHandledInterrupt}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, NonHandledInterrupt}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, ISP_ADC1}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};

stm8s105k_led.h文件
/*----------------------------------------------------------------------------*/
/* @Name  : stm8s105k_led.h                         */
/* @Brief :                                 */
/* @Include: stm8s105k.h                           */
/*----------------------------------------------------------------------------*/
//============================================================================//
#ifndef __STM8S105K_LED_H
#define __STM8S105K_LED_H
/* include-------------------------------------------------------------------*/
#include "stm8s105k.h"
/* define--------------------------------------------------------------------*/
#define LED_Init PE_DDR |= (uint8_t) (1<

回帖(1)

蒲泛粟

2024-5-13 18:15:38
STM8S105K4T6是一款8位单片机,使用ADC转换时出现异常的原因可能有以下几点:

1. 参考电压设置不正确:STM8S105K4T6的ADC转换结果与参考电压有关,如果参考电压设置不正确,可能导致转换结果异常。

2. 引脚配置问题:确保PB0引脚已正确配置为ADC输入。

3. 外部电路问题:检查外部电路连接是否正确,包括输入电压、电阻等。

4. 程序问题:检查程序中的ADC配置和转换逻辑是否正确。

针对您提供的代码和现象,以下是一些建议:

1. 检查参考电压设置:确保ADC的参考电压设置正确。STM8S105K4T6的ADC参考电压可以是Vref(AVDD),也可以是外部参考电压。根据您的描述,可能是参考电压设置不正确导致转换结果异常。

2. 检查引脚配置:确保PB0引脚已正确配置为ADC输入。在初始化代码中,应包含类似以下配置:

   ```c
   ADC1_ChannelConfig(ADC1_CHANNEL_8, ADC1_RANK_1, ADC1_SAMPLETIME_28_5);
   ```

3. 检查外部电路:确保外部电路连接正确,输入电压、电阻等无误。

4. 检查程序逻辑:检查您的程序中的ADC配置和转换逻辑是否正确。特别是ADC通道选择、时钟配置、触发方式等。

5. 使用STM8S105K4T6的官方库函数:STVD提供了STM8S105K4T6的官方库函数,使用这些库函数可以简化编程并减少错误。

6. 调试和测试:使用STVD的仿真功能,逐步调试和测试您的程序,以找到问题所在。

如果以上建议仍然无法解决问题,建议您查阅STM8S105K4T6的数据手册和参考例程,以获取更详细的信息和解决方案。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分