单片机应系统(三级)项目
设计说明书
(20122013学年第二学期)
题 目 : 基热敏电阻数字温度计 __
专业班级 : 电子信息工程
学生姓名 :
指导教师 :
设计周数 : 两周
设计成绩 :
2013年X月X日
目录
1实验设计目 2
2系统软件设计 2
21软件总体流程设计 2
22系统设计程序 3
221系统函数 3
222汉显lcd12864 4
223时钟芯片DS1302 6
224ADC0832 11
23位机设计代码 14
231SerialPort 组件 14
232串口操作 15
233数接收 15
234保存数清空数 17
3系统硬件电路设计 17
31恒温桥电路 17
32信号放电路 18
33AD转换电路 18
34控制电路 19
35显示电路 20
4总结展 20
参考文献 21
1实验设计目
着知识济特征信息化时代仪器仪表认识更加深入温度作重物理量工业生产程中普遍重工艺参数着工业断发展温度测量求越越高测量范围越越广温度检测技术求越越高温度测量测量技术研究重课题
系统温度测量采热阻效应温度测量模块温度测量电桥温度发生变化时电桥失衡电桥输出端电压输出该电压输出微弱电压信号通OP07放放信号输入AD转换芯片 进行AD转换单片机进行数处理显示电路测温度显示出
单
片
机
显示
模
块
电 源 模 块
测
温
模
块
信号
放
模块
AD
转
换
模
块
图11系统框图
2系统软件设计
21软件总体流程设计
软件设计采c语言编程运模块化程序设计思想功模块程序进行分编程便移植调样软件层次结构清晰利软件调试修改
数字温度计系统软件部分采模块化设计思想系统分程序初始化处理模块中断检测模块延时处理模块数处理模块显示模块软件系统程序实现流程图示:
开 始
DS1302时钟信息采集
数处理
12864显示
结 束
系统初始化
PT100温度采集
图21系统软件流程
22系统设计程序
221系统函数
程序入口分调头文件实现lcd12864汉显显示DS1302时钟芯片时间运行ADC0832模数转换代码实现:
#include reg52h
#include intrinsh
#include lcd12864h
#include DS1302h
#include ADC0832h
#define uchar unsigned char
#define uint unsigned int
void main( void )
{
Com_Init()
v_Lcd12864Init_f()
v_Lcd12864PutString_f( 10 年)
v_Lcd12864PutString_f( 30 月)
v_Lcd12864PutString_f( 50 日)
v_Lcd12864PutString_f( 11 时)
v_Lcd12864PutString_f( 31 分)
v_Lcd12864PutString_f( 51 秒)
v_Lcd12864PutString_f( 52 ℃)
while(1){
Run_DS1302()
displayADC ()
send()
_nop_
}
}
222汉显lcd12864
实现汉显lcd12864接收时钟芯片DS1302AD转换模块传递温度时间显示液晶屏代码实现:
#includelcd12864h
#include intrinsh
#define uchar unsigned char
#define uint unsigned int
void v_Lcd12864CheckBusy_f( void ) 忙检测函数
{
unsigned int nTimeOut 0
SET_INC
SET_READ
CLR_EN
SET_EN
while( ( io_LCD12864_DATAPORT & 0x80 ) && ( ++nTimeOut 0 ) )
CLR_EN
SET_INC
SET_READ
}
void v_Lcd12864SendCmd_f( unsigned char byCmd ) 发送命令
{
v_Lcd12864CheckBusy_f()
SET_INC
SET_WRITE
CLR_EN
io_LCD12864_DATAPORT byCmd
_nop_()
_nop_()
SET_EN
_nop_()
_nop_()
CLR_EN
SET_READ
SET_INC
}
void v_Lcd12864SendData_f( unsigned char byData ) 发送数
{
v_Lcd12864CheckBusy_f()
SET_DATA
SET_WRITE
CLR_EN
io_LCD12864_DATAPORT byData
_nop_()
_nop_()
SET_EN
_nop_()
_nop_()
CLR_EN
SET_READ
SET_INC
}
void v_DelayMs_f( unsigned int nDelay ) 延时
{
unsigned int i
for( nDelay > 0 nDelay )
{
for( i 125 i > 0 i )
}
}
void v_Lcd12864Init_f( void ) 初始化
{
v_Lcd12864SendCmd_f( 0x30 ) 基指令集
v_DelayMs_f( 50 )
v_Lcd12864SendCmd_f( 0x01 ) 清屏
v_DelayMs_f( 50 )
v_Lcd12864SendCmd_f( 0x06 ) 光标右移
v_DelayMs_f( 50 )
v_Lcd12864SendCmd_f( 0x0c ) 开显示
}
void v_Lcd12864SetAddress_f( unsigned char x y ) 址转换
{
unsigned char byAddress
switch( y )
{
case 0 byAddress 0x80 + x
break
case 1 byAddress 0x90 + x
break
case 2 byAddress 0x88 + x
break
case 3 byAddress 0x98 + x
break
default
break
}
v_Lcd12864SendCmd_f( byAddress )
}
void v_Lcd12864PutString_f( uchar x uchar y uchar *pData )
{
v_Lcd12864SetAddress_f( x y )
while( *pData '\0' )
{
v_Lcd12864SendData_f( *pData++ )
}
}
223时钟芯片DS1302
汉显12864提供时间输出代码实现:
#includeDS1302h
#includeintrinsh
#includelcd12864h
#define uchar unsigned char
#define uint unsigned int
void v_RTInputByte(uchar ucDa) 功 DS1302写入1Byte数
{
uchar i
ACC ucDa
T_RST 1
for(i8 i>0 i)
{
T_IO ACC0
T_CLK 1
T_CLK 0
ACC ACC >> 1
}
}
uchar uc_RTOutputByte(void)DS1302读取1Byte数
{
uchar i
T_RST 1
for(i8 i>0 i)
{
ACC ACC >>1
T_IO1
ACC7 T_IO
T_CLK 1
T_CLK 0
}
return(ACC)
}
void v_W1302(uchar ucAddr uchar ucDa) DS1302写入数 ucAddr DS1302址 ucDa 写数
{
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(ucAddr) 写址
_nop_()
_nop_()
v_RTInputByte(ucDa) 写1Byte数
T_CLK 1
T_RST 0
}
uchar uc_R1302(uchar ucAddr) 读取DS1302某址数 ucAddr DS1302址
{
uchar ucDa
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(ucAddr) 写址命令
_nop_()
_nop_()
ucDa uc_RTOutputByte() 读1Byte数
T_CLK 1
T_RST 0
return(ucDa) ucDa 读取数
}
void v_BurstW1302T(uchar *pSecDa) DS1302写入时钟数
{
uchar i
v_W1302(0x8e 0x00) 控制命令WP0写操作
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(0xbe) 0xbe时钟字节写命令
for(i8 i>0 i) 8Byte 7Byte 时钟数 + 1Byte 控制
{
v_RTInputByte(*pSecDa) 写1Byte数
pSecDa++
}
T_CLK 1
T_RST 0
}
void v_BurstR1302T(uchar *pSecDa) 读取DS1302时钟数
{
uchar i
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(0xbf) 0xbf时钟字节读命令
for(i8 i>0 i)
{
*pSecDa uc_RTOutputByte() 读1Byte数
pSecDa++
}
T_CLK 1
T_RST 0
}
void v_BurstW1302R(uchar *pReDa) DS1302寄存器数写入数 pReDa 寄存器数址
{
uchar i
v_W1302(0x8e0x00) 控制命令WP0写操作
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(0xfe) 0xbe时钟字节写命令
for(i31 i>0 i) 31Byte 寄存器数
{
v_RTInputByte(*pReDa) 写1Byte数
pReDa++
}
T_CLK 1
T_RST 0
}
void v_BurstR1302R(uchar *pReDa) 读取DS1302寄存器数 pReDa 寄存器数址
{
uchar i
T_RST 0
T_CLK 0
T_RST 1
v_RTInputByte(0xff) 0xbf时钟字节读命令
for(i31 i>0 i) 31Byte 寄存器数
{
*pReDa uc_RTOutputByte() 读1Byte数
pReDa++
}
T_CLK 1
T_RST 0
}
*
* 输入 pSecDa 初始时间址初始时间格式 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
*
void v_Set1302(uchar *pSecDa) 设置初始时间
{
uchar i
uchar ucAddr 0x80
v_W1302(0x8e 0x00) 控制命令WP0写操作
for(i7 i>0 i)
{
v_W1302(ucAddr *pSecDa) 秒 分 时 日 月 星期 年
pSecDa++
ucAddr + 2
}
v_W1302(0x8e 0x80) 控制命令WP1写保护
}
void v_Get1302(uchar ucCurtime[]) 读取DS1302前时间 ucCurtime 保存前时间址 BCD码
{
uchar i
uchar ucAddr 0x81
for(i0 i<7 i++)
{
ucCurtime[i] uc_R1302(ucAddr) 格式 秒 分 时 日 月 星期 年
ucAddr + 2
}
}
uchar dectobcd(uchar dec) DEC码转换BCD码
{
uchar bcd
bcd 0
while(dec > 10)
{
dec 10
bcd++
}
bcd << 4
bcd | dec
return bcd
}
uchar bcdtodec(uchar bcd) BCD码转换DEC码
{
uchar data1
data1 bcd & 0x0f 取BCD低4位
bcd bcd & 0x70 剔BCD高位低4位
data1 + bcd >> 1
data1 + bcd >> 3 位移代法运算
return data1
}
void Write_DS1302Init(void) 写入数 初始化
{
v_W1302(0x8e0)
v_W1302(0x800x50) 写入秒
v_W1302(0x8e0)
v_W1302(0x820x59) 写入分
v_W1302(0x8e0)
v_W1302(0x840x07) 写入时
v_W1302(0x8e0)
v_W1302(0x860x08) 写入日
v_W1302(0x8e0)
v_W1302(0x880x06) 写入月
v_W1302(0x8e0)
v_W1302(0x8a0x05) 写入星期
v_W1302(0x8e0)
v_W1302(0x8c0x13) 写入年
}
void Run_DS1302()
{
uchar sec min hour day month year week
v_W1302(0x8f 0)
sec bcdtodec(uc_R1302(0x81)) 读出DS1302中秒
v_W1302(0x8f 0)
min bcdtodec(uc_R1302(0x83)) 读出DS1302中分
v_W1302(0x8f 0)
hour bcdtodec(uc_R1302(0x85)) 读出DS1302中时
v_W1302(0x8f 0)
day bcdtodec(uc_R1302(0x87)) 读出DS1302中日
v_W1302(0x8f 0)
month bcdtodec(uc_R1302(0x89)) 读出DS1302中月
v_W1302(0x8f 0)
year bcdtodec(uc_R1302(0x8d)) 读出DS1302中年
v_W1302(0x8f0)
week bcdtodec(uc_R1302(0x8b)) 读出 星期
v_Lcd12864SetAddress_f(00)
v_Lcd12864SendData_f( year 10 10 + 48 )
v_Lcd12864SendData_f( year 10 + 48 )
v_Lcd12864SetAddress_f(20)
v_Lcd12864SendData_f( month 10 10 + 48 )
v_Lcd12864SendData_f( month 10 + 48 )
v_Lcd12864SetAddress_f(40)
v_Lcd12864SendData_f( day 10 10 + 48 )
v_Lcd12864SendData_f( day 10 + 48 )
v_Lcd12864SetAddress_f(60)
v_Lcd12864SendData_f( week + 48)
v_Lcd12864SetAddress_f(01)
v_Lcd12864SendData_f( hour 10 10 + 48 )
v_Lcd12864SendData_f( hour 10 + 48 )
v_Lcd12864SetAddress_f(21)
v_Lcd12864SendData_f( min 10 10 + 48 )
v_Lcd12864SendData_f( min 10 + 48 )
v_Lcd12864SetAddress_f(41)
v_Lcd12864SendData_f( sec 10 10 + 48 )
v_Lcd12864SendData_f( sec 10 + 48 )
}
224ADC0832
系统重模块实现项目——数字温度计系统基功核心模块模块中传递出0~255256数字然通分段计算出温度模块代码中加入串口通信串口初始化方式二9600特率代码实现:
#include ADC0832h
#include intrinsh
#includelcd12864h
#define uchar unsigned char
#define uint unsigned int
uchar l_temp
unsigned char LcdBuf1[10]
uchar ADC0832_Read(uchar ch)
{
uchar i
uchar ADC_buff0
ADC0832_CS 1
ADC0832_DIO 1 启动位
ADC0832_CLK 0
ADC0832_CS 0
_nop_()
ADC0832_CLK 1
_nop_()
ADC0832_CLK 0
ADC0832_DIO 1 送 SGLDIF 位
_nop_()
ADC0832_CLK 1
_nop_()
ADC0832_CLK 0
if(ch0) ADC0832_DIO 0 送转换通道值
else ADC0832_DIO 1
ADC0832_CLK 1
_nop_()
ADC0832_CLK 0
_nop_()
ADC0832_DIO 1 释放DIO端口转ADC控制
for(i0i<8i++){
_nop_()
ADC0832_CLK 0
_nop_()
ADC0832_CLK 1
_nop_()
if(ADC0832_DIO1) ADC_buffADC_buff+1 读取8位数
ADC_buffADC_buff<<1
}
_nop_()
_nop_()
ADC0832_CS 1
ADC0832_CLK 1
return ADC_buff 返回转换值
}
unsigned int ADC0832da_to_Volage(unsigned char da)
{
unsigned int Volage
float tt
ttda*495255
Volage tt*100+05
return Volage
}
void displayADC ()
{
char i
int w
int temp temp2l_temp1
unsigned long res
uint l_v
l_temp ADC0832_Read(0)
l_v ADC0832da_to_Volage(l_temp)
v_Lcd12864SetAddress_f(03)
l_temp1 l_temp * 2
res(float)(2550000+110000*(512l_temp1)30)(255011*(512l_temp1)30)
temp(float)(res*1000010000000)3851545
temp2 temp
if(temp > 0)
{
for(i6temp>0i)
{
LcdBuf1[i]temp10+48
temp10
}
}
if(temp < 0 )
{
w temp
for(i6w>0i)
{
LcdBuf1[i]w10+48
w10
}
}
if(i>0&&temp<0)
{
if(temp > 10)
{
LcdBuf1[i] '0'
i
}
LcdBuf1[i] ''
i
}
for(i>0i)
LcdBuf1[i]' '
for(i0i<5i++)
LcdBuf1[i]LcdBuf1[i+1]
if(LcdBuf1[4]' ')LcdBuf1[4]'0'
LcdBuf1[5]''
v_Lcd12864PutString_f( 02LcdBuf1 )
}
void Com_Init(void) 串口初始化
{
TMOD 0x20
PCON 0x00
SCON 0x50
TH1 0xFd 波特率9600110592*100000012(0x1000xfd)32
TL1 0xFd
TR1 1
}
void send_char_com( unsigned char ch) 发送字符
{
SBUFch
while (TI 0 )
TI 0
}
void send_string_com( unsigned char *str unsigned int strlen) 串口发送字符串strlen该字符串长度
{
unsigned int k 0
do
{
send_char_com(*(str + k))
k++
}
while (k < strlen)
}
void send()
{
send_string_com(LcdBuf1 10)
}
23位机设计代码
位机简易串口助手串口理位机数接收程序C#编写方便简洁
231SerialPort 组件
Visual Studio 2008 开发工具中采 第三方控件方法设计串口通讯程序NET Framework 20 类库包含 SerialPort 类方便实现需串口通讯种功实现MSComm 编程方法快速转换 SerialPort 类核心串口通讯位机选固定串口COM1波特率9600器件属性图22示:
图22设置串口属性
232串口操作
程序中添加开串口钮btnOpenbtnOpenText 初始化开串口btnOpen 响应函数中加入代码:
private void btnOpen_Click(object sender EventArgs e)
{
if (btnOpenText 开串口)
{
btnOpenText 关闭串口
serialPort1Open()
}
else
{
btnOpenText 开串口
serialPort1Close()
}
}
设置窗体响应事件代码:
private void Form1_Load(object sender EventArgs e)
{
btnOpenText 开串口
}
时该程序已具开关串口作单片机虚拟串口互连方法方法进行串口测试
233数接收
数接收体两种方案:1动定时读取2事件响应驱动
事件响应驱动种方式串口通信位机制作方式采中断思想成串口输入缓区中字节数某设定数时触发串口输入中断时中断程序中读取串口输入缓区中数具实时性灵活性常较方法程序采种方法进行串口输入缓区实时数读取
NET 中封装SerialPort 类表示串行端口资源
命名空间: SystemIOPorts
程序集: System(Systemdll 中)
前面串口常规属性设置(BuadRatePortName)里新串口属性:ReceivedBytesThreshol 获取设置DataReceived 事件发生前部输入缓区中字节数ReceiveBytesThreshold 属性设置串口输入缓区中数字节
ReceiveBytesThreshold 时触发DataReceived 事件代码:
string serialReadString
private void serialPort1_DataReceived(object sender SerialDataReceivedEventArgs e)
{
serialReadString serialPort1ReadExisting()
thisrTB_receiveInvoke
(
new MethodInvoker
(
delegate
{
thisrTB_receiveAppendText(serialReadString)
}
)
)
}
时接收功已实现图23示:
图23位机接收数
234保存数清空数
模块仅完善位机功程序简单代码实现:
private void btnSave_Click(object sender EventArgs e)
{
try
{
SystemIOFileStream objfile
saveFileDialog1ShowDialog()
objfile SystemIOFileCreate(@saveFileDialog1FileName)
objfileClose()
objfileDispose()
SystemIOStreamWriter objfil new SystemIOStreamWriter(@saveFileDialog1FileName)
objfilWrite(rTB_receiveText)
objfilClose()
objfilDispose()
}
catch
{
MessageBoxShow(数未保存)
}
}
private void btnClear_Click(object sender EventArgs e)
{
rTB_receiveClear()
}
3系统硬件电路设计
系统五部分组成:(1)测温电桥温量电路(2)数采集滤波放AD转换电路(3)单片机AT89C51控制数计算电路(4)电源电路(5)温度实时显示电路
31恒温桥电路
次课程设计测温电路测温电桥测温电桥部分热敏电阻
次设计采正温度系数热电阻PT100常温度传感器具较长期稳定性利适数处理设备传输显示记录温度输出热敏电阻阻值温度呈正关系需已知电流流该电阻温度成正输出电压Pt100电阻式温度传感器测温质实测量传感器电阻通常电阻变化转换成电压电流等模拟信号然模拟信号转换成数字信号处理器换算出相应温度
测温电路原理图图31示:
图31测温电路原理图
电桥原理图图32示:
图32电桥原理图
32信号放电路
次课程设计放模块采LM324放集成电路LM324四运放集成电路采14脚双列直插塑料封装外形图示部包含四组形式完全相运算放器电源外四组运放相互独立
33AD转换电路
次课程设计AD转换电路负责放模拟电压信号转化供单片机识数字信号次课程设计选ADC0832芯片
ADC08328位分辨率AD转换芯片高分辨达256级适应般模拟量转换求部电源输入参考电压复芯片模拟电压输入0~5V间芯片转换时间仅32μS双数输出作数校验减少数误差转换速度快稳定性强独立芯片输入器件挂接处理器控制变更加方便通DI数输入端轻易实现通道功选择
正常情况ADC0832单片机接口应4条数线分CSCLKDODIDO端DI端通信时未时效单片机接口双电路设计时DODI联根数线电路原理图图33示:
图33AD转换电路
ADC08328位分辨率返回数值0~255间应模拟数值0~5V档应电压值约00196V
34控制电路
AT89C51单片机系统AT89C51单片机外围电路组成数字温度计系统核心AT89C51单片机高温环境中稳定性支持线编程ISP需专编程器方便调试AT89C51单片机嵌入式控制应提供高灵活效解决方案作控制TLC2543进行模数转换形成必时序进行数计算控制数码显示 AT89C51单片机引脚分布图34示:
图34AT89C51单片机引脚图
35显示电路
显示电路采12864液晶显示模块带中文字库128X64种具4位8位行2线3线串行种接口方式部含国标级二级简体中文字库点阵图形液晶显示模块显示分辨率128×64 置819216*16点汉字12816*8点ASCII字符集利该模块灵活接口方式简单方便操作指令构成全中文机交互图形界面显示8×4行16×16点阵汉字 完成图形显示低电压低功耗显著特点该模块构成液晶显示方案类型图形点阵液晶显示模块相硬件电路结构显示程序简洁该模块价格略低相点阵图形液晶模块
4总结展
次课程设计里负责串口通信位机设计温度输出公式
星期制作作品终成功出炉继二相较简单课程设计次真正挑战题目时便知道二时着质区题目复杂程度远高前然起需实现功温度严格达求精度相困难电路图设计程序写法关系稍慎会温度值准确误差较精心设计原理图研究种热敏电阻原理适范围次修正测试现相较完美结果
体现量作品功齐全种方式完成设计易操作实现完成基功前提完成位机设计尝试查表法实现温度输出(然查表法没成功)花费时间精力终功实现感十分欣慰欢喜特串口通信里第次接触完全懂东西搞懂实属易C语言学进步少说重提高
会吸取次验希次做更
参考文献
[1] 秦志强 C51单片机应C语言程序设计[M] 电子工业出版社 200991
[2] 谢维成 杨加国 董秀成 单片机原理应C51程序设计[M] 清华学出版社 200991
[3]Maxim Integrated Products PT100温度变送器正温度系数补偿[EBOL] 2010[] httpd1ourdevcnbbs_upload782111files_30
项目设计
评 语
项目设计
成 绩
指导教师
(签字)
年 月 日
文档香网(httpswwwxiangdangnet)户传
《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
该内容是文档的文本内容,更好的格式请下载文档