题目:多路数据采集显示器设计
用的芯片是:STC90C516RD+,PCF8591
一、基本要求:
1、用DA转换器输出一正弦信号,频率150Hz
2、用AD转换器周期测量此正弦信号的频率,在数码管或LCD上将频率值显示出来,精确到0.1Hz
3、同时用IO口输出一500Hz的方波信号,用另一IO测量,显示信号参数,
4、设置一功能键,切换两种信号的显示参数
5、通过键盘,可修改方波的频率。每按一次键,频率步进或后退一定值,频率范围100Hz~1500Hz
二、发挥部分:
1、通过键盘,可修改正弦波的频率。每按一次键,频率步进或后退一定值,频率范围10Hz~1000Hz
2、显示器能同步反应参数的变化
3、按键时,蜂鸣器发出提示音,表示按键有效
显示格式:
使用LCD1602,参数必须能显示,并通过按键更改显示不同参数内容
三、protuse仿真运行图(方波和正玄波)
四、源代码见附件
单片机源程序如下:
- /*-----------------------------------------------
- 名称:LCD1602
- 编写:shifang
- 日期:2019-9-3
- 修改:无
- 内容:通过标准程序动态显示字符
- 引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
- ------------------------------------------------*/
- #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #include<intrins.h>
- #define _Nop() _nop_() //定义空指令
- bit ack; //应答标志位
- bit flag_dis=0;
- sbit SDA=P2^1;
- sbit SCL=P2^0;
- #define AddWr 0x90 //写数据地址
- #define AddRd 0x91 //读数据地址
- unsigned char ReadADC(unsigned char Chl);
- bit WriteDAC(unsigned char dat);
- //--定义全局变量--//
- unsigned char code table[] ={"Welcome use: 000 "};
- unsigned char code table1[]={"SIN:0000.0Hz FAG "};
- unsigned int dis,deg; //{"D:0 Voltage:0.00"};
- sbit RS = P2^4; //定义端口
- sbit RW = P2^5;
- sbit EN = P2^6;
- sbit out = P2^7;
- sbit k1 = P3^5;
- sbit k2 = P3^6;
- sbit k3 = P3^7;
- sbit out2 =P1^7;
- sbit buz = P1^2;
- unsigned int fh=150,fh2=100; //初始频率为150Hz
- unsigned int t_10us=0,pinlv,t100us,t100us2;
- #define RS_CLR RS=0
- #define RS_SET RS=1
- #define RW_CLR RW=0
- #define RW_SET RW=1
- #define EN_CLR EN=0
- #define EN_SET EN=1
- #define DataPort P0
- unsigned char code table2[256] ={
- 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x95, 0x98, 0x9c, 0x9f,
- 0xa2, 0xa5, 0xa8, 0xab, 0xae, 0xb0, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf,
- 0xc1, 0xc4, 0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8, 0xda,
- 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xed, 0xef,
- 0xf0, 0xf2, 0xf3, 0xf4, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
- 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfc, 0xfc, 0xfb, 0xfa,
- 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf3, 0xf2, 0xf0, 0xef, 0xed, 0xec,
- 0xea, 0xe8, 0xe6, 0xe4, 0xe3, 0xe1, 0xde, 0xdc, 0xda, 0xd8, 0xd6,
- 0xd3, 0xd1, 0xce, 0xcc, 0xc9, 0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9,
- 0xb6, 0xb4, 0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c, 0x99,
- 0x96, 0x92, 0x8f, 0x8c, 0x89, 0x86, 0x83, 0x80, 0x7d, 0x79, 0x76,
- 0x73, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55,
- 0x52, 0x4f, 0x4c, 0x49, 0x46, 0x43, 0x41, 0x3e, 0x3b, 0x39, 0x36,
- 0x33, 0x31, 0x2e, 0x2c, 0x2a, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d,
- 0x1b, 0x19, 0x17, 0x15, 0x14, 0x12, 0x10, 0x0f, 0x0d, 0x0c, 0x0b,
- 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x0a, 0x0c, 0x0d, 0x0e, 0x10, 0x12, 0x13, 0x15, 0x17, 0x18, 0x1a,
- 0x1c, 0x1e, 0x20, 0x23, 0x25, 0x27, 0x29, 0x2c, 0x2e, 0x30, 0x33,
- 0x35, 0x38, 0x3b, 0x3d, 0x40, 0x43, 0x46, 0x48, 0x4b, 0x4e, 0x51,
- 0x54, 0x57, 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6c, 0x6f, 0x73,
- 0x76, 0x79, 0x7c,
- };
- /*------------------------------------------------
- uS延时函数,含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
- 长度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned int t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延时函数,含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编
- ------------------------------------------------*/
- void DelayMs(unsigned int t)
- {
-
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*------------------------------------------------
- 启动总线
- ------------------------------------------------*/
- void Start_I2c()
- {
- SDA=1; //发送起始条件的数据信号
- _Nop();
- SCL=1;
- _Nop(); //起始条件建立时间大于4.7us,延时
- _Nop();
- _Nop();
- _Nop();
- SDA=0; //发送起始信号
- _Nop(); //起始条件锁定时间大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //钳住I2C总线,准备发送或接收数据
- _Nop();
- _Nop();
- }
- /*------------------------------------------------
- 结束总线
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA=0; //发送结束条件的数据信号
- _Nop(); //发送结束条件的时钟信号
- SCL=1; //结束条件建立时间大于4μ
- /* _Nop();
- _Nop();
- _Nop();
- _Nop();*/
- DelayUs2x(1);
- SDA=1; //发送I2C总线结束信号
- /* _Nop();
- _Nop();
- _Nop();*/
- }
- /*----------------------------------------------------------------
- 字节数据传送函数
- 函数原型: void SendByte(unsigned char c);
- 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
- 此状态位进行操作.(不应答或非应答都使ack=0 假)
- 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
-
- for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
- {
- if((c<<BitCnt)&0x80)SDA=1; //判断发送位
- else SDA=0;
- _Nop();
- SCL=1; //置时钟线为高,通知被控器开始接收数据位
- DelayUs2x(2);
- /* _Nop(); //保证时钟高电平周期大于4μ
- _Nop();
- _Nop();
- _Nop(); */
- SCL=0;
- }
-
- // _Nop();
- _Nop();
- SDA=1; //8位发送完后释放数据线,准备接收应答位
- // _Nop();
- _Nop();
- SCL=1;
- DelayUs2x(1);
- /* _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; */ //判断是否接收到应答信号
- SCL=0;
- // _Nop();
- }
- /*----------------------------------------------------------------
- 字节数据传送函数
- 函数原型: unsigned char RcvByte();
- 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
- 发完后请用应答函数。
- ------------------------------------------------------------------*/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
-
- retc=0;
- SDA=1; //置数据线为输入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; //置时钟线为低,准备接收数据位
- DelayUs2x(2);
- /* _Nop();
- _Nop(); //时钟低电平周期大于4.7us
- _Nop();
- _Nop();
- _Nop();*/
- SCL=1; //置时钟线为高使数据线上数据有效
- // _Nop();
- // _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
- // _Nop();
- // _Nop();
- }
- SCL=0;
- return(retc);
- }
- /*----------------------------------------------------------------
- 非应答子函数
- 原型: void NoAck_I2c(void);
-
- ----------------------------------------------------------------*/
- void NoAck_I2c(void)
- {
-
- SDA=1;
- DelayUs2x(1);
- /* _Nop();
- _Nop();
- _Nop(); */
- SCL=1;
- /*_Nop();
- _Nop(); //时钟低电平周期大于4μ
- _Nop();
- _Nop(); */
- DelayUs2x(1);
- SCL=0; //清时钟线,钳住I2C总线以便继续接收
- // _Nop();
- //_Nop();
- }
- /*------------------------------------------------
- 写入命令函数
- ------------------------------------------------*/
- void LCD_Write_Com(unsigned char com)
- {
- // while(LCD_Check_Busy()); //忙则等待
- DelayMs(5);
- RS_CLR;
- RW_CLR;
- EN_SET;
- DataPort= com;
- _nop_();
- EN_CLR;
- }
- /*------------------------------------------------
- 写入数据函数
- ------------------------------------------------*/
- void LCD_Write_Data(unsigned char Data)
- {
- //while(LCD_Check_Busy()); //忙则等待
- DelayMs(5);
- RS_SET;
- RW_CLR;
- EN_SET;
- DataPort= Data;
- _nop_();
- EN_CLR;
- }
- /*------------------------------------------------
- 清屏函数
- ------------------------------------------------*/
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- /*------------------------------------------------
- 初始化函数
- ------------------------------------------------*/
- void LCD_Init(void)
- {
- // LCD_Write_Com(0x38); /*显示模式设置*/
- // DelayMs(5);
- // LCD_Write_Com(0x38);
- // DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- LCD_Write_Com(0x08); /*显示关闭*/
- LCD_Write_Com(0x01); /*显示清屏*/
- LCD_Write_Com(0x06); /*显示光标移动设置*/
- DelayMs(5);
- LCD_Write_Com(0x0C); /*显示开及光标设置*/
- }
- /*------------------------------------------------
- 读AD转值程序
- 输入参数 Chl 表示需要转换的通道,范围从0-3
- 返回值范围0-255
- ------------------------------------------------*/
- /*unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //启动总线
- SendByte(AddWr); //发送器件地址
- if(ack==0)return(0);
- SendByte(0x40|Chl); //发送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddWr+1);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //发送非应位
- Stop_I2c(); //结束总线
- t_10us=100;
- return(Val);
- }*/
- /*------------------------------------------------
- 写入DA转换数值
- 输入参数:dat 表示需要转换的DA数值,范围是0-255
- ------------------------------------------------*/
- /*bit WriteDAC(unsigned char dat)
- {
- Start_I2c(); //启动总线
- SendByte(AddWr); //发送器件地址
- if(ack==0)return(0);
- SendByte(0x40); //发送器件子地址
- if(ack==0)return(0);
- SendByte(dat); //发送数据
- if(ack==0)return(0);
- Stop_I2c();
- }*/
- bit WriteDAC2()
- {
- unsigned int numm;
- Start_I2c(); //启动总线
- SendByte(AddWr); //发送器件地址
- // if(ack==0)return(0);
- SendByte(0x40); //发送器件子地址
- // if(ack==0)return(0);
-
- for(numm=0;numm<256;numm++)
- {
- SendByte(table2[numm]); //发送数据
- DelayUs2x((unsigned int)(1000/fh*3.9)-4); //150-1000Hz
- }
-
- // if(ack==0)return(0);
- // Stop_I2c();
- }
- /*void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0x0FF;
- TL0 = 0x0F6;
- EA = 1;
- ET0 = 1;
- TR0 = 0;
- }
- void Timer0Interrupt(void) interrupt 1
- {
- TH0 = 0x0FF;
- TL0 = 0x0F6;
- t_10us++;
- if(t_10us>10000)t_10us=0;
- }*/
- void InitTimer1(void)
- {
- TMOD |= 0x10;
- TH1 = 0xFF;
- TL1 = 0xF6;
- EA = 1;
- ET1 = 1;
- TR1 = 0;
- }
- void Timer1Interrupt(void) interrupt 3
- {
- TH1 = 0xFF;
- TL1 = 0xF6;
- t100us++;
- t100us2++;
- if(t100us2<10)out2=0;
- else if(t100us2<20)out2=1;
- else t100us2=0;
-
- // if(t100us>10000)
- // t100us=0;
- if(t100us<(500*5/fh2))out=1;
- else if(t100us<(500*8/fh2))out=0;
- else t100us=0;
- // keyscan();
- }
- void display()
- {
- unsigned int shi,ge,bai,qian,wan;
-
- LCD_Write_Com(0x80+0x40);
- if(flag_dis==1)
- {
- LCD_Write_Data(table1[13]);
- LCD_Write_Data(table1[14]);
- LCD_Write_Data(table1[15]);
- pinlv=fh2;
- }
- if(flag_dis==0)
- {
- LCD_Write_Data(table1[0]);
- LCD_Write_Data(table1[1]);
- LCD_Write_Data(table1[2]);
- pinlv=fh;
- }
- pinlv*=10.0;
- wan=pinlv/10000;
- qian=pinlv%10000/1000;
- bai=pinlv%1000/100;
- // shi=pinlv%100/10;
- // ge=pinlv%10;
-
- LCD_Write_Com(0x8d);
- if(flag_dis==1)
- LCD_Write_Data(0x35);
- else LCD_Write_Data(0x30);
-
- LCD_Write_Com(0x80+0x44);
- LCD_Write_Data(0x30+wan);
- LCD_Write_Data(0x30+qian);
- LCD_Write_Data(0x30+bai);
- // LCD_Write_Data(0x30+shi);
- // LCD_Write_Com(0x80+0x49);
- // LCD_Write_Data(0x30+ge);
- }
- void keyscan()
- {
- TR1 = 0;
- if(k1==0)
- {TR1 = 0;
- DelayMs(10);
- if(k1==0)
- {
- if(flag_dis==0)
- flag_dis=1;
- else flag_dis=0;
- while(!k1){buz=!buz;DelayUs2x(250);}
- }
- display();
- }
- if(k2==0)
- {TR1 = 0;
- DelayMs(10);
- if(k2==0)
- {
- if(flag_dis==0)
- if(fh==10)fh=0;
- if(fh<1000)
- fh+=50;
- if(flag_dis==1)
- if(fh2<1500)
- fh2+=100;
- while(!k2){buz=!buz;DelayUs2x(250);}
- }
- display();
- }
- if(k3==0)
- {TR1 = 0;
- DelayMs(10);
- if(k3==0)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
仿真程序.7z
(309.04 KB, 下载次数: 90)
|