关于多路AD转换问题
我现在使用一块STC8H1K,芯片实验AD转换一路输入的时候可以,但增加一路,我想使用中断中改变引脚输入,无法实现,请高手指教,我的中断程序如下看看是什么原因:void ADC_Isr() interrupt 5
{
if(Fleg==0)
{
Fleg=1;
ADC_CONTR &= ~0x20; //清中断标志
ADH = ADC_RES; //A存储ADC的12位结果的高8位
ADL = ADC_RESL; //B存储ADC的12位结果的低4位,B为0
AD= ADH;
AD= AD << 2;
AD |= (ADL>>6);
ADC_CONTR |= 0x41; //继续AD转换
}
else
{
Fleg=1 ;
ADC_CONTR &= ~0x20; //清中断标志
ADH = ADC_RES; //A存储ADC的12位结果的高8位
ADL = ADC_RESL; //B存储ADC的12位结果的低4位,B为0
AD1= ADH;
AD1= AD1 << 2;
AD1 |= (ADL>>6);
ADC_CONTR |= 0x40; //继续AD转换
}
}
我使用了一个标志位,实现改变输入引脚,但不能实现
你切换adc使用的是ADC_CONTR |= 0x41;操作
这样是不对的。因为这样会造成0x40无法覆盖0x41.
所以应该在每个“//继续ad转换的语句前面”,加入一句
ADC_CONTR &= ~0x0f;
用以清除通道选择,这样就可以了 楼上对的,位或只能变1不能变0,操作一遍就全是1了
建议把使用的通道号声明为数组,然后就可以用++来自动扫描了
如
#define ADC_Num 2
ADC_Map={0xC0,0xC1}
中断函数中
ADC_Ch++
if(ADC_Ch==ADC_Num)
ADC_Ch=0
ADC_CONTR=ADC_Map void ADC_Isr() interrupt 5
{
static unsigned char CH_sw;
ADC_CONTR &= ~0x20; //清完成标志
switch(CH_sw)
{
case 0:
ADCRES = ADC_RES;
ADCRES = ADC_RESL;
CH_sw++;
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x40 | 0x0B; //启动AD转换 //ADC11 P03
break;
case 1:
ADCRES = ADC_RES;
ADCRES = ADC_RESL;
CH_sw++;
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x40 | 0x00; //启动AD转换 //ADC0 P10
break;
case 2:
ADCRES = ADC_RES;
ADCRES = ADC_RESL;
CH_sw++;
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x40 | 0x01; //启动AD转换 //ADC1 P11
break;
case 3:
ADCRES = ADC_RES;
ADCRES = ADC_RESL;
CH_sw = 0;
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x0A; //不启动AD转换 //ADC10 P02
ADC_over = 1;
break;
default:
CH_sw = 0;
ADC_CONTR &= 0xF0;
ADC_CONTR |= 0x0A; //不启动AD转换 //ADC10 P02
break;
}
}
王昱顺 发表于 2024-10-31 18:49
你切换adc使用的是ADC_CONTR |= 0x41;操作
这样是不对的。因为这样会造成0x40无法覆盖0x41.
所以应该在每个 ...
OK,谢谢,明白,昨晚我找到STC32G的例程看了看,就有这个语句,我又参考例程写了个程序,出现一个奇怪现象,我把P1.0口AD转换值在第一行显示,P1.1口AD转换值在第三行显示,运行时,结果正好相反,改变P1.0口电压值,第三行显示随着改变,改变P1.1口电压值,第一行显示随着改变,但如果把P1.0端口转换停止,改变P1.1口电压值,第三行变化正常,如果反之把p1.1口转换停止,改变p1.0端口电压,第一行随之改变,不知什么原因求解答,程序如下
/*****************************************************
******************************************************/
#include "STC8H.H"
#include <intrins.h>
#include "12864.h"
typedef unsigned char u8;
typedef unsigned int u16;
#define MAIN_Fosc 24000000UL
uchar yi,er,san,si,wu ,liu,qi,ba;
uchar num=0;
unsigned int AD,AD1;
float ADF;
u16 Get_ADC12bitResult(u8 channel);
void delay_ms(u8 ms);
void ADC_Init(void);//初始化
/**************************************************
函数:void STC_Init()
描述:STC8H 初始化
**************************************************/
void STC_Init()
{
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
}
/*********************************************************
* *
* 主函数 *
* *
*********************************************************/
void main()
{
STC_Init(); //初始化STC8H
lcdinit(); //初始化LCD
ADC_Init(); //初始化ADC
/******************************************/
photodisplay(Photo1); //显示图片1
delay(4000);
write(0,0x30); //基本指令操作
write(0,0x01); //清屏
/*************************************/
while(1)
{
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);
AD=Get_ADC12bitResult(0);
// ADF=AD*4.88;
// delay(2);
// AD=ADF;
wu= AD/1000;
liu = AD%1000/100;
qi= AD%100/10;
ba= AD%10;
write(0,0x80);
write(1,DIS5);
write(1,DIS5);
write(1,DIS5);
write(1,DIS5);
AD1=Get_ADC12bitResult(1);
AD1=Get_ADC12bitResult(1);
AD1=Get_ADC12bitResult(1);
yi= AD1/1000;
er= AD1%1000/100;
san = AD1%100/10;
si= AD1%10;
write(0,0x88);
write(1,DIS5);
write(1,DIS5);
write(1,DIS5);
write(1,DIS5);
/*********************************************/
}
}
//========================================================================
// 函数: u16 Get_ADC12bitResult(u8 channel)) //channel = 0~15
// 描述: 查询法读一次ADC结果.
// 参数: channel: 选择要转换的ADC, 0~15.
// 返回: 12位ADC结果.
// 版本: V1.0, 2016-4-28
//========================================================================
u16 Get_ADC12bitResult(u8 channel) //channel = 0~15
{
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xf0) | channel; //设置ADC转换通道
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0xDF)); //wait for ADC finish
ADC_CONTR &= ~0x20; //清中断标志
// ADC_FLAG = 0; //清除ADC结束标志
return (((u16)ADC_RES << 8) | ADC_RESL);
}
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
//========================================================================
// 函数: void Timer0_Init(void)
// 描述: ADC初始化函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-2
// 备注:
//========================================================================
void ADC_Init(void)// Timer0初始化
{
P1M0 = 0x00; //设置P1.0,P1.1为高阻
P1M1 = 0x03;
ADCTIM = 0x3f;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16,右对齐
ADC_CONTR = 0x80; //使能ADC模块
}
页:
[1]