这是一个将AD转换的值通过串口发送到PC上的程序,但是弄了一晚上PC始终收不到程序,实在弄不明白了,来请教各位大师..谢谢各位!!单片机是STC12系列,1T的单片机.串口设置使用波特率计算软件算出来的,应该没有问题
#include"STC12C5620AD.H" //STC12C54系列单片机头文件
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
void uinit(void) //9600bps@11.0592MHz
{
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xDC; //设定定时初值
TH1 = 0xDC; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
void AD_Init()
{
P1M0=0x0f;//0000 1111 设置P1口低4位为开漏模式,用来AD采集
P1M1=0x0f;//0000 1111
ADC_CONTR=0xe0;//1110 0000 开启AD转换器电源,设置最高转换速度
delayms(100);
}
int GetAD(unsigned char channel) //channel为要取的通道号(0~7)
{
unsigned char AD_finished=0;
int result;
ADC_CONTR|=channel; //选择AD通道号
ADC_CONTR|=0x08; //启动AD转换
while(AD_finished==0) //等待AD转换结束
{
AD_finished=(ADC_CONTR&0x10);//查询ADC_FLAG位是否置1
}
result=ADC_DATA*4+ADC_LOW2;//读走AD转换结果,由于ADC_DATA中存储12位中的
//高8位,当要转换成10进制时,需将ADC_DATA中的数左移2位,即相当于*4
ADC_CONTR&=0xf7; //清除转换结束标志
return (result); //返回结果给函数
}
float Ad_Av(uchar channel) //求100次采集电压的平均值
{
float Val_Av=0;
uchar num;
for(num=100;num>0;num--)
{
Val_Av+=GetAD(channel);//100次采集求和
}
Val_Av/=100.0; //求平均值
Val_Av=Val_Av*5.0/1024; //单片机电源为5V,求的真实电压值
return (Val_Av); //返回给函数
}
void main()
{
float ad1,ad2,ad3,ad4;
AD_Init();
uinit();
ad1=Ad_Av(1);
ad2=Ad_Av(2);
ad3=Ad_Av(3);
ad4=Ad_Av(4);
printf("The voltage is %fV
",ad1);
while(1);
}
这是一个将AD转换的值通过串口发送到PC上的程序,但是弄了一晚上PC始终收不到程序,实在弄不明白了,来请教各位大师..谢谢各位!!单片机是STC12系列,1T的单片机.串口设置使用波特率计算软件算出来的,应该没有问题.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#include"STC12C5620AD.H" //STC12C54系列单片机头文件
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
void init()
{
SCON=0X40;
REN=0;
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
TI=1;
SM0=0;
SM1=1;
}
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
void AD_Init()
{
P1M0=0x0f;//0000 1111 设置P1口低4位为开漏模式,用来AD采集
P1M1=0x0f;//0000 1111
ADC_CONTR=0xe0;//1110 0000 开启AD转换器电源,设置最高转换速度
delayms(100);
}
int GetAD(unsigned char channel) //channel为要取的通道号(0~7)
{
unsigned char AD_finished=0;
int result;
ADC_CONTR|=channel; //选择AD通道号
ADC_CONTR|=0x08; //启动AD转换
while(AD_finished==0) //等待AD转换结束
{
AD_finished=(ADC_CONTR&0x10);//查询ADC_FLAG位是否置1
}
result=ADC_DATA*4+ADC_LOW2;//读走AD转换结果,由于ADC_DATA中存储12位中的
//高8位,当要转换成10进制时,需将ADC_DATA中的数左移2位,即相当于*4
ADC_CONTR&=0xf7; //清除转换结束标志
return (result); //返回结果给函数
}
float Ad_Av(uchar channel) //求100次采集电压的平均值
{
float Val_Av=0;
uchar num;
for(num=100;num>0;num--)
{
Val_Av+=GetAD(channel);//100次采集求和
}
Val_Av/=100.0; //求平均值
Val_Av=Val_Av*5.0/1024; //单片机电源为5V,求的真实电压值
return (Val_Av); //返回给函数
}
void main()
{
while(1)
{
float ad1;//,ad2,ad3,ad4;
init();
AD_Init();
ad1=Ad_Av(1);
printf("voltage is %f ",ad1);
delayms(2000);
}
}
原因有两点;1,串口初始化程序没有TI=1这一句,不知道为什么就不行,因为串口初始化是用STC的官方程序生成的.2,主函数有问题,主函数借鉴的郭天祥的程序.
(原文件名:电压表.jpg)
/*
* putchar (full version): expands ' ' into CR LF and handles
* XON/XOFF (Ctrl+S/Ctrl+Q) protocol
*/
char putchar (char c) {
if (c == ' ') {
if (RI) {
if (SBUF == XOFF) {
do {
RI = 0;
while (!RI);
}
while (SBUF != XON);
RI = 0;
}
}
while (!TI);
TI = 0;
SBUF = 0x0d; /* output CR */
}
if (RI) {
if (SBUF == XOFF) {
do {
RI = 0;
while (!RI);
}
while (SBUF != XON);
RI = 0;
}
}
while (!TI);
TI = 0;
return (SBUF = c);
}
#include"STC12C5620AD.H" //STC12C54系列单片机头文件
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
void init()
{
PCON &= 0x7f; //波特率不倍速
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
SCON=0X40; //由此以上带有注释的串口初始化部分在12T模式11M晶振下可删除.
REN=0;
TMOD=0x20;
TH1=0xed; // 12T 11.0592晶振模式下初始值为0Xfd
TL1=0xed;
TR1=1;
TI=1;
SM0=0;
SM1=1;
}
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
void AD_Init()
{
P1M0=0xff;//0000 1111 设置P1口低4位为开漏模式,用来AD采集
P1M1=0xff;//0000 1111
ADC_CONTR=0xe0;//1110 0000 开启AD转换器电源,设置最高转换速度
delayms(100);
}
int GetAD(unsigned char channel) //channel为要取的通道号(0~7)
{
unsigned char AD_finished=0;
int result;
ADC_CONTR|=channel; //选择AD通道号
ADC_CONTR|=0x08; //启动AD转换
while(AD_finished==0) //等待AD转换结束
{
AD_finished=(ADC_CONTR&0x10);//查询ADC_FLAG位是否置1
}
result=ADC_DATA*4+ADC_LOW2;//读走AD转换结果,由于ADC_DATA中存储12位中的
//高8位,当要转换成10进制时,需将ADC_DATA中的数左移2位,即相当于*4
ADC_CONTR&=0xf7; //清除转换结束标志
return (result); //返回结果给函数
}
float Ad_Av(uchar channel) //求100次采集电压的平均值
{
float Val_Av=0;
uchar num;
for(num=100;num>0;num--)
{
Val_Av+=GetAD(channel);//100次采集求和
}
Val_Av/=100.0; //求平均值
Val_Av=Val_Av*5.0/1024; //单片机电源为5V,求的真实电压值
return (Val_Av); //返回给函数
}
void main()
{
while(1)
{
float ad1,ad2,ad3,ad0;
init();
AD_Init();
ad0=Ad_Av(0);
ad1=Ad_Av(1);
ad2=Ad_Av(2);
ad3=Ad_Av(3);
printf("voltage0 is %f ",ad0);
delayms(2000);
printf("voltage1 is %f ",ad1);
delayms(2000);
printf("voltage2 is %f ",ad2);
delayms(2000);
}
}
不知道郭天祥到底是怎么教的,书本上的程序到处是错误,在他的程序上加上printf,结果三个通道的值竟然是一样的(与通道0相同).又找了一晚上的原因,原来是因为第1,2,3通道在启动之前根本没有对AD进行初始化.
最后的程序改一下就可以了.
void main()
{
while(1)
{
float ad1,ad2,ad3,ad0;
init();
AD_Init();
ad0=Ad_Av(0);
AD_Init();
ad1=Ad_Av(1);
AD_Init();
ad2=Ad_Av(2);
AD_Init();
ad3=Ad_Av(3);
printf("voltage0 is %f ",ad0);
delayms(2000);
printf("voltage1 is %f ",ad1);
delayms(2000);
printf("voltage2 is %f ",ad2);
delayms(2000);
}
}
才学到...记下~~~
我之前一直自己编写串口发送字符串的程序用的!!...~~~~
一周热门 更多>