基于单片机的数据采集系统设计内容摘要:

[14])。 LCD_Display_OneChar(4,1,chr[10])。 //: LCD_Display_OneChar(5,1,chr[0])。 //+ LCD_Display_OneChar(6,1,Num[0])。 LCD_Display_OneChar(7,1,chr[3])。 //小数点 LCD_Display_OneChar(8,1,Num[0])。 LCD_Display_OneChar(9,1,Num[0])。 LCD_Display_OneChar(10,1,chr[11])。 //V LCD_Display_OneChar(11,1,chr[2])。 //空 LCD_Display_OneChar(12,1,chr[5])。 //C LCD_Display_OneChar(13,1,chr[15])。 //H LCD_Display_OneChar(14,1,chr[10])。 //: LCD_Display_OneChar(15,1,Num[1])。 //1 } msDelay(500)。 while(1) { //执行测温、测电压操作 ,发送数据包 { USART_Send_Data(0x24)。 //串头 $ USART_Send_Data(ID)。 //发送 ID DS18B20_Read_rom()。 //发送温度传感器系列号 Temp_Change()。 //测温度,并发送温度值 Display_temperature()。 //LCD 显示温度值 Volt_Convert()。 //测电压,并发送电压值 volt_show()。 //LCD 显示温度值 USART_Send_Data(State)。 //发送检测状态 USART_Send_Data(0x2A)。 msDelay(2020)。 //延时 2 秒(可调,根据采样率要求而定) } if(Warning_Flag) //报警检测 { Ring = 0。 msDelay(50)。 Ring=1。 msDelay(50)。 Ring=0。 msDelay(50)。 Ring=1。 msDelay(50)。 Ring=0。 msDelay(50)。 Ring=1。 msDelay(50)。 Warning_Flag=0。 State=( State amp。 (~(0x01)))。 //复位温度报警状态位 State=( State amp。 (~(0x02)))。 //复位电压报警状态位 } } 数据采集模块 数据采集模块的任务是负责温度、电压数据的采集以及将采集到的模拟量通过A/D 转换器转化为相应的数字量提供给单片机。 DS18B20 温度传感器和 ADC0832 芯片的使用需要注意操作时序 ,时序图可以在相应型号的芯片手册中查阅得到。 /*****************DS18B20 读 1 位 *****************/ bit DS18B20_Read_bit(void) //读一位 { uint i。 bit dat。 DS=0。 i++。 //小延时一下 DS=1。 i++。 i++。 dat=DS。 i=8。 while(i0)i。 return (dat)。 } /*****************DS18B20 读 1 字节 *****************/ uchar DS18B20_Read_byte(void) //读一个字节 { uchar i,j,dat。 dat=0。 for(i=1。 i=8。 i++) { j=DS18B20_Read_bit()。 dat=(j7)|(dat1)。 //读出的数据最低位在最前面 return(dat)。 //将一个字节数据返回 } /*****************DS18B20 写 1 字节 *****************/ void DS18B20_Write_byte(uchar dat) //写一个字节到 DS18B20 里 { uint i。 uchar j。 bit testb。 for(j=1。 j=8。 j++) { testb=datamp。 0x01。 dat=dat1。 if(testb) // 写 1 部分 { DS=0。 i++。 i++。 DS=1。 i=8。 while(i0)i。 } else { DS=0。 //写 0 部分 i=8。 while(i0)i。 DS=1。 i++。 i++。 } } } /*****************DS18B20 温度转换 *****************/ void DS18B20_Temp_Convert(void) //发送温度转换命令 { DS18B20_init()。 //初始化 DS18B20 delayb(1)。 //延时 DS18B20_Write_byte(0xcc)。 //跳过序列号命令 DS18B20_Write_byte(0x44)。 //发送温度转换命令 } /*****************DS18B20 温度处理 *****************/ int Get_Temperature() //获得温度 { float tt。 uchar a,b。 DS18B20_init()。 delayb(1)。 DS18B20_Write_byte(0xcc)。 DS18B20_Write_byte(0xbe)。 //发送读取数据命令 a=DS18B20_Read_byte()。 //连续读两个字节数据 b=DS18B20_Read_byte()。 USART_Send_Data(b)。 USART_Send_Data(a)。 //串口发送温度值。 temp=b。 temp=8。 temp=temp|a。 //两字节合成一个整型变量。 tt=temp*。 //得到真实十进制温度值 , 因为 DS18B20 //可以精确到 度,所以读回数据的最低位代表的是 度。 temp=tt*10+。 //放大十倍,目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。 if((temp/10)Warning_Temperature) //大于温度报警值,启动报 警 { Warning_Flag=1。 //报警标志置位 State|=0x01。 } return temp。 //返回温度值 } /*****************DS18B20 读序列号 *****************/ void DS18B20_Read_rom() //read the serial 读取温度传感器的序列号 { //本程序中没有用到此函数 uchar sn1,sn2。 DS18B20_init()。 delayb(1)。 DS18B20_Write_byte(0x33)。 sn1=DS18B20_Read_byte()。 sn2=DS18B20_Read_byte()。 USART_Send_Data(sn1)。 USART_Send_Data(sn2)。 }  ADC0831 芯片时序图(图 32) /***************** AD0831 A/D 转换 *****************/ unsigned char AD0831_Read(void) //本函数是模拟 0831 的串口协议进行的 { unsigned char i=0,volt_tmp=0。 SDA2=1。 CS2=0。 _nop_()。 _nop_()。 SCL2=0。 _nop_()。 _nop_()。 SCL2=1。 _nop_()。 _nop_()。 SCL2=0。 _nop_()。 _nop_()。 SCL2=1。 _nop_()。 _nop_()。 SCL2=0。 _nop_()。 _nop_()。 for(i=0。 i8。 i++) { volt_tmp=1。 if(SDA2) { volt_tmp++。 } SCL2=1。 _nop_()。 _nop_()。 SCL2=0。 _nop_()。 _nop_()。 } CS2=1。 //转换完成 return volt_tmp。 } 数据处理模块 数据处理模块负责处理 A/D 转换后的数字量。 由于 DS18B20 温度传感器和ADC0832芯片的输出是串行数据输出,故其中最重要的环节是实现数据的串 — 并转换。 所以这里主要讨论数据的串 — 并转换程序。 /******************温度数据处理 *********************/ void Temp_Change() { int temperature。 DS18B20_Temp_Convert()。 temperature = Get_Temperature()。 if(temperature0) {tmp_4=0。 } // +温度 else {tmp_4=1。 } // 温度 tmp_3=temperature/1000。 //百位 if(tmp_3==0) {tmp_3=10。 } //无百位,不显示 10 为空字符 temperature = temperature % 1000。 tmp_2 = temperature/100。 //十位 temperature = temperature % 100。 tmp_1 = temperature/10。 //获取个位 tmp_0 = temperature % 10。 //获取小数第一位 } /*********************电压数据处理 **************************/ void Volt_Convert() { unsigned int i=0,tmp。 RST=0。 for (i=0。 i256。 i++) { if(i==255) { tmp=AD0831_Read()。 USART_Send_Data(tmp)。 //串口发送电压值 //这里为循环 255 个周期读取一次 0831,因 CPU 运行比较快,没必要每次循环都去读取 tmp=(tmp*100)。 //这里乘上 100 的意思是保留两位小数 tmp=tmp/51。 //除以 51,原因:模数转换 IC 是 8 位 ADC,转换回来的数值是 0255 , 0V 时是 0, 5V 时是 255,他相应的倍数就是 255/5=51,因此,将转换回来的数除以 51,就能得到相应的电压值 if(tmpWarning_Voltage) { Warning_Flag=1。 State|=0x02。 } volt_3=tmp/100。 //得到百位,其实是个位,因为刚才乘上 100 了 tmp=tmp%100。 volt_2=tmp/10。 //十位 即小数点后第一位 volt_1=tmp%10。 //个位 即小数点后第二位 } } } /*****************串口发送数据子函数 *****************/ void USART_Send_Data(uchar DATA) { uchar i=0。 SBUF=DATA。 while(1) { if(TI) { TI=0。 break。 } } } /*****************串口接收数据子函数 ******************/ void USAR。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。