STC单片机自带AD代码问题

STC单片机自带AD代码问题,第1张

同学,你的问题有问题

你是想问STC系列单片机的AD问题还是串口问题

你上面这段程序是51单片机串口初始化程序而不是AD程序。

51单片机串口初始化为

void COM_Init(void)

{

SCON = 0x50;

TMOD &= 0x0F;

TMOD |= 0x20;

PCON |= 0x80;

TH1 = 0xFD;

ES=1;EA=1;

TR1 = 1;

TI = 1;

}

AD转换程序

//定义与ADC有关的特殊功能寄存器

sfr ADC_CONTR =0xC5;

sfr ADC_DATA =0xC6;

sfr ADC_LOW2 =0xBE;

sfr P1M0 =0x91;

sfr P1M1 =0x92;

sbit p20 =P2^0;

void STC90CxxAD_delay(int timer) //延时函数

{

while(timer--);

}

int Ad_Change(char channel) //AD转换

{

int AD_Result_Temp = 0 ;

P1 = 0xff; //将P1口置高,为A/D转换作准备

ADC_CONTR = ADC_CONTR|0x80; //1000,0000打开A/D转换电源

P1M0 = 0x03; //0000,0011用于A/D转换的P1x口,先设为开漏

P1M1 = 0x03; //0000,0011P10--P11先设为开漏。断开内部上拉电阻

STC90CxxAD_delay(20); //20

ADC_CONTR = ADC_CONTR&0xE0; //1110,0000 清ADC_FLAG,ADC_START位和低3位

ADC_CONTR = ADC_CONTR|(channel); //设置当前通道号

STC90CxxAD_delay(1); //延时使输入电压达到稳定

ADC_DATA = 0; //清A/D转换结果寄存器

ADC_LOW2 = 0;

ADC_CONTR = ADC_CONTR|0x08; //0000,1000ADCS = 1,启动转换

do { ; }

while((ADC_CONTR & 0x10)==0); //0001,0000等待A/D转换结束

ADC_CONTR = ADC_CONTR&0xE7; //1110,0111清ADC_FLAG位,停止A/D转换

AD_Result_Temp = ((AD_Result_Temp|ADC_DATA)<<2)|(ADC_LOW2&0x03);

//保存返回AD转换的 结果

STC90CxxAD_delay(1); //

return AD_Result_Temp;

}

已调试通过,望对你有用

void Timer3_Init()

{

TMR3CN = 0x02;

TMR3R = -44236; //定时2ms

TMR3 = 0xffff;

EIE2 &= ~0x01;

TMR3CN |= 0x04;

}

void ADC0_Init(void)

{

AMX0SL=0x00; //选择通道0

AMX0CF=0x00; //选择AIN0和AIN1为独立输入

REF0CN=0x03; //选择外部的电压为基准电压

ADC0CF=(SYSCLK/2500000)<<3;//时钟为 ,增益为1

ADC0CN=0x84;//ADC0使能且为ADCBUSY的开启方式

EIE2|=0x02;//开启ADC0的中断

}

void ADC0_ISR() interrupt 15

{

static unsigned int_dec=INT_DEC;

static long accumulator=0L;

AD0INT = 0; // 清 ADC 中断标志位

accumulator += ADC0; // 累加ADC采样数据

int_dec--; // 指针减1

if (int_dec == 0) // 累加完了吗?

{

int_dec = INT_DEC; // 指针复位

result = accumulator >> 8;

accumulator = 0L; // 累加和变量清0

t=1;

}

}ADC0转换,定时器3开启的方式

DDRC=0X00;

PORTC=0X00;

ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADATE)|(1<<ADSC); //ADC使能

ADMUX=0x43;

atmega88只有6路输入没有ADC6或者ADC7,只能用PC0~PC5

这个问题需要有实物调试,

原因可能有很多,硬件,软件方面。

思路是:

先排除硬件问题,用这个SPI通道测试一下其他通讯

再仔细对照一下AD7190的规格书,看看初始化,设置是否正确,

然后再检查一下发送接收的过程和步骤是否正确。

整理一下代码:

void SPI_Init(void)

