这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» 测周法测方波频率,数据测出来了就是结合串口发不出去,求大神放马过来

共7条 1/1 1 跳转至

测周法测方波频率,数据测出来了就是结合串口发不出去,求大神放马过来

菜鸟
2014-03-12 21:20:00 打赏

测周法测方波频率,用AT89S52单片机的外部中断0输入待测信号,定时器T0产生标准信号,外部中断输入信号(即待测信号)两个下跳沿分别控制定时器TO的开和关,这样即测得待测信号包含多少个标准信号,乘以标准信号周期取倒数即待测频率。不过现在数据测量出来了,就是想用串口与上位机串口通信,数据发不过去,或者发过去一直是00 00 00 00 00 00 00 00(八组00)程序如下:

#include
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long int
//#define CHU 100

sbit lcden=P3^1; //1602使能端
sbit lcdrs=P2^7; //命令、数据端
sbit RW=P2^6; //读写控制端

uchar i=0; //外部中断0下调沿次数,定时功能
ulong t=0; // T0定时模式软件计数
ulong num; //暂存1S计数次数中间变量
uchar n; //固定显示字符个数
ulong a,b,c,d; //个位,十位,百位
uint e,g;

uchar code table[]="maibo cishu :"; //第一排固定显示
uchar code table1[]=" ci/min"; //第二排固定单位显示
uchar code table2[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //1602调用0到9数字库


void delay(uint z) // 1ms延时
{
uint a;
for(z;z>0;z--)
for(a=110;a>0;a--);
}

void write_com(uchar com) // 1602写命令
{
lcdrs=0;
P0=com;
RW=0;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) // 1602写数据
{
lcdrs=1;
P0=date;
RW=0;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() // 1602初始化
{
lcden=0;
write_com(0x38); //功能设定,4/8位数据等
write_com(0x0e); //显示状态开/关
write_com(0x06); //设置光标
write_com(0x01); //清屏
write_com(0x80); //显示位址 第一行:80H-A7H 第二行:C0H-E7H
}

void display(ulong n)
{
a=n%10; //个位
b=n/10%10; //十位
c=n/100%10; //百位
d=n/1000%10; //千位

write_com(0xc6); //第二行第六个显示块
write_data(table2[d]);
delay(2);

write_com(0xc7); //第二行第六个显示块
write_data(table2[c]);
delay(2);

// if(c==0) //百位为0不显示
// {
// write_com(0xc5); //第二行第六个显示块
// write_data(0x20);
// delay(20);
// }

write_com(0xc8); //第二行第七个显示块
write_data(table2[b]);
delay(2);

// if(c==0&&b==0) //十位为0不显示
// {
// write_com(0xc6); //第二行第七个显示块
// write_data(0x20);
// delay(20);
// }


write_com(0xc9); //第二行第八个显示块
write_data(table2[a]);
delay(2);
}

void main()
{
// PS=1;
SCON=0x50; //串口模式1,允许接收;SM0 SM1 = 01; REN=1;
PCON=0x00; //波特率不倍增 SMOD=0;

TMOD=0x21; //定时器T0设置为定时模式1,服务程序为软件计时

ET0=0;
TR0=0;
TI=1; //TI 置1,以发送第一个字节
TR1=1; //启动定时器 T1

TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TL1=0xfd;
TH1=0xfd; //波特率9600

EX0=1;//开外部中断0
IT0=1;//下降沿触发

// ES=1;
EA=1;

init(); // 1602初始化

while(1)
{

if(e==1)
{
display(num);
e=0;
ES=0;
SBUF=g; //向上位机传数据(此时为返回上位机发送的数据)
while(!TI);
ES=1;
TI=0; //软件清零TI,以准备发送下一帧数据
}
}

}
void exr0() interrupt 0
{
i++; //来一个外部脉冲计一次数
if(i==1)
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256; //定时满一次的时间T=CHU*t机器
ET0=1; //开定时器T0
TR0=1;

}
if(i==2) // 取i-1个周期来计数内部脉冲
{
ET0=0; //关定时器T0
TR0=0;
num=200000/t; //频率=num=1000/t 1为测了1次周期,为了显示小数点后3位再乘以1000 即1000000
// num=(40000000/10/t)*60/1000; //f=num=4000/t 4为测了4次周期,为了显示小数点后3位再乘以1000 即4000000
g=num;

//显示频率
i=0;
e=1;
t=0; //计数器清零

}

}

void timer0() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256; //定时满一次的时间T=CHU*t机器
t++; //定时满一次t加一
}




关键词: 单片机 测周法 串口通信 中断

院士
2014-03-13 08:49:50 打赏
2楼
妈呀,不明白啊

高工
2014-03-13 08:55:32 打赏
3楼
一看就知道跟郭天祥学的51编程风格,,,问题交给楼下大侠处理啦,,

专家
2014-03-13 08:56:52 打赏
4楼

1、查看下波特率设置的是否一致;

2、构建一个详细的错误指令集,何种错误对应何种指令,这样便于检查错误。

你上面写的都是测量的,对于串口发送没有涉及到。


院士
2014-03-13 08:56:55 打赏
5楼
从返回的数据来看,楼主你的串口波特率设置错误了

专家
2014-03-13 09:16:50 打赏
6楼
你的串口可以单独工作不?波特率设置的对不?晶振用多大的? 2、可以用1602现实测得结果,如果不能,还请看看定时器和中断那边的配置。 分步调试,再联调。

高工
2014-03-13 10:55:49 打赏
7楼

1、串口波特率

2、串口通信的函数没见啊,检查一下是不是缓存错了。

建议撸主中断里面还是不要有计算。


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]