{

 RCC->APB2ENR|=1<<3; //PB的时钟使能

 RCC->APB1ENR|=1<<14; //SPI2时钟使能

 GPIOB->CRH&=0X000F0FFF; //PB11 PB13 PB15复用推挽 PB14浮空输入

 GPIOB->CRH|=0XB4B0B000;

 GPIOB->ODR|=1<<11; //上拉

 GPIOB->ODR|=1<<13;

 GPIOB->ODR|=1<<15;

 SPI2->CR1|=0<<10;  //全双工

 SPI2->CR1|=1<<9;   //软件SSM,NSS引脚的电平由SSI位的值决定

 SPI2->CR1|=1<<8;   //SSI位

 SPI2->CR1|=1<<2;   //配置为主设备

 SPI2->CR1|=0<<11;  //使用8位数据格式

 SPI2->CR1|=1<<1;   //空闲状态sck=1保持高电平

 SPI2->CR1|=1<<0;   //数据采样从第二个时钟边沿开始

 SPI2->CR1|=3<<3;    //fsck=36M/16 波特率控制

 SPI2->CR1|=0<<7; //先发送MSB 

 SPI2->CR1|=1<<6; //使能spi设备

}

void SPI2_Send_ReveiceFull(u8 data,u8 len)

{

CS=0;

for(i=0;i<len;i++)

{

while((SPI2->SR&(1<<1))==0); //检查spi标志位设置与否,发送缓存空标志位TXE=1为空跳出

SPI2->DR=(data+i);

while((SPI2->SR&(1<<0))==0); //检查指定spi标志位设置与否,接受缓存非空标志位RXNE为非空跳出

temp=SPI2->DR;

(AD7190_ReveiceData+len-i-1)=temp;

}

CS=1;

}

void AD7190_Init(void)

{

//复位

AD7190_SendaData[2]=0xff;

AD7190_SendaData[1]=0xff;

AD7190_SendaData[0]=0xff;

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

//设置配置寄存器

AD7190_SendaData[0]=0x10;

SPI2_Send_ReveiceFull(AD7190_SendaData,1);

AD7190_SendaData[2]=0x10;   //基准电压选择需确定

AD7190_SendaData[1]=0x03; //通道选择需配置

AD7190_SendaData[0]=0x07; //输入范围 

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

//设置模式寄存器

AD7190_SendaData[0]=0x08;

SPI2_Send_ReveiceFull(AD7190_SendaData,1);

AD7190_SendaData[2]=0x10; //使用外部时钟

AD7190_SendaData[1]=0x03;

AD7190_SendaData[0]=0xff;

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

//读模式

for(i=0;i<4;i++)AD7190_SendaData[i]=0x00;

AD7190_SendaData[0]=0x48;

SPI2_Send_ReveiceFull(AD7190_SendaData,1);

AD7190_SendaData[0]=0x00;

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

//读配置寄存器

AD7190_SendaData[0]=0x50;

SPI2_Send_ReveiceFull(AD7190_SendaData,1);

SPI2_Send_ReveiceFull(AD7190_SendaData,3);

//读数据寄存器

AD7190_SendaData[0]=0x5C; //5C

SPI2_Send_ReveiceFull(AD7190_SendaData,1);

AD7190_SendaData[0]=0xff;

}

要在 AD 域控制器上设置开机启动 EXE 程序,可以按照以下步骤进行 *** 作:

1 在域控制器上登录管理员账号。

2 按下“Win+R”组合键打开运行窗口,输入“shell:startup”,然后按“Enter”键,进入当前用户的启动项目文件夹。

3 将需要设置开机启动的 EXE 程序复制到该文件夹中。

4 右键点击复制进来的 EXE 程序,并选择“属性”。

5 在d出的属性对话框中,选择“常规”选项卡,然后勾选“以管理员身份运行”选项框。

6 点击“确定”按钮关闭属性对话框。

现在,每次域控服务器重启时,复制进来的 EXE 程序都将自动启动。如果您想在所有用户登录域控服务器的时候都自动启动该程序,可以在“C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp”目录下创建一个快捷方式,以确保在所有用户登录时都能够启动该程序。

简单点,建立32位变量A,每采样一次就加到A,采样完8次再除以8就好了,

u16 ADC_ZKB(u8 Channel)

{

u32 value1=0;

u16 value;

u8 i;

for(i=0;i<8;i++)

{

ADC_CSR = Channel & 0x0F; // 选择AD转换通道

ADC_CR1 |= 0x01; // 启动AD转换

while(!(ADC_CSR & 0x80)); // 等待AD转换完成

value = ADC_DRL;

value |=((ADC_DRH<<8)&0X0300);

value1+=value;

ADC_CSR = 0x00;

}

return (value1/8);

}

大概这意思,怎么定义32位数,这个自己去查,因为AD采样时间比较久,估计这样FOR可能不合适,自己可以改改。

以上就是关于STC单片机自带AD代码问题全部的内容,包括:STC单片机自带AD代码问题、跪求会C8051F020单片机的,要用C语言写出测量电压,就是AD转换的程序、求atmega88单片机的AD采样程序,另外如果用ADC6或者ADC7作采样通道在程序上应该怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10103104.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存